1 /* $Id: points.c,v 1.5 1999/11/11 01:22:27 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 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
.Size
!= size
) {
58 ctx
->Point
.Size
= size
;
59 ctx
->TriangleCaps
&= ~DD_POINT_SIZE
;
60 if (size
!= 1.0) ctx
->TriangleCaps
|= DD_POINT_SIZE
;
61 ctx
->NewState
|= NEW_RASTER_OPS
;
68 _mesa_PointParameterfEXT( GLenum pname
, GLfloat param
)
70 _mesa_PointParameterfvEXT(pname
, ¶m
);
75 _mesa_PointParameterfvEXT( GLenum pname
, const GLfloat
*params
)
77 GET_CURRENT_CONTEXT(ctx
);
78 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointParameterfvEXT");
80 if (pname
== GL_DISTANCE_ATTENUATION_EXT
) {
81 GLboolean tmp
= ctx
->Point
.Attenuated
;
82 COPY_3V(ctx
->Point
.Params
,params
);
83 ctx
->Point
.Attenuated
= (params
[0] != 1.0 ||
87 if (tmp
!= ctx
->Point
.Attenuated
) {
88 ctx
->Enabled
^= ENABLE_POINT_ATTEN
;
89 ctx
->TriangleCaps
^= DD_POINT_ATTEN
;
90 ctx
->NewState
|= NEW_RASTER_OPS
;
95 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
99 case GL_POINT_SIZE_MIN_EXT
:
100 ctx
->Point
.MinSize
=*params
;
102 case GL_POINT_SIZE_MAX_EXT
:
103 ctx
->Point
.MaxSize
=*params
;
105 case GL_POINT_FADE_THRESHOLD_SIZE_EXT
:
106 ctx
->Point
.Threshold
=*params
;
109 gl_error( ctx
, GL_INVALID_ENUM
, "glPointParameterfvEXT" );
113 ctx
->NewState
|= NEW_RASTER_OPS
;
117 /**********************************************************************/
118 /***** Rasterization *****/
119 /**********************************************************************/
123 * There are 3 pairs (RGBA, CI) of point rendering functions:
124 * 1. simple: size=1 and no special rasterization functions (fastest)
125 * 2. size1: size=1 and any rasterization functions
126 * 3. general: any size and rasterization functions (slowest)
128 * All point rendering functions take the same two arguments: first and
129 * last which specify that the points specified by VB[first] through
130 * VB[last] are to be rendered.
138 * CI points with size == 1.0
140 static void size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
142 struct vertex_buffer
*VB
= ctx
->VB
;
143 struct pixel_buffer
*PB
= ctx
->PB
;
145 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
146 GLdepth
*pbz
= PB
->z
;
148 GLuint pbcount
= PB
->count
;
151 win
= &VB
->Win
.data
[first
][0];
152 for (i
=first
;i
<=last
;i
++) {
153 if (VB
->ClipMask
[i
]==0) {
154 pbx
[pbcount
] = (GLint
) win
[0];
155 pby
[pbcount
] = (GLint
) win
[1];
156 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
157 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
163 PB_CHECK_FLUSH(ctx
, PB
);
169 * RGBA points with size == 1.0
171 static void size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
173 struct vertex_buffer
*VB
= ctx
->VB
;
174 struct pixel_buffer
*PB
= ctx
->PB
;
177 for (i
=first
;i
<=last
;i
++) {
178 if (VB
->ClipMask
[i
]==0) {
180 GLint red
, green
, blue
, alpha
;
182 x
= (GLint
) VB
->Win
.data
[i
][0];
183 y
= (GLint
) VB
->Win
.data
[i
][1];
184 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
186 red
= VB
->ColorPtr
->data
[i
][0];
187 green
= VB
->ColorPtr
->data
[i
][1];
188 blue
= VB
->ColorPtr
->data
[i
][2];
189 alpha
= VB
->ColorPtr
->data
[i
][3];
191 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
);
194 PB_CHECK_FLUSH(ctx
,PB
);
202 static void general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
204 struct vertex_buffer
*VB
= ctx
->VB
;
205 struct pixel_buffer
*PB
= ctx
->PB
;
207 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
208 GLint radius
= isize
>> 1;
210 for (i
=first
;i
<=last
;i
++) {
211 if (VB
->ClipMask
[i
]==0) {
213 GLint x0
, x1
, y0
, y1
;
216 x
= (GLint
) VB
->Win
.data
[i
][0];
217 y
= (GLint
) VB
->Win
.data
[i
][1];
218 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
229 x0
= (GLint
) (x
+ 1.5F
) - radius
;
231 y0
= (GLint
) (y
+ 1.5F
) - radius
;
235 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
237 for (iy
=y0
;iy
<=y1
;iy
++) {
238 for (ix
=x0
;ix
<=x1
;ix
++) {
239 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
242 PB_CHECK_FLUSH(ctx
,PB
);
249 * General RGBA points.
251 static void general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
253 struct vertex_buffer
*VB
= ctx
->VB
;
254 struct pixel_buffer
*PB
= ctx
->PB
;
256 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
257 GLint radius
= isize
>> 1;
259 for (i
=first
;i
<=last
;i
++) {
260 if (VB
->ClipMask
[i
]==0) {
262 GLint x0
, x1
, y0
, y1
;
265 x
= (GLint
) VB
->Win
.data
[i
][0];
266 y
= (GLint
) VB
->Win
.data
[i
][1];
267 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
278 x0
= (GLint
) (x
+ 1.5F
) - radius
;
280 y0
= (GLint
) (y
+ 1.5F
) - radius
;
284 PB_SET_COLOR( ctx
, PB
,
285 VB
->ColorPtr
->data
[i
][0],
286 VB
->ColorPtr
->data
[i
][1],
287 VB
->ColorPtr
->data
[i
][2],
288 VB
->ColorPtr
->data
[i
][3] );
290 for (iy
=y0
;iy
<=y1
;iy
++) {
291 for (ix
=x0
;ix
<=x1
;ix
++) {
292 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
295 PB_CHECK_FLUSH(ctx
,PB
);
304 * Textured RGBA points.
306 static void textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
308 struct vertex_buffer
*VB
= ctx
->VB
;
309 struct pixel_buffer
*PB
= ctx
->PB
;
312 for (i
=first
;i
<=last
;i
++) {
313 if (VB
->ClipMask
[i
]==0) {
315 GLint x0
, x1
, y0
, y1
;
318 GLint red
, green
, blue
, alpha
;
321 x
= (GLint
) VB
->Win
.data
[i
][0];
322 y
= (GLint
) VB
->Win
.data
[i
][1];
323 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
326 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
341 x0
= (GLint
) (x
+ 1.5F
) - radius
;
343 y0
= (GLint
) (y
+ 1.5F
) - radius
;
347 red
= VB
->ColorPtr
->data
[i
][0];
348 green
= VB
->ColorPtr
->data
[i
][1];
349 blue
= VB
->ColorPtr
->data
[i
][2];
350 alpha
= VB
->ColorPtr
->data
[i
][3];
352 switch (VB
->TexCoordPtr
[0]->size
) {
354 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
355 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
356 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
359 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
360 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
361 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
364 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
365 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
369 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
374 /* should never get here */
376 gl_problem(ctx
, "unexpected texcoord size in textured_rgba_points()");
379 /* don't think this is needed
380 PB_SET_COLOR( red, green, blue, alpha );
383 for (iy
=y0
;iy
<=y1
;iy
++) {
384 for (ix
=x0
;ix
<=x1
;ix
++) {
385 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
388 PB_CHECK_FLUSH(ctx
,PB
);
395 * Multitextured RGBA points.
397 static void multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
399 struct vertex_buffer
*VB
= ctx
->VB
;
400 struct pixel_buffer
*PB
= ctx
->PB
;
403 for (i
=first
;i
<=last
;i
++) {
404 if (VB
->ClipMask
[i
]==0) {
406 GLint x0
, x1
, y0
, y1
;
409 GLint red
, green
, blue
, alpha
;
413 x
= (GLint
) VB
->Win
.data
[i
][0];
414 y
= (GLint
) VB
->Win
.data
[i
][1];
415 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
418 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
433 x0
= (GLint
) (x
+ 1.5F
) - radius
;
435 y0
= (GLint
) (y
+ 1.5F
) - radius
;
439 red
= VB
->ColorPtr
->data
[i
][0];
440 green
= VB
->ColorPtr
->data
[i
][1];
441 blue
= VB
->ColorPtr
->data
[i
][2];
442 alpha
= VB
->ColorPtr
->data
[i
][3];
444 switch (VB
->TexCoordPtr
[0]->size
) {
446 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
447 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
448 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
451 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
452 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
453 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
456 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
457 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
461 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
466 /* should never get here */
468 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
471 switch (VB
->TexCoordPtr
[1]->size
) {
473 s1
= VB
->TexCoordPtr
[1]->data
[i
][0]/VB
->TexCoordPtr
[1]->data
[i
][3];
474 t1
= VB
->TexCoordPtr
[1]->data
[i
][1]/VB
->TexCoordPtr
[1]->data
[i
][3];
475 u1
= VB
->TexCoordPtr
[1]->data
[i
][2]/VB
->TexCoordPtr
[1]->data
[i
][3];
478 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
479 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
480 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
483 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
484 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
488 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
493 /* should never get here */
495 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
498 for (iy
=y0
;iy
<=y1
;iy
++) {
499 for (ix
=x0
;ix
<=x1
;ix
++) {
500 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
503 PB_CHECK_FLUSH(ctx
,PB
);
512 * Antialiased points with or without texture mapping.
514 static void antialiased_rgba_points( GLcontext
*ctx
,
515 GLuint first
, GLuint last
)
517 struct vertex_buffer
*VB
= ctx
->VB
;
518 struct pixel_buffer
*PB
= ctx
->PB
;
520 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
522 radius
= CLAMP( ctx
->Point
.Size
, MIN_POINT_SIZE
, MAX_POINT_SIZE
) * 0.5F
;
523 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
524 rmax
= radius
+ 0.7071F
;
527 cscale
= 256.0F
/ (rmax2
-rmin2
);
529 if (ctx
->Texture
.ReallyEnabled
) {
530 for (i
=first
;i
<=last
;i
++) {
531 if (VB
->ClipMask
[i
]==0) {
532 GLint xmin
, ymin
, xmax
, ymax
;
534 GLint red
, green
, blue
, alpha
;
538 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
539 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
540 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
541 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
542 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
544 red
= VB
->ColorPtr
->data
[i
][0];
545 green
= VB
->ColorPtr
->data
[i
][1];
546 blue
= VB
->ColorPtr
->data
[i
][2];
548 switch (VB
->TexCoordPtr
[0]->size
) {
550 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
551 VB
->TexCoordPtr
[0]->data
[i
][3]);
552 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
553 VB
->TexCoordPtr
[0]->data
[i
][3]);
554 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
555 VB
->TexCoordPtr
[0]->data
[i
][3]);
558 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
559 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
560 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
563 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
564 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
568 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
573 /* should never get here */
575 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
578 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
579 /* Multitextured! This is probably a slow enough path that
580 there's no reason to specialize the multitexture case. */
581 switch (VB
->TexCoordPtr
[1]->size
) {
583 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
584 VB
->TexCoordPtr
[1]->data
[i
][3]);
585 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
586 VB
->TexCoordPtr
[1]->data
[i
][3]);
587 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
588 VB
->TexCoordPtr
[1]->data
[i
][3]);
591 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
592 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
593 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
596 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
597 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
601 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
606 /* should never get here */
608 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
612 for (y
=ymin
;y
<=ymax
;y
++) {
613 for (x
=xmin
;x
<=xmax
;x
++) {
614 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
615 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
616 GLfloat dist2
= dx
*dx
+ dy
*dy
;
618 alpha
= VB
->ColorPtr
->data
[i
][3];
620 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
621 /* coverage is in [0,256] */
622 alpha
= (alpha
* coverage
) >> 8;
624 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
625 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
626 alpha
, s
, t
, u
, s1
, t1
, u1
);
628 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
635 PB_CHECK_FLUSH(ctx
,PB
);
640 /* Not texture mapped */
641 for (i
=first
;i
<=last
;i
++) {
642 if (VB
->ClipMask
[i
]==0) {
643 GLint xmin
, ymin
, xmax
, ymax
;
645 GLint red
, green
, blue
, alpha
;
647 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
648 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
649 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
650 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
651 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
653 red
= VB
->ColorPtr
->data
[i
][0];
654 green
= VB
->ColorPtr
->data
[i
][1];
655 blue
= VB
->ColorPtr
->data
[i
][2];
657 for (y
=ymin
;y
<=ymax
;y
++) {
658 for (x
=xmin
;x
<=xmax
;x
++) {
659 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
660 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
661 GLfloat dist2
= dx
*dx
+ dy
*dy
;
663 alpha
= VB
->ColorPtr
->data
[i
][3];
665 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
666 /* coverage is in [0,256] */
667 alpha
= (alpha
* coverage
) >> 8;
669 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
,
674 PB_CHECK_FLUSH(ctx
,PB
);
683 * Null rasterizer for measuring transformation speed.
685 static void null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
694 /* Definition of the functions for GL_EXT_point_parameters */
696 /* Calculates the distance attenuation formula of a vector of points in
697 * eye space coordinates
699 static void dist3(GLfloat
*out
, GLuint first
, GLuint last
,
700 const GLcontext
*ctx
, const GLvector4f
*v
)
702 GLuint stride
= v
->stride
;
703 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
706 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
708 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
709 out
[i
] = 1/(ctx
->Point
.Params
[0]+
710 dist
* (ctx
->Point
.Params
[1] +
711 dist
* ctx
->Point
.Params
[2]));
715 static void dist2(GLfloat
*out
, GLuint first
, GLuint last
,
716 const GLcontext
*ctx
, const GLvector4f
*v
)
718 GLuint stride
= v
->stride
;
719 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
722 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
724 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
725 out
[i
] = 1/(ctx
->Point
.Params
[0]+
726 dist
* (ctx
->Point
.Params
[1] +
727 dist
* ctx
->Point
.Params
[2]));
732 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
733 const GLcontext
*ctx
, const GLvector4f
*v
);
736 static dist_func eye_dist_tab
[5] = {
745 static void clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
746 const GLcontext
*ctx
, GLvector4f
*clip
)
748 /* this is never called */
749 gl_problem(NULL
, "clip_dist() called - dead code!\n");
759 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
760 const GLuint stride
= clip_vec
->stride
;
762 for (i
= first
; i
<= last
; i
++ )
764 GLfloat dist
= win
[i
][2];
765 out
[i
] = 1/(ctx
->Point
.Params
[0]+
766 dist
* (ctx
->Point
.Params
[1] +
767 dist
* ctx
->Point
.Params
[2]));
775 * Distance Attenuated General CI points.
777 static void dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
,
780 struct vertex_buffer
*VB
= ctx
->VB
;
781 struct pixel_buffer
*PB
= ctx
->PB
;
784 GLfloat dist
[VB_SIZE
];
785 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
787 if (ctx
->NeedEyeCoords
)
788 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
790 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
792 for (i
=first
;i
<=last
;i
++) {
793 if (VB
->ClipMask
[i
]==0) {
795 GLint x0
, x1
, y0
, y1
;
799 x
= (GLint
) VB
->Win
.data
[i
][0];
800 y
= (GLint
) VB
->Win
.data
[i
][1];
801 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
804 if(dsize
>=ctx
->Point
.Threshold
) {
805 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
807 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
820 x0
= (GLint
) (x
+ 1.5F
) - radius
;
822 y0
= (GLint
) (y
+ 1.5F
) - radius
;
826 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
828 for (iy
=y0
;iy
<=y1
;iy
++) {
829 for (ix
=x0
;ix
<=x1
;ix
++) {
830 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
833 PB_CHECK_FLUSH(ctx
,PB
);
839 * Distance Attenuated General RGBA points.
841 static void dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
,
844 struct vertex_buffer
*VB
= ctx
->VB
;
845 struct pixel_buffer
*PB
= ctx
->PB
;
849 GLfloat dist
[VB_SIZE
];
850 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
852 if (ctx
->NeedEyeCoords
)
853 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
855 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
857 for (i
=first
;i
<=last
;i
++) {
858 if (VB
->ClipMask
[i
]==0) {
860 GLint x0
, x1
, y0
, y1
;
864 x
= (GLint
) VB
->Win
.data
[i
][0];
865 y
= (GLint
) VB
->Win
.data
[i
][1];
866 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
868 if (dsize
>= ctx
->Point
.Threshold
) {
869 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
870 alpha
= VB
->ColorPtr
->data
[i
][3];
873 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
874 dsize
/= ctx
->Point
.Threshold
;
875 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
888 x0
= (GLint
) (x
+ 1.5F
) - radius
;
890 y0
= (GLint
) (y
+ 1.5F
) - radius
;
894 PB_SET_COLOR( ctx
, PB
,
895 VB
->ColorPtr
->data
[i
][0],
896 VB
->ColorPtr
->data
[i
][1],
897 VB
->ColorPtr
->data
[i
][2],
900 for (iy
=y0
;iy
<=y1
;iy
++) {
901 for (ix
=x0
;ix
<=x1
;ix
++) {
902 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
905 PB_CHECK_FLUSH(ctx
,PB
);
911 * Distance Attenuated Textured RGBA points.
913 static void dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
,
916 struct vertex_buffer
*VB
= ctx
->VB
;
917 struct pixel_buffer
*PB
= ctx
->PB
;
920 GLfloat dist
[VB_SIZE
];
921 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
923 if (ctx
->NeedEyeCoords
)
924 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
926 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
928 for (i
=first
;i
<=last
;i
++) {
929 if (VB
->ClipMask
[i
]==0) {
931 GLint x0
, x1
, y0
, y1
;
934 GLint red
, green
, blue
, alpha
;
938 x
= (GLint
) VB
->Win
.data
[i
][0];
939 y
= (GLint
) VB
->Win
.data
[i
][1];
940 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
943 if(dsize
>=ctx
->Point
.Threshold
) {
944 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
945 alpha
=VB
->ColorPtr
->data
[i
][3];
947 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
948 dsize
/=ctx
->Point
.Threshold
;
949 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
966 x0
= (GLint
) (x
+ 1.5F
) - radius
;
968 y0
= (GLint
) (y
+ 1.5F
) - radius
;
972 red
= VB
->ColorPtr
->data
[i
][0];
973 green
= VB
->ColorPtr
->data
[i
][1];
974 blue
= VB
->ColorPtr
->data
[i
][2];
976 switch (VB
->TexCoordPtr
[0]->size
) {
978 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
979 VB
->TexCoordPtr
[0]->data
[i
][3]);
980 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
981 VB
->TexCoordPtr
[0]->data
[i
][3]);
982 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
983 VB
->TexCoordPtr
[0]->data
[i
][3]);
986 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
987 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
988 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
991 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
992 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
996 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1001 /* should never get here */
1003 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1006 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1007 /* Multitextured! This is probably a slow enough path that
1008 there's no reason to specialize the multitexture case. */
1009 switch (VB
->TexCoordPtr
[1]->size
) {
1011 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1012 VB
->TexCoordPtr
[1]->data
[i
][3] );
1013 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1014 VB
->TexCoordPtr
[1]->data
[i
][3] );
1015 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1016 VB
->TexCoordPtr
[1]->data
[i
][3] );
1019 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1020 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1021 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1024 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1025 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1029 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1034 /* should never get here */
1036 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1040 /* don't think this is needed
1041 PB_SET_COLOR( red, green, blue, alpha );
1044 for (iy
=y0
;iy
<=y1
;iy
++) {
1045 for (ix
=x0
;ix
<=x1
;ix
++) {
1046 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1047 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1049 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
1053 PB_CHECK_FLUSH(ctx
,PB
);
1059 * Distance Attenuated Antialiased points with or without texture mapping.
1061 static void dist_atten_antialiased_rgba_points( GLcontext
*ctx
,
1062 GLuint first
, GLuint last
)
1064 struct vertex_buffer
*VB
= ctx
->VB
;
1065 struct pixel_buffer
*PB
= ctx
->PB
;
1067 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
1068 GLfloat psize
,dsize
,alphaf
;
1069 GLfloat dist
[VB_SIZE
];
1070 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
1072 if (ctx
->NeedEyeCoords
)
1073 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1075 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1077 if (ctx
->Texture
.ReallyEnabled
) {
1078 for (i
=first
;i
<=last
;i
++) {
1079 if (VB
->ClipMask
[i
]==0) {
1080 GLint xmin
, ymin
, xmax
, ymax
;
1082 GLint red
, green
, blue
, alpha
;
1086 dsize
=psize
*dist
[i
];
1087 if(dsize
>=ctx
->Point
.Threshold
) {
1088 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1091 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1092 dsize
/=ctx
->Point
.Threshold
;
1093 alphaf
=(dsize
*dsize
);
1095 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1096 rmax
= radius
+ 0.7071F
;
1099 cscale
= 256.0F
/ (rmax2
-rmin2
);
1101 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1102 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1103 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1104 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1105 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1107 red
= VB
->ColorPtr
->data
[i
][0];
1108 green
= VB
->ColorPtr
->data
[i
][1];
1109 blue
= VB
->ColorPtr
->data
[i
][2];
1111 switch (VB
->TexCoordPtr
[0]->size
) {
1113 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1114 VB
->TexCoordPtr
[0]->data
[i
][3]);
1115 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1116 VB
->TexCoordPtr
[0]->data
[i
][3]);
1117 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1118 VB
->TexCoordPtr
[0]->data
[i
][3]);
1121 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1122 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1123 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1126 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1127 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1131 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1136 /* should never get here */
1138 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1141 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1142 /* Multitextured! This is probably a slow enough path that
1143 there's no reason to specialize the multitexture case. */
1144 switch (VB
->TexCoordPtr
[1]->size
) {
1146 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1147 VB
->TexCoordPtr
[1]->data
[i
][3] );
1148 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1149 VB
->TexCoordPtr
[1]->data
[i
][3] );
1150 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1151 VB
->TexCoordPtr
[1]->data
[i
][3] );
1154 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1155 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1156 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1159 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1160 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1164 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1169 /* should never get here */
1171 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1175 for (y
=ymin
;y
<=ymax
;y
++) {
1176 for (x
=xmin
;x
<=xmax
;x
++) {
1177 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1178 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1179 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1181 alpha
= VB
->ColorPtr
->data
[i
][3];
1183 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1184 /* coverage is in [0,256] */
1185 alpha
= (alpha
* coverage
) >> 8;
1187 alpha
= (GLint
) (alpha
* alphaf
);
1188 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1189 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1191 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
);
1196 PB_CHECK_FLUSH(ctx
,PB
);
1201 /* Not texture mapped */
1202 for (i
=first
;i
<=last
;i
++) {
1203 if (VB
->ClipMask
[i
]==0) {
1204 GLint xmin
, ymin
, xmax
, ymax
;
1206 GLint red
, green
, blue
, alpha
;
1208 dsize
=psize
*dist
[i
];
1209 if(dsize
>=ctx
->Point
.Threshold
) {
1210 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1213 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1214 dsize
/=ctx
->Point
.Threshold
;
1215 alphaf
=(dsize
*dsize
);
1217 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1218 rmax
= radius
+ 0.7071F
;
1221 cscale
= 256.0F
/ (rmax2
-rmin2
);
1223 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1224 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1225 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1226 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1227 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1229 red
= VB
->ColorPtr
->data
[i
][0];
1230 green
= VB
->ColorPtr
->data
[i
][1];
1231 blue
= VB
->ColorPtr
->data
[i
][2];
1233 for (y
=ymin
;y
<=ymax
;y
++) {
1234 for (x
=xmin
;x
<=xmax
;x
++) {
1235 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1236 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1237 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1239 alpha
= VB
->ColorPtr
->data
[i
][3];
1241 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1242 /* coverage is in [0,256] */
1243 alpha
= (alpha
* coverage
) >> 8;
1245 alpha
= (GLint
) (alpha
* alphaf
);
1246 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
)
1251 PB_CHECK_FLUSH(ctx
,PB
);
1259 * Examine the current context to determine which point drawing function
1262 void gl_set_point_function( GLcontext
*ctx
)
1264 GLboolean rgbmode
= ctx
->Visual
->RGBAflag
;
1266 if (ctx
->RenderMode
==GL_RENDER
) {
1267 if (ctx
->NoRaster
) {
1268 ctx
->Driver
.PointsFunc
= null_points
;
1271 if (ctx
->Driver
.PointsFunc
) {
1272 /* Device driver will draw points. */
1273 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1277 if (!ctx
->Point
.Attenuated
) {
1278 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1279 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1281 else if (ctx
->Texture
.ReallyEnabled
) {
1282 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1283 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1286 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1289 else if (ctx
->Point
.Size
==1.0) {
1290 /* size=1, any raster ops */
1292 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1294 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1297 /* every other kind of point rendering */
1299 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1301 ctx
->Driver
.PointsFunc
= general_ci_points
;
1304 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1305 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1307 else if (ctx
->Texture
.ReallyEnabled
) {
1308 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1311 /* every other kind of point rendering */
1313 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1315 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1318 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1319 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1322 /* GL_SELECT mode */
1323 ctx
->Driver
.PointsFunc
= gl_select_points
;