1 /* $Id: points.c,v 1.17 2000/10/28 18:34:48 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 GLfixed
*pbfog
= PB
->fog
;
160 GLuint
*pbi
= PB
->index
;
161 GLuint pbcount
= PB
->count
;
164 win
= &VB
->Win
.data
[first
][0];
165 fog
= &VB
->FogCoordPtr
->data
[first
];
167 for (i
= first
; i
<= last
; i
++) {
168 if (VB
->ClipMask
[i
] == 0) {
169 pbx
[pbcount
] = (GLint
) win
[0];
170 pby
[pbcount
] = (GLint
) win
[1];
171 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
172 pbfog
[pbcount
] = FloatToFixed(fog
[i
]);
173 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
179 PB_CHECK_FLUSH(ctx
, PB
);
185 * RGBA points with size == 1.0
188 size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
190 struct vertex_buffer
*VB
= ctx
->VB
;
191 struct pixel_buffer
*PB
= ctx
->PB
;
194 for (i
= first
; i
<= last
; i
++) {
195 if (VB
->ClipMask
[i
] == 0) {
198 GLint red
, green
, blue
, alpha
;
200 x
= (GLint
) VB
->Win
.data
[i
][0];
201 y
= (GLint
) VB
->Win
.data
[i
][1];
202 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
204 fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
206 red
= VB
->ColorPtr
->data
[i
][0];
207 green
= VB
->ColorPtr
->data
[i
][1];
208 blue
= VB
->ColorPtr
->data
[i
][2];
209 alpha
= VB
->ColorPtr
->data
[i
][3];
211 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, fog
, red
, green
, blue
, alpha
);
214 PB_CHECK_FLUSH(ctx
, PB
);
223 general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
225 struct vertex_buffer
*VB
= ctx
->VB
;
226 struct pixel_buffer
*PB
= ctx
->PB
;
227 const GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
228 GLint radius
= isize
>> 1;
231 for (i
= first
; i
<= last
; i
++) {
232 if (VB
->ClipMask
[i
] == 0) {
233 GLint x0
, x1
, y0
, y1
;
236 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
237 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
238 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
240 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
251 x0
= (GLint
) (x
+ 1.5F
) - radius
;
253 y0
= (GLint
) (y
+ 1.5F
) - radius
;
257 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
259 for (iy
= y0
; iy
<= y1
; iy
++) {
260 for (ix
= x0
; ix
<= x1
; ix
++) {
261 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
264 PB_CHECK_FLUSH(ctx
,PB
);
271 * General RGBA points.
274 general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
276 struct vertex_buffer
*VB
= ctx
->VB
;
277 struct pixel_buffer
*PB
= ctx
->PB
;
278 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
279 GLint radius
= isize
>> 1;
282 for (i
= first
; i
<= last
; i
++) {
283 if (VB
->ClipMask
[i
] == 0) {
284 GLint x0
, x1
, y0
, y1
;
287 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
288 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
289 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
291 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
302 x0
= (GLint
) (x
+ 1.5F
) - radius
;
304 y0
= (GLint
) (y
+ 1.5F
) - radius
;
309 VB
->ColorPtr
->data
[i
][0],
310 VB
->ColorPtr
->data
[i
][1],
311 VB
->ColorPtr
->data
[i
][2],
312 VB
->ColorPtr
->data
[i
][3] );
314 for (iy
= y0
; iy
<= y1
; iy
++) {
315 for (ix
= x0
; ix
<= x1
; ix
++) {
316 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
319 PB_CHECK_FLUSH(ctx
,PB
);
328 * Textured RGBA points.
331 textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
333 struct vertex_buffer
*VB
= ctx
->VB
;
334 struct pixel_buffer
*PB
= ctx
->PB
;
337 for (i
= first
; i
<= last
; i
++) {
338 if (VB
->ClipMask
[i
] == 0) {
339 GLint x0
, x1
, y0
, y1
;
340 GLint ix
, iy
, radius
;
341 GLint red
, green
, blue
, alpha
;
344 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
345 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
346 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
347 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
349 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
365 x0
= (GLint
) (x
+ 1.5F
) - radius
;
367 y0
= (GLint
) (y
+ 1.5F
) - radius
;
371 red
= VB
->ColorPtr
->data
[i
][0];
372 green
= VB
->ColorPtr
->data
[i
][1];
373 blue
= VB
->ColorPtr
->data
[i
][2];
374 alpha
= VB
->ColorPtr
->data
[i
][3];
376 switch (VB
->TexCoordPtr
[0]->size
) {
378 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
379 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
380 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
383 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
384 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
385 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
388 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
389 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
393 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
398 /* should never get here */
400 gl_problem(ctx
, "unexpected texcoord size in textured_rgba_points()");
403 for (iy
= y0
; iy
<= y1
; iy
++) {
404 for (ix
= x0
; ix
<= x1
; ix
++) {
405 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, fog
, red
, green
, blue
, alpha
,
410 PB_CHECK_FLUSH(ctx
, PB
);
417 * Multitextured RGBA points.
420 multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
422 struct vertex_buffer
*VB
= ctx
->VB
;
423 struct pixel_buffer
*PB
= ctx
->PB
;
426 for (i
= first
; i
<= last
; i
++) {
427 if (VB
->ClipMask
[i
] == 0) {
428 const GLint red
= VB
->ColorPtr
->data
[i
][0];
429 const GLint green
= VB
->ColorPtr
->data
[i
][1];
430 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
431 const GLint alpha
= VB
->ColorPtr
->data
[i
][3];
432 const GLint sRed
= VB
->SecondaryColorPtr
->data
? VB
->SecondaryColorPtr
->data
[i
][0] : 0;
433 const GLint sGreen
= VB
->SecondaryColorPtr
->data
? VB
->SecondaryColorPtr
->data
[i
][1] : 0;
434 const GLint sBlue
= VB
->SecondaryColorPtr
->data
? VB
->SecondaryColorPtr
->data
[i
][2] : 0;
435 const GLint x
= (GLint
) VB
->Win
.data
[i
][0];
436 const GLint y
= (GLint
) VB
->Win
.data
[i
][1];
437 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
438 GLint x0
, x1
, y0
, y1
;
440 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
442 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
444 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
460 x0
= (GLint
) (x
+ 1.5F
) - radius
;
462 y0
= (GLint
) (y
+ 1.5F
) - radius
;
466 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
467 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
468 switch (VB
->TexCoordPtr
[0]->size
) {
470 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
471 VB
->TexCoordPtr
[u
]->data
[i
][3];
472 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
473 VB
->TexCoordPtr
[u
]->data
[i
][3];
474 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
475 VB
->TexCoordPtr
[u
]->data
[i
][3];
478 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
479 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
480 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
483 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
484 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
485 texcoord
[u
][2] = 0.0;
488 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
489 texcoord
[u
][1] = 0.0;
490 texcoord
[u
][2] = 0.0;
493 /* should never get here */
494 gl_problem(ctx
, "unexpected texcoord size");
499 for (iy
= y0
; iy
<= y1
; iy
++) {
500 for (ix
= x0
; ix
<= x1
; ix
++) {
501 PB_WRITE_MULTITEX_SPEC_PIXEL( PB
, ix
, iy
, z
, fog
,
502 red
, green
, blue
, alpha
,
507 PB_CHECK_FLUSH(ctx
, PB
);
514 * NOTES on aa point rasterization:
516 * Let d = distance of fragment center from vertex.
518 * fragment has 100% coverage
519 * else if d > rmax2 then
520 * fragment has 0% coverage
522 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
527 * Antialiased points with or without texture mapping.
530 antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
532 struct vertex_buffer
*VB
= ctx
->VB
;
533 struct pixel_buffer
*PB
= ctx
->PB
;
534 const GLfloat radius
= ctx
->Point
.Size
* 0.5F
;
535 const GLfloat rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
536 const GLfloat rmax
= radius
+ 0.7071F
;
537 const GLfloat rmin2
= MAX2(0.0, rmin
* rmin
);
538 const GLfloat rmax2
= rmax
* rmax
;
539 const GLfloat cscale
= 256.0F
/ (rmax2
- rmin2
);
542 if (ctx
->Texture
.ReallyEnabled
) {
543 for (i
= first
; i
<= last
; i
++) {
544 if (VB
->ClipMask
[i
] == 0) {
546 GLfloat vx
= VB
->Win
.data
[i
][0];
547 GLfloat vy
= VB
->Win
.data
[i
][1];
548 const GLint xmin
= (GLint
) (vx
- radius
);
549 const GLint xmax
= (GLint
) (vx
+ radius
);
550 const GLint ymin
= (GLint
) (vy
- radius
);
551 const GLint ymax
= (GLint
) (vy
+ radius
);
552 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
553 const GLint red
= VB
->ColorPtr
->data
[i
][0];
554 const GLint green
= VB
->ColorPtr
->data
[i
][1];
555 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
556 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
559 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
561 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
562 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
563 switch (VB
->TexCoordPtr
[0]->size
) {
565 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
566 VB
->TexCoordPtr
[u
]->data
[i
][3];
567 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
568 VB
->TexCoordPtr
[u
]->data
[i
][3];
569 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
570 VB
->TexCoordPtr
[u
]->data
[i
][3];
573 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
574 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
575 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
578 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
579 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
580 texcoord
[u
][2] = 0.0;
583 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
584 texcoord
[u
][1] = 0.0;
585 texcoord
[u
][2] = 0.0;
588 /* should never get here */
589 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
594 /* translate by a half pixel to simplify math below */
598 for (y
= ymin
; y
<= ymax
; y
++) {
599 for (x
= xmin
; x
<= xmax
; x
++) {
600 const GLfloat dx
= x
- vx
;
601 const GLfloat dy
= y
- vy
;
602 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
604 alpha
= VB
->ColorPtr
->data
[i
][3];
605 if (dist2
>= rmin2
) {
606 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
607 /* coverage is in [0,256] */
608 alpha
= (alpha
* coverage
) >> 8;
610 if (ctx
->Texture
.MultiTextureEnabled
) {
611 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, fog
,
616 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, fog
,
617 red
, green
, blue
, alpha
,
626 PB_CHECK_FLUSH(ctx
,PB
);
631 /* Not texture mapped */
632 for (i
=first
;i
<=last
;i
++) {
633 if (VB
->ClipMask
[i
]==0) {
634 const GLint xmin
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 - radius
);
635 const GLint xmax
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 + radius
);
636 const GLint ymin
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 - radius
);
637 const GLint ymax
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 + radius
);
638 const GLint red
= VB
->ColorPtr
->data
[i
][0];
639 const GLint green
= VB
->ColorPtr
->data
[i
][1];
640 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
641 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
644 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
647 printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
648 printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
650 for (y
= ymin
; y
<= ymax
; y
++) {
651 for (x
= xmin
; x
<= xmax
; x
++) {
652 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
653 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
654 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
656 GLint alpha
= VB
->ColorPtr
->data
[i
][3];
657 if (dist2
>= rmin2
) {
658 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
659 /* coverage is in [0,256] */
660 alpha
= (alpha
* coverage
) >> 8;
662 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
,
663 red
, green
, blue
, alpha
);
667 PB_CHECK_FLUSH(ctx
,PB
);
676 * Null rasterizer for measuring transformation speed.
679 null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
688 /* Definition of the functions for GL_EXT_point_parameters */
690 /* Calculates the distance attenuation formula of a vector of points in
691 * eye space coordinates
694 dist3(GLfloat
*out
, GLuint first
, GLuint last
,
695 const GLcontext
*ctx
, const GLvector4f
*v
)
697 GLuint stride
= v
->stride
;
698 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
701 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
702 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
703 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
704 dist
* (ctx
->Point
.Params
[1] +
705 dist
* ctx
->Point
.Params
[2]));
711 dist2(GLfloat
*out
, GLuint first
, GLuint last
,
712 const GLcontext
*ctx
, const GLvector4f
*v
)
714 GLuint stride
= v
->stride
;
715 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
718 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
719 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
720 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
721 dist
* (ctx
->Point
.Params
[1] +
722 dist
* ctx
->Point
.Params
[2]));
727 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
728 const GLcontext
*ctx
, const GLvector4f
*v
);
731 static dist_func eye_dist_tab
[5] = {
742 * Distance Attenuated General CI points.
745 dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
747 struct vertex_buffer
*VB
= ctx
->VB
;
748 struct pixel_buffer
*PB
= ctx
->PB
;
749 GLfloat dist
[VB_SIZE
];
750 const GLfloat psize
= ctx
->Point
.Size
;
753 ASSERT(ctx
->NeedEyeCoords
);
754 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
757 for (i
=first
;i
<=last
;i
++) {
758 if (VB
->ClipMask
[i
]==0) {
759 GLint x0
, x1
, y0
, y1
;
762 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
763 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
764 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
765 GLfloat dsize
= psize
* dist
[i
];
767 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
769 if (dsize
>= ctx
->Point
.Threshold
) {
770 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
773 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
786 x0
= (GLint
) (x
+ 1.5F
) - radius
;
788 y0
= (GLint
) (y
+ 1.5F
) - radius
;
792 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
794 for (iy
=y0
;iy
<=y1
;iy
++) {
795 for (ix
=x0
;ix
<=x1
;ix
++) {
796 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
799 PB_CHECK_FLUSH(ctx
,PB
);
805 * Distance Attenuated General RGBA points.
808 dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
810 struct vertex_buffer
*VB
= ctx
->VB
;
811 struct pixel_buffer
*PB
= ctx
->PB
;
812 GLfloat dist
[VB_SIZE
];
813 const GLfloat psize
= ctx
->Point
.Size
;
816 ASSERT (ctx
->NeedEyeCoords
);
817 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
819 for (i
=first
;i
<=last
;i
++) {
820 if (VB
->ClipMask
[i
]==0) {
821 GLint x0
, x1
, y0
, y1
;
824 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
825 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
826 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
827 GLfloat dsize
=psize
*dist
[i
];
829 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
831 if (dsize
>= ctx
->Point
.Threshold
) {
832 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
833 alpha
= VB
->ColorPtr
->data
[i
][3];
836 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
837 dsize
/= ctx
->Point
.Threshold
;
838 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
851 x0
= (GLint
) (x
+ 1.5F
) - radius
;
853 y0
= (GLint
) (y
+ 1.5F
) - radius
;
858 VB
->ColorPtr
->data
[i
][0],
859 VB
->ColorPtr
->data
[i
][1],
860 VB
->ColorPtr
->data
[i
][2],
863 for (iy
= y0
; iy
<= y1
; iy
++) {
864 for (ix
= x0
; ix
<= x1
; ix
++) {
865 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
868 PB_CHECK_FLUSH(ctx
,PB
);
874 * Distance Attenuated Textured RGBA points.
877 dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
879 struct vertex_buffer
*VB
= ctx
->VB
;
880 struct pixel_buffer
*PB
= ctx
->PB
;
881 GLfloat dist
[VB_SIZE
];
882 const GLfloat psize
= ctx
->Point
.Size
;
885 ASSERT(ctx
->NeedEyeCoords
);
886 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
888 for (i
=first
;i
<=last
;i
++) {
889 if (VB
->ClipMask
[i
]==0) {
890 const GLint x
= (GLint
) VB
->Win
.data
[i
][0];
891 const GLint y
= (GLint
) VB
->Win
.data
[i
][1];
892 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
893 const GLint red
= VB
->ColorPtr
->data
[i
][0];
894 const GLint green
= VB
->ColorPtr
->data
[i
][1];
895 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
896 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
897 GLint x0
, x1
, y0
, y1
;
898 GLint ix
, iy
, alpha
, u
;
900 GLfloat dsize
= psize
*dist
[i
];
902 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
904 /* compute point size and alpha */
905 if (dsize
>= ctx
->Point
.Threshold
) {
906 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
907 alpha
= VB
->ColorPtr
->data
[i
][3];
910 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
911 dsize
/= ctx
->Point
.Threshold
;
912 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3] * (dsize
* dsize
));
928 x0
= (GLint
) (x
+ 1.5F
) - radius
;
930 y0
= (GLint
) (y
+ 1.5F
) - radius
;
934 /* get texture coordinates */
935 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
936 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
937 switch (VB
->TexCoordPtr
[0]->size
) {
939 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
940 VB
->TexCoordPtr
[u
]->data
[i
][3];
941 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
942 VB
->TexCoordPtr
[u
]->data
[i
][3];
943 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
944 VB
->TexCoordPtr
[u
]->data
[i
][3];
947 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
948 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
949 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
952 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
953 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
954 texcoord
[u
][2] = 0.0;
957 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
958 texcoord
[u
][1] = 0.0;
959 texcoord
[u
][2] = 0.0;
962 /* should never get here */
963 gl_problem(ctx
, "unexpected texcoord size");
968 for (iy
= y0
; iy
<= y1
; iy
++) {
969 for (ix
= x0
; ix
<= x1
; ix
++) {
970 if (ctx
->Texture
.MultiTextureEnabled
) {
971 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, fog
,
972 red
, green
, blue
, alpha
,
976 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, fog
,
977 red
, green
, blue
, alpha
,
984 PB_CHECK_FLUSH(ctx
,PB
);
990 * Distance Attenuated Antialiased points with or without texture mapping.
993 dist_atten_antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
995 struct vertex_buffer
*VB
= ctx
->VB
;
996 struct pixel_buffer
*PB
= ctx
->PB
;
997 GLfloat dist
[VB_SIZE
];
998 const GLfloat psize
= ctx
->Point
.Size
;
1001 ASSERT(ctx
->NeedEyeCoords
);
1002 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1004 if (ctx
->Texture
.ReallyEnabled
) {
1005 for (i
=first
;i
<=last
;i
++) {
1006 if (VB
->ClipMask
[i
]==0) {
1007 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1008 GLint xmin
, ymin
, xmax
, ymax
;
1010 GLint red
, green
, blue
, alpha
;
1011 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
1012 GLfloat dsize
= psize
* dist
[i
];
1015 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
1017 if (dsize
>= ctx
->Point
.Threshold
) {
1018 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1022 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1023 dsize
/= ctx
->Point
.Threshold
;
1024 alphaf
= (dsize
*dsize
);
1026 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1027 rmax
= radius
+ 0.7071F
;
1028 rmin2
= MAX2(0.0, rmin
* rmin
);
1029 rmax2
= rmax
* rmax
;
1030 cscale
= 256.0F
/ (rmax2
- rmin2
);
1032 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1033 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1034 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1035 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1036 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1038 red
= VB
->ColorPtr
->data
[i
][0];
1039 green
= VB
->ColorPtr
->data
[i
][1];
1040 blue
= VB
->ColorPtr
->data
[i
][2];
1042 /* get texture coordinates */
1043 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
1044 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
1045 switch (VB
->TexCoordPtr
[0]->size
) {
1047 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
1048 VB
->TexCoordPtr
[u
]->data
[i
][3];
1049 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
1050 VB
->TexCoordPtr
[u
]->data
[i
][3];
1051 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
1052 VB
->TexCoordPtr
[u
]->data
[i
][3];
1055 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
1056 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
1057 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
1060 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
1061 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
1062 texcoord
[u
][2] = 0.0;
1065 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
1066 texcoord
[u
][1] = 0.0;
1067 texcoord
[u
][2] = 0.0;
1070 /* should never get here */
1071 gl_problem(ctx
, "unexpected texcoord size");
1076 for (y
= ymin
; y
<= ymax
; y
++) {
1077 for (x
= xmin
; x
<= xmax
; x
++) {
1078 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1079 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1080 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
1081 if (dist2
< rmax2
) {
1082 alpha
= VB
->ColorPtr
->data
[i
][3];
1083 if (dist2
>= rmin2
) {
1084 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1085 /* coverage is in [0,256] */
1086 alpha
= (alpha
* coverage
) >> 8;
1088 alpha
= (GLint
) (alpha
* alphaf
);
1089 if (ctx
->Texture
.MultiTextureEnabled
) {
1090 PB_WRITE_MULTITEX_PIXEL( PB
, x
, y
, z
, fog
,
1091 red
, green
, blue
, alpha
,
1095 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, fog
,
1096 red
, green
, blue
, alpha
,
1104 PB_CHECK_FLUSH(ctx
,PB
);
1109 /* Not texture mapped */
1110 for (i
= first
; i
<= last
; i
++) {
1111 if (VB
->ClipMask
[i
] == 0) {
1112 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1113 GLint xmin
, ymin
, xmax
, ymax
;
1116 GLint red
, green
, blue
, alpha
;
1117 GLfloat dsize
= psize
* dist
[i
];
1119 if (dsize
>= ctx
->Point
.Threshold
) {
1120 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1124 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1125 dsize
/= ctx
->Point
.Threshold
;
1126 alphaf
= dsize
* dsize
;
1128 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1129 rmax
= radius
+ 0.7071F
;
1130 rmin2
= MAX2(0.0, rmin
* rmin
);
1131 rmax2
= rmax
* rmax
;
1132 cscale
= 256.0F
/ (rmax2
- rmin2
);
1134 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1135 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1136 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1137 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1138 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1140 fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
1142 red
= VB
->ColorPtr
->data
[i
][0];
1143 green
= VB
->ColorPtr
->data
[i
][1];
1144 blue
= VB
->ColorPtr
->data
[i
][2];
1146 for (y
= ymin
; y
<= ymax
; y
++) {
1147 for (x
= xmin
; x
<= xmax
; x
++) {
1148 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1149 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1150 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
1151 if (dist2
< rmax2
) {
1152 alpha
= VB
->ColorPtr
->data
[i
][3];
1153 if (dist2
>= rmin2
) {
1154 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1155 /* coverage is in [0,256] */
1156 alpha
= (alpha
* coverage
) >> 8;
1158 alpha
= (GLint
) (alpha
* alphaf
);
1159 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
,
1160 red
, green
, blue
, alpha
);
1164 PB_CHECK_FLUSH(ctx
,PB
);
1173 _mesa_print_points_function(GLcontext
*ctx
)
1175 printf("Point Func == ");
1176 if (ctx
->Driver
.PointsFunc
== size1_ci_points
)
1177 printf("size1_ci_points\n");
1178 else if (ctx
->Driver
.PointsFunc
== size1_rgba_points
)
1179 printf("size1_rgba_points\n");
1180 else if (ctx
->Driver
.PointsFunc
== general_ci_points
)
1181 printf("general_ci_points\n");
1182 else if (ctx
->Driver
.PointsFunc
== general_rgba_points
)
1183 printf("general_rgba_points\n");
1184 else if (ctx
->Driver
.PointsFunc
== textured_rgba_points
)
1185 printf("textured_rgba_points\n");
1186 else if (ctx
->Driver
.PointsFunc
== multitextured_rgba_points
)
1187 printf("multitextured_rgba_points\n");
1188 else if (ctx
->Driver
.PointsFunc
== antialiased_rgba_points
)
1189 printf("antialiased_rgba_points\n");
1190 else if (ctx
->Driver
.PointsFunc
== null_points
)
1191 printf("null_points\n");
1192 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_ci_points
)
1193 printf("dist_atten_general_ci_points\n");
1194 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_rgba_points
)
1195 printf("dist_atten_general_rgba_points\n");
1196 else if (ctx
->Driver
.PointsFunc
== dist_atten_textured_rgba_points
)
1197 printf("dist_atten_textured_rgba_points\n");
1198 else if (ctx
->Driver
.PointsFunc
== dist_atten_antialiased_rgba_points
)
1199 printf("dist_atten_antialiased_rgba_points\n");
1200 else if (!ctx
->Driver
.PointsFunc
)
1203 printf("Driver func %p\n", ctx
->Driver
.PointsFunc
);
1209 * Examine the current context to determine which point drawing function
1212 void gl_set_point_function( GLcontext
*ctx
)
1214 GLboolean rgbmode
= ctx
->Visual
.RGBAflag
;
1216 if (ctx
->RenderMode
==GL_RENDER
) {
1217 if (ctx
->NoRaster
) {
1218 ctx
->Driver
.PointsFunc
= null_points
;
1221 if (ctx
->Driver
.PointsFunc
) {
1222 /* Device driver will draw points. */
1223 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1227 if (!ctx
->Point
.Attenuated
) {
1228 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1229 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1231 else if (ctx
->Texture
.ReallyEnabled
) {
1232 if (ctx
->Texture
.MultiTextureEnabled
||
1233 ctx
->Light
.Model
.ColorControl
==GL_SEPARATE_SPECULAR_COLOR
||
1234 ctx
->Fog
.ColorSumEnabled
) {
1235 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1238 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1241 else if (ctx
->Point
.Size
==1.0) {
1242 /* size=1, any raster ops */
1244 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1246 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1249 /* every other kind of point rendering */
1251 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1253 ctx
->Driver
.PointsFunc
= general_ci_points
;
1256 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1257 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1259 else if (ctx
->Texture
.ReallyEnabled
) {
1260 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1263 /* every other kind of point rendering */
1265 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1267 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1270 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1271 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1274 /* GL_SELECT mode */
1275 ctx
->Driver
.PointsFunc
= gl_select_points
;
1278 /*_mesa_print_points_function(ctx);*/