1 /* $Id: points.c,v 1.7 2000/03/02 18:34:34 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
.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");
81 case GL_DISTANCE_ATTENUATION_EXT
:
83 const GLboolean tmp
= ctx
->Point
.Attenuated
;
84 COPY_3V(ctx
->Point
.Params
, params
);
85 ctx
->Point
.Attenuated
= (params
[0] != 1.0 ||
89 if (tmp
!= ctx
->Point
.Attenuated
) {
90 ctx
->Enabled
^= ENABLE_POINT_ATTEN
;
91 ctx
->TriangleCaps
^= DD_POINT_ATTEN
;
92 ctx
->NewState
|= NEW_RASTER_OPS
;
96 case GL_POINT_SIZE_MIN_EXT
:
98 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
101 ctx
->Point
.MinSize
= *params
;
103 case GL_POINT_SIZE_MAX_EXT
:
104 if (*params
< 0.0F
) {
105 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
108 ctx
->Point
.MaxSize
= *params
;
110 case GL_POINT_FADE_THRESHOLD_SIZE_EXT
:
111 if (*params
< 0.0F
) {
112 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
115 ctx
->Point
.Threshold
= *params
;
118 gl_error( ctx
, GL_INVALID_ENUM
, "glPointParameterfvEXT" );
122 ctx
->NewState
|= NEW_RASTER_OPS
;
126 /**********************************************************************/
127 /***** Rasterization *****/
128 /**********************************************************************/
132 * There are 3 pairs (RGBA, CI) of point rendering functions:
133 * 1. simple: size=1 and no special rasterization functions (fastest)
134 * 2. size1: size=1 and any rasterization functions
135 * 3. general: any size and rasterization functions (slowest)
137 * All point rendering functions take the same two arguments: first and
138 * last which specify that the points specified by VB[first] through
139 * VB[last] are to be rendered.
147 * CI points with size == 1.0
149 static void size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
151 struct vertex_buffer
*VB
= ctx
->VB
;
152 struct pixel_buffer
*PB
= ctx
->PB
;
154 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
155 GLdepth
*pbz
= PB
->z
;
157 GLuint pbcount
= PB
->count
;
160 win
= &VB
->Win
.data
[first
][0];
161 for (i
=first
;i
<=last
;i
++) {
162 if (VB
->ClipMask
[i
]==0) {
163 pbx
[pbcount
] = (GLint
) win
[0];
164 pby
[pbcount
] = (GLint
) win
[1];
165 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
166 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
172 PB_CHECK_FLUSH(ctx
, PB
);
178 * RGBA points with size == 1.0
180 static void size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
182 struct vertex_buffer
*VB
= ctx
->VB
;
183 struct pixel_buffer
*PB
= ctx
->PB
;
186 for (i
=first
;i
<=last
;i
++) {
187 if (VB
->ClipMask
[i
]==0) {
189 GLint red
, green
, blue
, alpha
;
191 x
= (GLint
) VB
->Win
.data
[i
][0];
192 y
= (GLint
) VB
->Win
.data
[i
][1];
193 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
195 red
= VB
->ColorPtr
->data
[i
][0];
196 green
= VB
->ColorPtr
->data
[i
][1];
197 blue
= VB
->ColorPtr
->data
[i
][2];
198 alpha
= VB
->ColorPtr
->data
[i
][3];
200 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
);
203 PB_CHECK_FLUSH(ctx
,PB
);
211 static void general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
213 struct vertex_buffer
*VB
= ctx
->VB
;
214 struct pixel_buffer
*PB
= ctx
->PB
;
216 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
217 GLint radius
= isize
>> 1;
219 for (i
=first
;i
<=last
;i
++) {
220 if (VB
->ClipMask
[i
]==0) {
222 GLint x0
, x1
, y0
, y1
;
225 x
= (GLint
) VB
->Win
.data
[i
][0];
226 y
= (GLint
) VB
->Win
.data
[i
][1];
227 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
238 x0
= (GLint
) (x
+ 1.5F
) - radius
;
240 y0
= (GLint
) (y
+ 1.5F
) - radius
;
244 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
246 for (iy
=y0
;iy
<=y1
;iy
++) {
247 for (ix
=x0
;ix
<=x1
;ix
++) {
248 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
251 PB_CHECK_FLUSH(ctx
,PB
);
258 * General RGBA points.
260 static void general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
262 struct vertex_buffer
*VB
= ctx
->VB
;
263 struct pixel_buffer
*PB
= ctx
->PB
;
265 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
266 GLint radius
= isize
>> 1;
268 for (i
=first
;i
<=last
;i
++) {
269 if (VB
->ClipMask
[i
]==0) {
271 GLint x0
, x1
, y0
, y1
;
274 x
= (GLint
) VB
->Win
.data
[i
][0];
275 y
= (GLint
) VB
->Win
.data
[i
][1];
276 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
287 x0
= (GLint
) (x
+ 1.5F
) - radius
;
289 y0
= (GLint
) (y
+ 1.5F
) - radius
;
293 PB_SET_COLOR( ctx
, PB
,
294 VB
->ColorPtr
->data
[i
][0],
295 VB
->ColorPtr
->data
[i
][1],
296 VB
->ColorPtr
->data
[i
][2],
297 VB
->ColorPtr
->data
[i
][3] );
299 for (iy
=y0
;iy
<=y1
;iy
++) {
300 for (ix
=x0
;ix
<=x1
;ix
++) {
301 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
304 PB_CHECK_FLUSH(ctx
,PB
);
313 * Textured RGBA points.
315 static void textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
317 struct vertex_buffer
*VB
= ctx
->VB
;
318 struct pixel_buffer
*PB
= ctx
->PB
;
321 for (i
=first
;i
<=last
;i
++) {
322 if (VB
->ClipMask
[i
]==0) {
324 GLint x0
, x1
, y0
, y1
;
327 GLint red
, green
, blue
, alpha
;
330 x
= (GLint
) VB
->Win
.data
[i
][0];
331 y
= (GLint
) VB
->Win
.data
[i
][1];
332 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
335 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
350 x0
= (GLint
) (x
+ 1.5F
) - radius
;
352 y0
= (GLint
) (y
+ 1.5F
) - radius
;
356 red
= VB
->ColorPtr
->data
[i
][0];
357 green
= VB
->ColorPtr
->data
[i
][1];
358 blue
= VB
->ColorPtr
->data
[i
][2];
359 alpha
= VB
->ColorPtr
->data
[i
][3];
361 switch (VB
->TexCoordPtr
[0]->size
) {
363 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
364 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
365 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
368 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
369 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
370 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
373 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
374 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
378 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
383 /* should never get here */
385 gl_problem(ctx
, "unexpected texcoord size in textured_rgba_points()");
388 /* don't think this is needed
389 PB_SET_COLOR( red, green, blue, alpha );
392 for (iy
=y0
;iy
<=y1
;iy
++) {
393 for (ix
=x0
;ix
<=x1
;ix
++) {
394 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
397 PB_CHECK_FLUSH(ctx
,PB
);
404 * Multitextured RGBA points.
406 static void multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
408 struct vertex_buffer
*VB
= ctx
->VB
;
409 struct pixel_buffer
*PB
= ctx
->PB
;
412 for (i
=first
;i
<=last
;i
++) {
413 if (VB
->ClipMask
[i
]==0) {
415 GLint x0
, x1
, y0
, y1
;
418 GLint red
, green
, blue
, alpha
;
422 x
= (GLint
) VB
->Win
.data
[i
][0];
423 y
= (GLint
) VB
->Win
.data
[i
][1];
424 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
427 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_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];
453 switch (VB
->TexCoordPtr
[0]->size
) {
455 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
456 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
457 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
460 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
461 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
462 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
465 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
466 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
470 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
475 /* should never get here */
477 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
480 switch (VB
->TexCoordPtr
[1]->size
) {
482 s1
= VB
->TexCoordPtr
[1]->data
[i
][0]/VB
->TexCoordPtr
[1]->data
[i
][3];
483 t1
= VB
->TexCoordPtr
[1]->data
[i
][1]/VB
->TexCoordPtr
[1]->data
[i
][3];
484 u1
= VB
->TexCoordPtr
[1]->data
[i
][2]/VB
->TexCoordPtr
[1]->data
[i
][3];
487 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
488 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
489 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
492 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
493 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
497 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
502 /* should never get here */
504 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
507 for (iy
=y0
;iy
<=y1
;iy
++) {
508 for (ix
=x0
;ix
<=x1
;ix
++) {
509 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
512 PB_CHECK_FLUSH(ctx
,PB
);
521 * Antialiased points with or without texture mapping.
523 static void antialiased_rgba_points( GLcontext
*ctx
,
524 GLuint first
, GLuint last
)
526 struct vertex_buffer
*VB
= ctx
->VB
;
527 struct pixel_buffer
*PB
= ctx
->PB
;
529 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
531 radius
= CLAMP( ctx
->Point
.Size
, MIN_POINT_SIZE
, MAX_POINT_SIZE
) * 0.5F
;
532 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
533 rmax
= radius
+ 0.7071F
;
536 cscale
= 256.0F
/ (rmax2
-rmin2
);
538 if (ctx
->Texture
.ReallyEnabled
) {
539 for (i
=first
;i
<=last
;i
++) {
540 if (VB
->ClipMask
[i
]==0) {
541 GLint xmin
, ymin
, xmax
, ymax
;
543 GLint red
, green
, blue
, alpha
;
547 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
548 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
549 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
550 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
551 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
553 red
= VB
->ColorPtr
->data
[i
][0];
554 green
= VB
->ColorPtr
->data
[i
][1];
555 blue
= VB
->ColorPtr
->data
[i
][2];
557 switch (VB
->TexCoordPtr
[0]->size
) {
559 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
560 VB
->TexCoordPtr
[0]->data
[i
][3]);
561 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
562 VB
->TexCoordPtr
[0]->data
[i
][3]);
563 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
564 VB
->TexCoordPtr
[0]->data
[i
][3]);
567 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
568 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
569 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
572 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
573 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
577 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
582 /* should never get here */
584 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
587 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
588 /* Multitextured! This is probably a slow enough path that
589 there's no reason to specialize the multitexture case. */
590 switch (VB
->TexCoordPtr
[1]->size
) {
592 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
593 VB
->TexCoordPtr
[1]->data
[i
][3]);
594 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
595 VB
->TexCoordPtr
[1]->data
[i
][3]);
596 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
597 VB
->TexCoordPtr
[1]->data
[i
][3]);
600 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
601 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
602 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
605 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
606 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
610 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
615 /* should never get here */
617 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
621 for (y
=ymin
;y
<=ymax
;y
++) {
622 for (x
=xmin
;x
<=xmax
;x
++) {
623 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
624 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
625 GLfloat dist2
= dx
*dx
+ dy
*dy
;
627 alpha
= VB
->ColorPtr
->data
[i
][3];
629 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
630 /* coverage is in [0,256] */
631 alpha
= (alpha
* coverage
) >> 8;
633 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
634 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
635 alpha
, s
, t
, u
, s1
, t1
, u1
);
637 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
644 PB_CHECK_FLUSH(ctx
,PB
);
649 /* Not texture mapped */
650 for (i
=first
;i
<=last
;i
++) {
651 if (VB
->ClipMask
[i
]==0) {
652 GLint xmin
, ymin
, xmax
, ymax
;
654 GLint red
, green
, blue
, alpha
;
656 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
657 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
658 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
659 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
660 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
662 red
= VB
->ColorPtr
->data
[i
][0];
663 green
= VB
->ColorPtr
->data
[i
][1];
664 blue
= VB
->ColorPtr
->data
[i
][2];
666 for (y
=ymin
;y
<=ymax
;y
++) {
667 for (x
=xmin
;x
<=xmax
;x
++) {
668 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
669 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
670 GLfloat dist2
= dx
*dx
+ dy
*dy
;
672 alpha
= VB
->ColorPtr
->data
[i
][3];
674 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
675 /* coverage is in [0,256] */
676 alpha
= (alpha
* coverage
) >> 8;
678 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
,
683 PB_CHECK_FLUSH(ctx
,PB
);
692 * Null rasterizer for measuring transformation speed.
694 static void null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
703 /* Definition of the functions for GL_EXT_point_parameters */
705 /* Calculates the distance attenuation formula of a vector of points in
706 * eye space coordinates
708 static void dist3(GLfloat
*out
, GLuint first
, GLuint last
,
709 const GLcontext
*ctx
, const GLvector4f
*v
)
711 GLuint stride
= v
->stride
;
712 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
715 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
716 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
717 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
718 dist
* (ctx
->Point
.Params
[1] +
719 dist
* ctx
->Point
.Params
[2]));
723 static void dist2(GLfloat
*out
, GLuint first
, GLuint last
,
724 const GLcontext
*ctx
, const GLvector4f
*v
)
726 GLuint stride
= v
->stride
;
727 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
730 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
731 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
732 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
733 dist
* (ctx
->Point
.Params
[1] +
734 dist
* ctx
->Point
.Params
[2]));
739 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
740 const GLcontext
*ctx
, const GLvector4f
*v
);
743 static dist_func eye_dist_tab
[5] = {
752 static void clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
753 const GLcontext
*ctx
, GLvector4f
*clip
)
755 /* this is never called */
756 gl_problem(NULL
, "clip_dist() called - dead code!\n");
766 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
767 const GLuint stride
= clip_vec
->stride
;
769 for (i
= first
; i
<= last
; i
++ )
771 GLfloat dist
= win
[i
][2];
772 out
[i
] = 1/(ctx
->Point
.Params
[0]+
773 dist
* (ctx
->Point
.Params
[1] +
774 dist
* ctx
->Point
.Params
[2]));
782 * Distance Attenuated General CI points.
784 static void dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
,
787 struct vertex_buffer
*VB
= ctx
->VB
;
788 struct pixel_buffer
*PB
= ctx
->PB
;
791 GLfloat dist
[VB_SIZE
];
792 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
794 if (ctx
->NeedEyeCoords
)
795 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
797 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
799 for (i
=first
;i
<=last
;i
++) {
800 if (VB
->ClipMask
[i
]==0) {
802 GLint x0
, x1
, y0
, y1
;
806 x
= (GLint
) VB
->Win
.data
[i
][0];
807 y
= (GLint
) VB
->Win
.data
[i
][1];
808 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
811 if(dsize
>=ctx
->Point
.Threshold
) {
812 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
814 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
827 x0
= (GLint
) (x
+ 1.5F
) - radius
;
829 y0
= (GLint
) (y
+ 1.5F
) - radius
;
833 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
835 for (iy
=y0
;iy
<=y1
;iy
++) {
836 for (ix
=x0
;ix
<=x1
;ix
++) {
837 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
840 PB_CHECK_FLUSH(ctx
,PB
);
846 * Distance Attenuated General RGBA points.
848 static void dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
,
851 struct vertex_buffer
*VB
= ctx
->VB
;
852 struct pixel_buffer
*PB
= ctx
->PB
;
856 GLfloat dist
[VB_SIZE
];
857 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
859 if (ctx
->NeedEyeCoords
)
860 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
862 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
864 for (i
=first
;i
<=last
;i
++) {
865 if (VB
->ClipMask
[i
]==0) {
867 GLint x0
, x1
, y0
, y1
;
871 x
= (GLint
) VB
->Win
.data
[i
][0];
872 y
= (GLint
) VB
->Win
.data
[i
][1];
873 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
875 if (dsize
>= ctx
->Point
.Threshold
) {
876 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
877 alpha
= VB
->ColorPtr
->data
[i
][3];
880 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
881 dsize
/= ctx
->Point
.Threshold
;
882 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
895 x0
= (GLint
) (x
+ 1.5F
) - radius
;
897 y0
= (GLint
) (y
+ 1.5F
) - radius
;
901 PB_SET_COLOR( ctx
, PB
,
902 VB
->ColorPtr
->data
[i
][0],
903 VB
->ColorPtr
->data
[i
][1],
904 VB
->ColorPtr
->data
[i
][2],
907 for (iy
=y0
;iy
<=y1
;iy
++) {
908 for (ix
=x0
;ix
<=x1
;ix
++) {
909 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
912 PB_CHECK_FLUSH(ctx
,PB
);
918 * Distance Attenuated Textured RGBA points.
920 static void dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
,
923 struct vertex_buffer
*VB
= ctx
->VB
;
924 struct pixel_buffer
*PB
= ctx
->PB
;
927 GLfloat dist
[VB_SIZE
];
928 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
930 if (ctx
->NeedEyeCoords
)
931 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
933 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
935 for (i
=first
;i
<=last
;i
++) {
936 if (VB
->ClipMask
[i
]==0) {
938 GLint x0
, x1
, y0
, y1
;
941 GLint red
, green
, blue
, alpha
;
945 x
= (GLint
) VB
->Win
.data
[i
][0];
946 y
= (GLint
) VB
->Win
.data
[i
][1];
947 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
950 if(dsize
>=ctx
->Point
.Threshold
) {
951 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
952 alpha
=VB
->ColorPtr
->data
[i
][3];
954 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
955 dsize
/=ctx
->Point
.Threshold
;
956 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
973 x0
= (GLint
) (x
+ 1.5F
) - radius
;
975 y0
= (GLint
) (y
+ 1.5F
) - radius
;
979 red
= VB
->ColorPtr
->data
[i
][0];
980 green
= VB
->ColorPtr
->data
[i
][1];
981 blue
= VB
->ColorPtr
->data
[i
][2];
983 switch (VB
->TexCoordPtr
[0]->size
) {
985 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
986 VB
->TexCoordPtr
[0]->data
[i
][3]);
987 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
988 VB
->TexCoordPtr
[0]->data
[i
][3]);
989 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
990 VB
->TexCoordPtr
[0]->data
[i
][3]);
993 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
994 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
995 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
998 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
999 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1003 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1008 /* should never get here */
1010 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1013 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1014 /* Multitextured! This is probably a slow enough path that
1015 there's no reason to specialize the multitexture case. */
1016 switch (VB
->TexCoordPtr
[1]->size
) {
1018 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1019 VB
->TexCoordPtr
[1]->data
[i
][3] );
1020 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1021 VB
->TexCoordPtr
[1]->data
[i
][3] );
1022 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1023 VB
->TexCoordPtr
[1]->data
[i
][3] );
1026 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1027 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1028 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1031 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1032 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1036 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1041 /* should never get here */
1043 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1047 /* don't think this is needed
1048 PB_SET_COLOR( red, green, blue, alpha );
1051 for (iy
=y0
;iy
<=y1
;iy
++) {
1052 for (ix
=x0
;ix
<=x1
;ix
++) {
1053 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1054 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1056 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
1060 PB_CHECK_FLUSH(ctx
,PB
);
1066 * Distance Attenuated Antialiased points with or without texture mapping.
1068 static void dist_atten_antialiased_rgba_points( GLcontext
*ctx
,
1069 GLuint first
, GLuint last
)
1071 struct vertex_buffer
*VB
= ctx
->VB
;
1072 struct pixel_buffer
*PB
= ctx
->PB
;
1074 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
1075 GLfloat psize
,dsize
,alphaf
;
1076 GLfloat dist
[VB_SIZE
];
1077 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
1079 if (ctx
->NeedEyeCoords
)
1080 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1082 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1084 if (ctx
->Texture
.ReallyEnabled
) {
1085 for (i
=first
;i
<=last
;i
++) {
1086 if (VB
->ClipMask
[i
]==0) {
1087 GLint xmin
, ymin
, xmax
, ymax
;
1089 GLint red
, green
, blue
, alpha
;
1093 dsize
=psize
*dist
[i
];
1094 if(dsize
>=ctx
->Point
.Threshold
) {
1095 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1098 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1099 dsize
/=ctx
->Point
.Threshold
;
1100 alphaf
=(dsize
*dsize
);
1102 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1103 rmax
= radius
+ 0.7071F
;
1106 cscale
= 256.0F
/ (rmax2
-rmin2
);
1108 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1109 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1110 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1111 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1112 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1114 red
= VB
->ColorPtr
->data
[i
][0];
1115 green
= VB
->ColorPtr
->data
[i
][1];
1116 blue
= VB
->ColorPtr
->data
[i
][2];
1118 switch (VB
->TexCoordPtr
[0]->size
) {
1120 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1121 VB
->TexCoordPtr
[0]->data
[i
][3]);
1122 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1123 VB
->TexCoordPtr
[0]->data
[i
][3]);
1124 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1125 VB
->TexCoordPtr
[0]->data
[i
][3]);
1128 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1129 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1130 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1133 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1134 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1138 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1143 /* should never get here */
1145 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1148 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1149 /* Multitextured! This is probably a slow enough path that
1150 there's no reason to specialize the multitexture case. */
1151 switch (VB
->TexCoordPtr
[1]->size
) {
1153 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1154 VB
->TexCoordPtr
[1]->data
[i
][3] );
1155 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1156 VB
->TexCoordPtr
[1]->data
[i
][3] );
1157 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1158 VB
->TexCoordPtr
[1]->data
[i
][3] );
1161 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1162 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1163 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1166 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1167 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1171 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1176 /* should never get here */
1178 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1182 for (y
=ymin
;y
<=ymax
;y
++) {
1183 for (x
=xmin
;x
<=xmax
;x
++) {
1184 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1185 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1186 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1188 alpha
= VB
->ColorPtr
->data
[i
][3];
1190 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1191 /* coverage is in [0,256] */
1192 alpha
= (alpha
* coverage
) >> 8;
1194 alpha
= (GLint
) (alpha
* alphaf
);
1195 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1196 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1198 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
);
1203 PB_CHECK_FLUSH(ctx
,PB
);
1208 /* Not texture mapped */
1209 for (i
=first
;i
<=last
;i
++) {
1210 if (VB
->ClipMask
[i
]==0) {
1211 GLint xmin
, ymin
, xmax
, ymax
;
1213 GLint red
, green
, blue
, alpha
;
1215 dsize
=psize
*dist
[i
];
1216 if(dsize
>=ctx
->Point
.Threshold
) {
1217 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1220 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1221 dsize
/=ctx
->Point
.Threshold
;
1222 alphaf
=(dsize
*dsize
);
1224 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1225 rmax
= radius
+ 0.7071F
;
1228 cscale
= 256.0F
/ (rmax2
-rmin2
);
1230 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1231 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1232 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1233 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1234 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1236 red
= VB
->ColorPtr
->data
[i
][0];
1237 green
= VB
->ColorPtr
->data
[i
][1];
1238 blue
= VB
->ColorPtr
->data
[i
][2];
1240 for (y
=ymin
;y
<=ymax
;y
++) {
1241 for (x
=xmin
;x
<=xmax
;x
++) {
1242 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1243 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1244 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1246 alpha
= VB
->ColorPtr
->data
[i
][3];
1248 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1249 /* coverage is in [0,256] */
1250 alpha
= (alpha
* coverage
) >> 8;
1252 alpha
= (GLint
) (alpha
* alphaf
);
1253 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
)
1258 PB_CHECK_FLUSH(ctx
,PB
);
1266 * Examine the current context to determine which point drawing function
1269 void gl_set_point_function( GLcontext
*ctx
)
1271 GLboolean rgbmode
= ctx
->Visual
->RGBAflag
;
1273 if (ctx
->RenderMode
==GL_RENDER
) {
1274 if (ctx
->NoRaster
) {
1275 ctx
->Driver
.PointsFunc
= null_points
;
1278 if (ctx
->Driver
.PointsFunc
) {
1279 /* Device driver will draw points. */
1280 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1284 if (!ctx
->Point
.Attenuated
) {
1285 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1286 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1288 else if (ctx
->Texture
.ReallyEnabled
) {
1289 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1290 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1293 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1296 else if (ctx
->Point
.Size
==1.0) {
1297 /* size=1, any raster ops */
1299 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1301 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1304 /* every other kind of point rendering */
1306 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1308 ctx
->Driver
.PointsFunc
= general_ci_points
;
1311 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1312 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1314 else if (ctx
->Texture
.ReallyEnabled
) {
1315 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1318 /* every other kind of point rendering */
1320 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1322 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1325 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1326 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1329 /* GL_SELECT mode */
1330 ctx
->Driver
.PointsFunc
= gl_select_points
;