1 /* $Id: points.c,v 1.11 2000/07/15 03:13:43 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47 _mesa_PointSize( GLfloat size
)
49 GET_CURRENT_CONTEXT(ctx
);
50 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointSize");
53 gl_error( ctx
, GL_INVALID_VALUE
, "glPointSize" );
57 if (ctx
->Point
.UserSize
!= size
) {
58 ctx
->Point
.UserSize
= size
;
59 ctx
->Point
.Size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
60 ctx
->TriangleCaps
&= ~DD_POINT_SIZE
;
62 ctx
->TriangleCaps
|= DD_POINT_SIZE
;
63 ctx
->NewState
|= NEW_RASTER_OPS
;
70 _mesa_PointParameterfEXT( GLenum pname
, GLfloat param
)
72 _mesa_PointParameterfvEXT(pname
, ¶m
);
77 _mesa_PointParameterfvEXT( GLenum pname
, const GLfloat
*params
)
79 GET_CURRENT_CONTEXT(ctx
);
80 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointParameterfvEXT");
83 case GL_DISTANCE_ATTENUATION_EXT
:
85 const GLboolean tmp
= ctx
->Point
.Attenuated
;
86 COPY_3V(ctx
->Point
.Params
, params
);
87 ctx
->Point
.Attenuated
= (params
[0] != 1.0 ||
91 if (tmp
!= ctx
->Point
.Attenuated
) {
92 ctx
->Enabled
^= ENABLE_POINT_ATTEN
;
93 ctx
->TriangleCaps
^= DD_POINT_ATTEN
;
94 ctx
->NewState
|= NEW_RASTER_OPS
;
98 case GL_POINT_SIZE_MIN_EXT
:
100 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
103 ctx
->Point
.MinSize
= *params
;
105 case GL_POINT_SIZE_MAX_EXT
:
106 if (*params
< 0.0F
) {
107 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
110 ctx
->Point
.MaxSize
= *params
;
112 case GL_POINT_FADE_THRESHOLD_SIZE_EXT
:
113 if (*params
< 0.0F
) {
114 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
117 ctx
->Point
.Threshold
= *params
;
120 gl_error( ctx
, GL_INVALID_ENUM
, "glPointParameterfvEXT" );
124 ctx
->NewState
|= NEW_RASTER_OPS
;
128 /**********************************************************************/
129 /***** Rasterization *****/
130 /**********************************************************************/
134 * There are 3 pairs (RGBA, CI) of point rendering functions:
135 * 1. simple: size=1 and no special rasterization functions (fastest)
136 * 2. size1: size=1 and any rasterization functions
137 * 3. general: any size and rasterization functions (slowest)
139 * All point rendering functions take the same two arguments: first and
140 * last which specify that the points specified by VB[first] through
141 * VB[last] are to be rendered.
149 * CI points with size == 1.0
152 size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
154 struct vertex_buffer
*VB
= ctx
->VB
;
155 struct pixel_buffer
*PB
= ctx
->PB
;
157 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
158 GLdepth
*pbz
= PB
->z
;
159 GLuint
*pbi
= PB
->index
;
160 GLuint pbcount
= PB
->count
;
163 win
= &VB
->Win
.data
[first
][0];
164 for (i
= first
; i
<= last
; i
++) {
165 if (VB
->ClipMask
[i
] == 0) {
166 pbx
[pbcount
] = (GLint
) win
[0];
167 pby
[pbcount
] = (GLint
) win
[1];
168 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
169 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
175 PB_CHECK_FLUSH(ctx
, PB
);
181 * RGBA points with size == 1.0
184 size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
186 struct vertex_buffer
*VB
= ctx
->VB
;
187 struct pixel_buffer
*PB
= ctx
->PB
;
190 for (i
= first
; i
<= last
; i
++) {
191 if (VB
->ClipMask
[i
] == 0) {
193 GLint red
, green
, blue
, alpha
;
195 x
= (GLint
) VB
->Win
.data
[i
][0];
196 y
= (GLint
) VB
->Win
.data
[i
][1];
197 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
199 red
= VB
->ColorPtr
->data
[i
][0];
200 green
= VB
->ColorPtr
->data
[i
][1];
201 blue
= VB
->ColorPtr
->data
[i
][2];
202 alpha
= VB
->ColorPtr
->data
[i
][3];
204 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
);
207 PB_CHECK_FLUSH(ctx
, PB
);
216 general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
218 struct vertex_buffer
*VB
= ctx
->VB
;
219 struct pixel_buffer
*PB
= ctx
->PB
;
220 const GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
221 GLint radius
= isize
>> 1;
224 for (i
= first
; i
<= last
; i
++) {
225 if (VB
->ClipMask
[i
] == 0) {
226 GLint x0
, x1
, y0
, y1
;
229 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
230 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
231 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
242 x0
= (GLint
) (x
+ 1.5F
) - radius
;
244 y0
= (GLint
) (y
+ 1.5F
) - radius
;
248 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
250 for (iy
= y0
; iy
<= y1
; iy
++) {
251 for (ix
= x0
; ix
<= x1
; ix
++) {
252 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
255 PB_CHECK_FLUSH(ctx
,PB
);
262 * General RGBA points.
265 general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
267 struct vertex_buffer
*VB
= ctx
->VB
;
268 struct pixel_buffer
*PB
= ctx
->PB
;
269 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
270 GLint radius
= isize
>> 1;
273 for (i
= first
; i
<= last
; i
++) {
274 if (VB
->ClipMask
[i
] == 0) {
275 GLint x0
, x1
, y0
, y1
;
278 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
279 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
280 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
291 x0
= (GLint
) (x
+ 1.5F
) - radius
;
293 y0
= (GLint
) (y
+ 1.5F
) - radius
;
298 VB
->ColorPtr
->data
[i
][0],
299 VB
->ColorPtr
->data
[i
][1],
300 VB
->ColorPtr
->data
[i
][2],
301 VB
->ColorPtr
->data
[i
][3] );
303 for (iy
= y0
; iy
<= y1
; iy
++) {
304 for (ix
= x0
; ix
<= x1
; ix
++) {
305 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
308 PB_CHECK_FLUSH(ctx
,PB
);
317 * Textured RGBA points.
320 textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
322 struct vertex_buffer
*VB
= ctx
->VB
;
323 struct pixel_buffer
*PB
= ctx
->PB
;
326 for (i
= first
; i
<= last
; i
++) {
327 if (VB
->ClipMask
[i
] == 0) {
328 GLint x0
, x1
, y0
, y1
;
329 GLint ix
, iy
, radius
;
330 GLint red
, green
, blue
, alpha
;
333 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
334 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
335 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
336 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
352 x0
= (GLint
) (x
+ 1.5F
) - radius
;
354 y0
= (GLint
) (y
+ 1.5F
) - radius
;
358 red
= VB
->ColorPtr
->data
[i
][0];
359 green
= VB
->ColorPtr
->data
[i
][1];
360 blue
= VB
->ColorPtr
->data
[i
][2];
361 alpha
= VB
->ColorPtr
->data
[i
][3];
363 switch (VB
->TexCoordPtr
[0]->size
) {
365 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
366 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
367 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
370 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
371 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
372 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
375 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
376 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
380 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
385 /* should never get here */
387 gl_problem(ctx
, "unexpected texcoord size in textured_rgba_points()");
390 for (iy
= y0
; iy
<= y1
; iy
++) {
391 for (ix
= x0
; ix
<= x1
; ix
++) {
392 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
,
397 PB_CHECK_FLUSH(ctx
, PB
);
404 * Multitextured RGBA points.
407 multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
409 struct vertex_buffer
*VB
= ctx
->VB
;
410 struct pixel_buffer
*PB
= ctx
->PB
;
413 for (i
= first
; i
<= last
; i
++) {
414 if (VB
->ClipMask
[i
] == 0) {
415 GLint x0
, x1
, y0
, y1
;
418 GLint red
, green
, blue
, alpha
;
419 GLint sRed
, sGreen
, sBlue
;
423 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
424 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
425 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
426 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
442 x0
= (GLint
) (x
+ 1.5F
) - radius
;
444 y0
= (GLint
) (y
+ 1.5F
) - radius
;
448 red
= VB
->ColorPtr
->data
[i
][0];
449 green
= VB
->ColorPtr
->data
[i
][1];
450 blue
= VB
->ColorPtr
->data
[i
][2];
451 alpha
= VB
->ColorPtr
->data
[i
][3];
452 sRed
= VB
->Specular
? VB
->Specular
[i
][0] : 0;
453 sGreen
= VB
->Specular
? VB
->Specular
[i
][1] : 0;
454 sBlue
= VB
->Specular
? VB
->Specular
[i
][2] : 0;
456 switch (VB
->TexCoordPtr
[0]->size
) {
458 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
459 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
460 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
463 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
464 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
465 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
468 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
469 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
473 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
478 /* should never get here */
480 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
483 switch (VB
->TexCoordPtr
[1]->size
) {
485 s1
= VB
->TexCoordPtr
[1]->data
[i
][0]/VB
->TexCoordPtr
[1]->data
[i
][3];
486 t1
= VB
->TexCoordPtr
[1]->data
[i
][1]/VB
->TexCoordPtr
[1]->data
[i
][3];
487 u1
= VB
->TexCoordPtr
[1]->data
[i
][2]/VB
->TexCoordPtr
[1]->data
[i
][3];
490 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
491 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
492 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
495 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
496 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
500 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
505 /* should never get here */
507 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
510 for (iy
=y0
;iy
<=y1
;iy
++) {
511 for (ix
=x0
;ix
<=x1
;ix
++) {
512 PB_WRITE_MULTITEX_SPEC_PIXEL( PB
, ix
, iy
, z
,
513 red
, green
, blue
, alpha
,
515 s
, t
, u
, s1
, t1
, u1
);
518 PB_CHECK_FLUSH(ctx
, PB
);
525 * NOTES on aa point rasterization:
527 * Let d = distance of fragment center from vertex.
529 * fragment has 100% coverage
530 * else if d > rmax2 then
531 * fragment has 0% coverage
533 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
538 * Antialiased points with or without texture mapping.
541 antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
543 struct vertex_buffer
*VB
= ctx
->VB
;
544 struct pixel_buffer
*PB
= ctx
->PB
;
545 const GLfloat radius
= ctx
->Point
.Size
* 0.5F
;
546 const GLfloat rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
547 const GLfloat rmax
= radius
+ 0.7071F
;
548 const GLfloat rmin2
= MAX2(0.0, rmin
* rmin
);
549 const GLfloat rmax2
= rmax
* rmax
;
550 const GLfloat cscale
= 256.0F
/ (rmax2
- rmin2
);
553 if (ctx
->Texture
.ReallyEnabled
) {
554 for (i
= first
; i
<= last
; i
++) {
555 if (VB
->ClipMask
[i
] == 0) {
557 GLint red
, green
, blue
, alpha
;
560 GLfloat vx
= VB
->Win
.data
[i
][0];
561 GLfloat vy
= VB
->Win
.data
[i
][1];
563 GLint xmin
= (GLint
) (vx
- radius
);
564 GLint xmax
= (GLint
) (vx
+ radius
);
565 GLint ymin
= (GLint
) (vy
- radius
);
566 GLint ymax
= (GLint
) (vy
+ radius
);
567 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
569 red
= VB
->ColorPtr
->data
[i
][0];
570 green
= VB
->ColorPtr
->data
[i
][1];
571 blue
= VB
->ColorPtr
->data
[i
][2];
573 switch (VB
->TexCoordPtr
[0]->size
) {
575 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
576 VB
->TexCoordPtr
[0]->data
[i
][3]);
577 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
578 VB
->TexCoordPtr
[0]->data
[i
][3]);
579 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
580 VB
->TexCoordPtr
[0]->data
[i
][3]);
583 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
584 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
585 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
588 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
589 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
593 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
598 /* should never get here */
600 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
603 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
604 /* Multitextured! This is probably a slow enough path that
605 there's no reason to specialize the multitexture case. */
606 switch (VB
->TexCoordPtr
[1]->size
) {
608 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
609 VB
->TexCoordPtr
[1]->data
[i
][3]);
610 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
611 VB
->TexCoordPtr
[1]->data
[i
][3]);
612 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
613 VB
->TexCoordPtr
[1]->data
[i
][3]);
616 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
617 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
618 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
621 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
622 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
626 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
631 /* should never get here */
633 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
637 /* translate by a half pixel to simplify math below */
641 for (y
= ymin
; y
<= ymax
; y
++) {
642 for (x
= xmin
; x
<= xmax
; x
++) {
643 const GLfloat dx
= x
- vx
;
644 const GLfloat dy
= y
- vy
;
645 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
647 alpha
= VB
->ColorPtr
->data
[i
][3];
648 if (dist2
>= rmin2
) {
649 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
650 /* coverage is in [0,256] */
651 alpha
= (alpha
* coverage
) >> 8;
653 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
654 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
655 alpha
, s
, t
, u
, s1
, t1
, u1
);
657 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
664 PB_CHECK_FLUSH(ctx
,PB
);
669 /* Not texture mapped */
670 for (i
=first
;i
<=last
;i
++) {
671 if (VB
->ClipMask
[i
]==0) {
672 GLint xmin
, ymin
, xmax
, ymax
;
674 GLint red
, green
, blue
, alpha
;
676 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 - radius
);
677 xmax
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 + radius
);
678 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 - radius
);
679 ymax
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 + radius
);
680 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
682 red
= VB
->ColorPtr
->data
[i
][0];
683 green
= VB
->ColorPtr
->data
[i
][1];
684 blue
= VB
->ColorPtr
->data
[i
][2];
687 printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
688 printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
690 for (y
= ymin
; y
<= ymax
; y
++) {
691 for (x
= xmin
; x
<= xmax
; x
++) {
692 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
693 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
694 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
696 alpha
= VB
->ColorPtr
->data
[i
][3];
697 if (dist2
>= rmin2
) {
698 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
699 /* coverage is in [0,256] */
700 alpha
= (alpha
* coverage
) >> 8;
702 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
,
707 PB_CHECK_FLUSH(ctx
,PB
);
716 * Null rasterizer for measuring transformation speed.
719 null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
728 /* Definition of the functions for GL_EXT_point_parameters */
730 /* Calculates the distance attenuation formula of a vector of points in
731 * eye space coordinates
734 dist3(GLfloat
*out
, GLuint first
, GLuint last
,
735 const GLcontext
*ctx
, const GLvector4f
*v
)
737 GLuint stride
= v
->stride
;
738 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
741 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
742 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
743 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
744 dist
* (ctx
->Point
.Params
[1] +
745 dist
* ctx
->Point
.Params
[2]));
751 dist2(GLfloat
*out
, GLuint first
, GLuint last
,
752 const GLcontext
*ctx
, const GLvector4f
*v
)
754 GLuint stride
= v
->stride
;
755 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
758 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
759 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
760 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
761 dist
* (ctx
->Point
.Params
[1] +
762 dist
* ctx
->Point
.Params
[2]));
767 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
768 const GLcontext
*ctx
, const GLvector4f
*v
);
771 static dist_func eye_dist_tab
[5] = {
781 clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
782 const GLcontext
*ctx
, GLvector4f
*clip
)
784 /* this is never called */
785 gl_problem(NULL
, "clip_dist() called - dead code!\n");
795 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
796 const GLuint stride
= clip_vec
->stride
;
798 for (i
= first
; i
<= last
; i
++ )
800 GLfloat dist
= win
[i
][2];
801 out
[i
] = 1/(ctx
->Point
.Params
[0]+
802 dist
* (ctx
->Point
.Params
[1] +
803 dist
* ctx
->Point
.Params
[2]));
811 * Distance Attenuated General CI points.
814 dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
816 struct vertex_buffer
*VB
= ctx
->VB
;
817 struct pixel_buffer
*PB
= ctx
->PB
;
818 GLfloat dist
[VB_SIZE
];
819 const GLfloat psize
= ctx
->Point
.Size
;
822 if (ctx
->NeedEyeCoords
)
823 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
825 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
827 for (i
=first
;i
<=last
;i
++) {
828 if (VB
->ClipMask
[i
]==0) {
829 GLint x0
, x1
, y0
, y1
;
832 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
833 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
834 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
835 GLfloat dsize
= psize
* dist
[i
];
837 if (dsize
>= ctx
->Point
.Threshold
) {
838 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
841 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
854 x0
= (GLint
) (x
+ 1.5F
) - radius
;
856 y0
= (GLint
) (y
+ 1.5F
) - radius
;
860 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
862 for (iy
=y0
;iy
<=y1
;iy
++) {
863 for (ix
=x0
;ix
<=x1
;ix
++) {
864 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
867 PB_CHECK_FLUSH(ctx
,PB
);
873 * Distance Attenuated General RGBA points.
876 dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
878 struct vertex_buffer
*VB
= ctx
->VB
;
879 struct pixel_buffer
*PB
= ctx
->PB
;
880 GLfloat dist
[VB_SIZE
];
881 const GLfloat psize
= ctx
->Point
.Size
;
884 if (ctx
->NeedEyeCoords
)
885 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
887 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
889 for (i
=first
;i
<=last
;i
++) {
890 if (VB
->ClipMask
[i
]==0) {
891 GLint x0
, x1
, y0
, y1
;
894 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
895 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
896 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
897 GLfloat dsize
=psize
*dist
[i
];
900 if (dsize
>= ctx
->Point
.Threshold
) {
901 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
902 alpha
= VB
->ColorPtr
->data
[i
][3];
905 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
906 dsize
/= ctx
->Point
.Threshold
;
907 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
920 x0
= (GLint
) (x
+ 1.5F
) - radius
;
922 y0
= (GLint
) (y
+ 1.5F
) - radius
;
927 VB
->ColorPtr
->data
[i
][0],
928 VB
->ColorPtr
->data
[i
][1],
929 VB
->ColorPtr
->data
[i
][2],
932 for (iy
=y0
;iy
<=y1
;iy
++) {
933 for (ix
=x0
;ix
<=x1
;ix
++) {
934 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
937 PB_CHECK_FLUSH(ctx
,PB
);
943 * Distance Attenuated Textured RGBA points.
946 dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
948 struct vertex_buffer
*VB
= ctx
->VB
;
949 struct pixel_buffer
*PB
= ctx
->PB
;
950 GLfloat dist
[VB_SIZE
];
951 const GLfloat psize
= ctx
->Point
.Size
;
954 if (ctx
->NeedEyeCoords
)
955 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
957 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
959 for (i
=first
;i
<=last
;i
++) {
960 if (VB
->ClipMask
[i
]==0) {
961 GLint x0
, x1
, y0
, y1
;
964 GLint red
, green
, blue
, alpha
;
968 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
969 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
970 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
972 GLfloat dsize
= psize
*dist
[i
];
973 if(dsize
>= ctx
->Point
.Threshold
) {
974 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
975 alpha
= VB
->ColorPtr
->data
[i
][3];
978 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
979 dsize
/= ctx
->Point
.Threshold
;
980 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3] * (dsize
* dsize
));
997 x0
= (GLint
) (x
+ 1.5F
) - radius
;
999 y0
= (GLint
) (y
+ 1.5F
) - radius
;
1000 y1
= y0
+ isize
- 1;
1003 red
= VB
->ColorPtr
->data
[i
][0];
1004 green
= VB
->ColorPtr
->data
[i
][1];
1005 blue
= VB
->ColorPtr
->data
[i
][2];
1007 switch (VB
->TexCoordPtr
[0]->size
) {
1009 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1010 VB
->TexCoordPtr
[0]->data
[i
][3]);
1011 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1012 VB
->TexCoordPtr
[0]->data
[i
][3]);
1013 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1014 VB
->TexCoordPtr
[0]->data
[i
][3]);
1017 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1018 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1019 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1022 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1023 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1027 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1032 /* should never get here */
1034 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1037 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1038 /* Multitextured! This is probably a slow enough path that
1039 there's no reason to specialize the multitexture case. */
1040 switch (VB
->TexCoordPtr
[1]->size
) {
1042 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1043 VB
->TexCoordPtr
[1]->data
[i
][3] );
1044 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1045 VB
->TexCoordPtr
[1]->data
[i
][3] );
1046 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1047 VB
->TexCoordPtr
[1]->data
[i
][3] );
1050 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1051 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1052 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1055 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1056 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1060 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1065 /* should never get here */
1067 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1071 /* don't think this is needed
1072 PB_SET_COLOR( red, green, blue, alpha );
1075 for (iy
=y0
;iy
<=y1
;iy
++) {
1076 for (ix
=x0
;ix
<=x1
;ix
++) {
1077 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1078 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1080 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
1084 PB_CHECK_FLUSH(ctx
,PB
);
1090 * Distance Attenuated Antialiased points with or without texture mapping.
1093 dist_atten_antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
1095 struct vertex_buffer
*VB
= ctx
->VB
;
1096 struct pixel_buffer
*PB
= ctx
->PB
;
1097 GLfloat dist
[VB_SIZE
];
1098 const GLfloat psize
= ctx
->Point
.Size
;
1101 if (ctx
->NeedEyeCoords
)
1102 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1104 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1106 if (ctx
->Texture
.ReallyEnabled
) {
1107 for (i
=first
;i
<=last
;i
++) {
1108 if (VB
->ClipMask
[i
]==0) {
1109 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1110 GLint xmin
, ymin
, xmax
, ymax
;
1112 GLint red
, green
, blue
, alpha
;
1115 GLfloat dsize
= psize
* dist
[i
];
1117 if (dsize
>= ctx
->Point
.Threshold
) {
1118 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1122 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1123 dsize
/= ctx
->Point
.Threshold
;
1124 alphaf
= (dsize
*dsize
);
1126 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1127 rmax
= radius
+ 0.7071F
;
1128 rmin2
= MAX2(0.0, rmin
* rmin
);
1129 rmax2
= rmax
* rmax
;
1130 cscale
= 256.0F
/ (rmax2
- rmin2
);
1132 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1133 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1134 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1135 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1136 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1138 red
= VB
->ColorPtr
->data
[i
][0];
1139 green
= VB
->ColorPtr
->data
[i
][1];
1140 blue
= VB
->ColorPtr
->data
[i
][2];
1142 switch (VB
->TexCoordPtr
[0]->size
) {
1144 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1145 VB
->TexCoordPtr
[0]->data
[i
][3]);
1146 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1147 VB
->TexCoordPtr
[0]->data
[i
][3]);
1148 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1149 VB
->TexCoordPtr
[0]->data
[i
][3]);
1152 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1153 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1154 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1157 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1158 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1162 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1167 /* should never get here */
1169 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1172 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1173 /* Multitextured! This is probably a slow enough path that
1174 there's no reason to specialize the multitexture case. */
1175 switch (VB
->TexCoordPtr
[1]->size
) {
1177 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1178 VB
->TexCoordPtr
[1]->data
[i
][3] );
1179 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1180 VB
->TexCoordPtr
[1]->data
[i
][3] );
1181 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1182 VB
->TexCoordPtr
[1]->data
[i
][3] );
1185 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1186 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1187 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1190 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1191 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1195 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1200 /* should never get here */
1202 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1206 for (y
= ymin
; y
<= ymax
; y
++) {
1207 for (x
= xmin
; x
<= xmax
; x
++) {
1208 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1209 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1210 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
1211 if (dist2
< rmax2
) {
1212 alpha
= VB
->ColorPtr
->data
[i
][3];
1213 if (dist2
>= rmin2
) {
1214 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1215 /* coverage is in [0,256] */
1216 alpha
= (alpha
* coverage
) >> 8;
1218 alpha
= (GLint
) (alpha
* alphaf
);
1219 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1220 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
1221 alpha
, s
, t
, u
, s1
, t1
, u1
);
1223 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
,
1229 PB_CHECK_FLUSH(ctx
,PB
);
1234 /* Not texture mapped */
1235 for (i
= first
; i
<= last
; i
++) {
1236 if (VB
->ClipMask
[i
] == 0) {
1237 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1238 GLint xmin
, ymin
, xmax
, ymax
;
1240 GLint red
, green
, blue
, alpha
;
1241 GLfloat dsize
= psize
* dist
[i
];
1243 if (dsize
>= ctx
->Point
.Threshold
) {
1244 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1248 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1249 dsize
/= ctx
->Point
.Threshold
;
1250 alphaf
= dsize
* dsize
;
1252 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1253 rmax
= radius
+ 0.7071F
;
1254 rmin2
= MAX2(0.0, rmin
* rmin
);
1255 rmax2
= rmax
* rmax
;
1256 cscale
= 256.0F
/ (rmax2
- rmin2
);
1258 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1259 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1260 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1261 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1262 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1264 red
= VB
->ColorPtr
->data
[i
][0];
1265 green
= VB
->ColorPtr
->data
[i
][1];
1266 blue
= VB
->ColorPtr
->data
[i
][2];
1268 for (y
= ymin
; y
<= ymax
; y
++) {
1269 for (x
= xmin
; x
<= xmax
; x
++) {
1270 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1271 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1272 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
1273 if (dist2
< rmax2
) {
1274 alpha
= VB
->ColorPtr
->data
[i
][3];
1275 if (dist2
>= rmin2
) {
1276 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1277 /* coverage is in [0,256] */
1278 alpha
= (alpha
* coverage
) >> 8;
1280 alpha
= (GLint
) (alpha
* alphaf
);
1281 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, red
, green
, blue
, alpha
);
1285 PB_CHECK_FLUSH(ctx
,PB
);
1294 _mesa_print_points_function(GLcontext
*ctx
)
1296 printf("Point Func == ");
1297 if (ctx
->Driver
.PointsFunc
== size1_ci_points
)
1298 printf("size1_ci_points\n");
1299 else if (ctx
->Driver
.PointsFunc
== size1_rgba_points
)
1300 printf("size1_rgba_points\n");
1301 else if (ctx
->Driver
.PointsFunc
== general_ci_points
)
1302 printf("general_ci_points\n");
1303 else if (ctx
->Driver
.PointsFunc
== general_rgba_points
)
1304 printf("general_rgba_points\n");
1305 else if (ctx
->Driver
.PointsFunc
== textured_rgba_points
)
1306 printf("textured_rgba_points\n");
1307 else if (ctx
->Driver
.PointsFunc
== multitextured_rgba_points
)
1308 printf("multitextured_rgba_points\n");
1309 else if (ctx
->Driver
.PointsFunc
== antialiased_rgba_points
)
1310 printf("antialiased_rgba_points\n");
1311 else if (ctx
->Driver
.PointsFunc
== null_points
)
1312 printf("null_points\n");
1313 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_ci_points
)
1314 printf("dist_atten_general_ci_points\n");
1315 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_rgba_points
)
1316 printf("dist_atten_general_rgba_points\n");
1317 else if (ctx
->Driver
.PointsFunc
== dist_atten_textured_rgba_points
)
1318 printf("dist_atten_textured_rgba_points\n");
1319 else if (ctx
->Driver
.PointsFunc
== dist_atten_antialiased_rgba_points
)
1320 printf("dist_atten_antialiased_rgba_points\n");
1321 else if (!ctx
->Driver
.PointsFunc
)
1324 printf("Driver func %p\n", ctx
->Driver
.PointsFunc
);
1330 * Examine the current context to determine which point drawing function
1333 void gl_set_point_function( GLcontext
*ctx
)
1335 GLboolean rgbmode
= ctx
->Visual
->RGBAflag
;
1337 if (ctx
->RenderMode
==GL_RENDER
) {
1338 if (ctx
->NoRaster
) {
1339 ctx
->Driver
.PointsFunc
= null_points
;
1342 if (ctx
->Driver
.PointsFunc
) {
1343 /* Device driver will draw points. */
1344 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1348 if (!ctx
->Point
.Attenuated
) {
1349 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1350 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1352 else if (ctx
->Texture
.ReallyEnabled
) {
1353 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
||
1354 ctx
->Light
.Model
.ColorControl
==GL_SEPARATE_SPECULAR_COLOR
) {
1355 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1358 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1361 else if (ctx
->Point
.Size
==1.0) {
1362 /* size=1, any raster ops */
1364 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1366 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1369 /* every other kind of point rendering */
1371 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1373 ctx
->Driver
.PointsFunc
= general_ci_points
;
1376 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1377 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1379 else if (ctx
->Texture
.ReallyEnabled
) {
1380 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1383 /* every other kind of point rendering */
1385 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1387 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1390 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1391 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1394 /* GL_SELECT mode */
1395 ctx
->Driver
.PointsFunc
= gl_select_points
;
1398 /*_mesa_print_points_function(ctx);*/