1 /* $Id: points.c,v 1.15 2000/10/20 19:54:49 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 const GLint red
= VB
->ColorPtr
->data
[i
][0];
416 const GLint green
= VB
->ColorPtr
->data
[i
][1];
417 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
418 const GLint alpha
= VB
->ColorPtr
->data
[i
][3];
419 const GLint sRed
= VB
->Specular
? VB
->Specular
[i
][0] : 0;
420 const GLint sGreen
= VB
->Specular
? VB
->Specular
[i
][1] : 0;
421 const GLint sBlue
= VB
->Specular
? VB
->Specular
[i
][2] : 0;
422 const GLint x
= (GLint
) VB
->Win
.data
[i
][0];
423 const GLint y
= (GLint
) VB
->Win
.data
[i
][1];
424 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
425 GLint x0
, x1
, y0
, y1
;
427 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
429 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
445 x0
= (GLint
) (x
+ 1.5F
) - radius
;
447 y0
= (GLint
) (y
+ 1.5F
) - radius
;
451 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
452 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
453 switch (VB
->TexCoordPtr
[0]->size
) {
455 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
456 VB
->TexCoordPtr
[u
]->data
[i
][3];
457 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
458 VB
->TexCoordPtr
[u
]->data
[i
][3];
459 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
460 VB
->TexCoordPtr
[u
]->data
[i
][3];
463 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
464 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
465 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
468 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
469 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
470 texcoord
[u
][2] = 0.0;
473 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
474 texcoord
[u
][1] = 0.0;
475 texcoord
[u
][2] = 0.0;
478 /* should never get here */
479 gl_problem(ctx
, "unexpected texcoord size");
484 for (iy
= y0
; iy
<= y1
; iy
++) {
485 for (ix
= x0
; ix
<= x1
; ix
++) {
486 PB_WRITE_MULTITEX_SPEC_PIXEL( PB
, ix
, iy
, z
,
487 red
, green
, blue
, alpha
,
492 PB_CHECK_FLUSH(ctx
, PB
);
499 * NOTES on aa point rasterization:
501 * Let d = distance of fragment center from vertex.
503 * fragment has 100% coverage
504 * else if d > rmax2 then
505 * fragment has 0% coverage
507 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
512 * Antialiased points with or without texture mapping.
515 antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
517 struct vertex_buffer
*VB
= ctx
->VB
;
518 struct pixel_buffer
*PB
= ctx
->PB
;
519 const GLfloat radius
= ctx
->Point
.Size
* 0.5F
;
520 const GLfloat rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
521 const GLfloat rmax
= radius
+ 0.7071F
;
522 const GLfloat rmin2
= MAX2(0.0, rmin
* rmin
);
523 const GLfloat rmax2
= rmax
* rmax
;
524 const GLfloat cscale
= 256.0F
/ (rmax2
- rmin2
);
527 if (ctx
->Texture
.ReallyEnabled
) {
528 for (i
= first
; i
<= last
; i
++) {
529 if (VB
->ClipMask
[i
] == 0) {
531 GLfloat vx
= VB
->Win
.data
[i
][0];
532 GLfloat vy
= VB
->Win
.data
[i
][1];
533 const GLint xmin
= (GLint
) (vx
- radius
);
534 const GLint xmax
= (GLint
) (vx
+ radius
);
535 const GLint ymin
= (GLint
) (vy
- radius
);
536 const GLint ymax
= (GLint
) (vy
+ radius
);
537 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
538 const GLint red
= VB
->ColorPtr
->data
[i
][0];
539 const GLint green
= VB
->ColorPtr
->data
[i
][1];
540 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
541 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
544 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
545 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
546 switch (VB
->TexCoordPtr
[0]->size
) {
548 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
549 VB
->TexCoordPtr
[u
]->data
[i
][3];
550 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
551 VB
->TexCoordPtr
[u
]->data
[i
][3];
552 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
553 VB
->TexCoordPtr
[u
]->data
[i
][3];
556 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
557 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
558 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
561 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
562 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
563 texcoord
[u
][2] = 0.0;
566 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
567 texcoord
[u
][1] = 0.0;
568 texcoord
[u
][2] = 0.0;
571 /* should never get here */
572 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
577 /* translate by a half pixel to simplify math below */
581 for (y
= ymin
; y
<= ymax
; y
++) {
582 for (x
= xmin
; x
<= xmax
; x
++) {
583 const GLfloat dx
= x
- vx
;
584 const GLfloat dy
= y
- vy
;
585 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
587 alpha
= VB
->ColorPtr
->data
[i
][3];
588 if (dist2
>= rmin2
) {
589 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
590 /* coverage is in [0,256] */
591 alpha
= (alpha
* coverage
) >> 8;
593 if (ctx
->Texture
.MultiTextureEnabled
) {
594 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
598 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
,
607 PB_CHECK_FLUSH(ctx
,PB
);
612 /* Not texture mapped */
613 for (i
=first
;i
<=last
;i
++) {
614 if (VB
->ClipMask
[i
]==0) {
615 const GLint xmin
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 - radius
);
616 const GLint xmax
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 + radius
);
617 const GLint ymin
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 - radius
);
618 const GLint ymax
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 + radius
);
619 const GLint red
= VB
->ColorPtr
->data
[i
][0];
620 const GLint green
= VB
->ColorPtr
->data
[i
][1];
621 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
622 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
626 printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
627 printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
629 for (y
= ymin
; y
<= ymax
; y
++) {
630 for (x
= xmin
; x
<= xmax
; x
++) {
631 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
632 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
633 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
635 GLint alpha
= VB
->ColorPtr
->data
[i
][3];
636 if (dist2
>= rmin2
) {
637 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
638 /* coverage is in [0,256] */
639 alpha
= (alpha
* coverage
) >> 8;
641 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, red
, green
, blue
, alpha
);
645 PB_CHECK_FLUSH(ctx
,PB
);
654 * Null rasterizer for measuring transformation speed.
657 null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
666 /* Definition of the functions for GL_EXT_point_parameters */
668 /* Calculates the distance attenuation formula of a vector of points in
669 * eye space coordinates
672 dist3(GLfloat
*out
, GLuint first
, GLuint last
,
673 const GLcontext
*ctx
, const GLvector4f
*v
)
675 GLuint stride
= v
->stride
;
676 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
679 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
680 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
681 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
682 dist
* (ctx
->Point
.Params
[1] +
683 dist
* ctx
->Point
.Params
[2]));
689 dist2(GLfloat
*out
, GLuint first
, GLuint last
,
690 const GLcontext
*ctx
, const GLvector4f
*v
)
692 GLuint stride
= v
->stride
;
693 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
696 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
697 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
698 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
699 dist
* (ctx
->Point
.Params
[1] +
700 dist
* ctx
->Point
.Params
[2]));
705 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
706 const GLcontext
*ctx
, const GLvector4f
*v
);
709 static dist_func eye_dist_tab
[5] = {
719 clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
720 const GLcontext
*ctx
, GLvector4f
*clip
)
722 /* this is never called */
723 gl_problem(NULL
, "clip_dist() called - dead code!\n");
733 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
734 const GLuint stride
= clip_vec
->stride
;
736 for (i
= first
; i
<= last
; i
++ )
738 GLfloat dist
= win
[i
][2];
739 out
[i
] = 1/(ctx
->Point
.Params
[0]+
740 dist
* (ctx
->Point
.Params
[1] +
741 dist
* ctx
->Point
.Params
[2]));
749 * Distance Attenuated General CI points.
752 dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
754 struct vertex_buffer
*VB
= ctx
->VB
;
755 struct pixel_buffer
*PB
= ctx
->PB
;
756 GLfloat dist
[VB_SIZE
];
757 const GLfloat psize
= ctx
->Point
.Size
;
760 if (ctx
->NeedEyeCoords
)
761 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
763 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
765 for (i
=first
;i
<=last
;i
++) {
766 if (VB
->ClipMask
[i
]==0) {
767 GLint x0
, x1
, y0
, y1
;
770 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
771 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
772 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
773 GLfloat dsize
= psize
* dist
[i
];
775 if (dsize
>= ctx
->Point
.Threshold
) {
776 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
779 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
792 x0
= (GLint
) (x
+ 1.5F
) - radius
;
794 y0
= (GLint
) (y
+ 1.5F
) - radius
;
798 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
800 for (iy
=y0
;iy
<=y1
;iy
++) {
801 for (ix
=x0
;ix
<=x1
;ix
++) {
802 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
805 PB_CHECK_FLUSH(ctx
,PB
);
811 * Distance Attenuated General RGBA points.
814 dist_atten_general_rgba_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
];
838 if (dsize
>= ctx
->Point
.Threshold
) {
839 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
840 alpha
= VB
->ColorPtr
->data
[i
][3];
843 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
844 dsize
/= ctx
->Point
.Threshold
;
845 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
858 x0
= (GLint
) (x
+ 1.5F
) - radius
;
860 y0
= (GLint
) (y
+ 1.5F
) - radius
;
865 VB
->ColorPtr
->data
[i
][0],
866 VB
->ColorPtr
->data
[i
][1],
867 VB
->ColorPtr
->data
[i
][2],
870 for (iy
= y0
; iy
<= y1
; iy
++) {
871 for (ix
= x0
; ix
<= x1
; ix
++) {
872 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
875 PB_CHECK_FLUSH(ctx
,PB
);
881 * Distance Attenuated Textured RGBA points.
884 dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
886 struct vertex_buffer
*VB
= ctx
->VB
;
887 struct pixel_buffer
*PB
= ctx
->PB
;
888 GLfloat dist
[VB_SIZE
];
889 const GLfloat psize
= ctx
->Point
.Size
;
892 if (ctx
->NeedEyeCoords
)
893 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
895 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
897 for (i
=first
;i
<=last
;i
++) {
898 if (VB
->ClipMask
[i
]==0) {
899 const GLint x
= (GLint
) VB
->Win
.data
[i
][0];
900 const GLint y
= (GLint
) VB
->Win
.data
[i
][1];
901 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
902 const GLint red
= VB
->ColorPtr
->data
[i
][0];
903 const GLint green
= VB
->ColorPtr
->data
[i
][1];
904 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
905 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
906 GLint x0
, x1
, y0
, y1
;
907 GLint ix
, iy
, alpha
, u
;
909 GLfloat dsize
= psize
*dist
[i
];
911 /* compute point size and alpha */
912 if (dsize
>= ctx
->Point
.Threshold
) {
913 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
914 alpha
= VB
->ColorPtr
->data
[i
][3];
917 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
918 dsize
/= ctx
->Point
.Threshold
;
919 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3] * (dsize
* dsize
));
935 x0
= (GLint
) (x
+ 1.5F
) - radius
;
937 y0
= (GLint
) (y
+ 1.5F
) - radius
;
941 /* get texture coordinates */
942 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
943 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
944 switch (VB
->TexCoordPtr
[0]->size
) {
946 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
947 VB
->TexCoordPtr
[u
]->data
[i
][3];
948 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
949 VB
->TexCoordPtr
[u
]->data
[i
][3];
950 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
951 VB
->TexCoordPtr
[u
]->data
[i
][3];
954 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
955 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
956 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
959 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
960 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
961 texcoord
[u
][2] = 0.0;
964 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
965 texcoord
[u
][1] = 0.0;
966 texcoord
[u
][2] = 0.0;
969 /* should never get here */
970 gl_problem(ctx
, "unexpected texcoord size");
975 for (iy
= y0
; iy
<= y1
; iy
++) {
976 for (ix
= x0
; ix
<= x1
; ix
++) {
977 if (ctx
->Texture
.MultiTextureEnabled
) {
978 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
,
979 red
, green
, blue
, alpha
,
983 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
,
990 PB_CHECK_FLUSH(ctx
,PB
);
996 * Distance Attenuated Antialiased points with or without texture mapping.
999 dist_atten_antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
1001 struct vertex_buffer
*VB
= ctx
->VB
;
1002 struct pixel_buffer
*PB
= ctx
->PB
;
1003 GLfloat dist
[VB_SIZE
];
1004 const GLfloat psize
= ctx
->Point
.Size
;
1007 if (ctx
->NeedEyeCoords
)
1008 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1010 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1012 if (ctx
->Texture
.ReallyEnabled
) {
1013 for (i
=first
;i
<=last
;i
++) {
1014 if (VB
->ClipMask
[i
]==0) {
1015 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1016 GLint xmin
, ymin
, xmax
, ymax
;
1018 GLint red
, green
, blue
, alpha
;
1019 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
1020 GLfloat dsize
= psize
* dist
[i
];
1023 if (dsize
>= ctx
->Point
.Threshold
) {
1024 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1028 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1029 dsize
/= ctx
->Point
.Threshold
;
1030 alphaf
= (dsize
*dsize
);
1032 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1033 rmax
= radius
+ 0.7071F
;
1034 rmin2
= MAX2(0.0, rmin
* rmin
);
1035 rmax2
= rmax
* rmax
;
1036 cscale
= 256.0F
/ (rmax2
- rmin2
);
1038 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1039 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1040 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1041 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1042 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1044 red
= VB
->ColorPtr
->data
[i
][0];
1045 green
= VB
->ColorPtr
->data
[i
][1];
1046 blue
= VB
->ColorPtr
->data
[i
][2];
1048 /* get texture coordinates */
1049 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
1050 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
1051 switch (VB
->TexCoordPtr
[0]->size
) {
1053 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
1054 VB
->TexCoordPtr
[u
]->data
[i
][3];
1055 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
1056 VB
->TexCoordPtr
[u
]->data
[i
][3];
1057 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
1058 VB
->TexCoordPtr
[u
]->data
[i
][3];
1061 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
1062 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
1063 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
1066 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
1067 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
1068 texcoord
[u
][2] = 0.0;
1071 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
1072 texcoord
[u
][1] = 0.0;
1073 texcoord
[u
][2] = 0.0;
1076 /* should never get here */
1077 gl_problem(ctx
, "unexpected texcoord size");
1082 for (y
= ymin
; y
<= ymax
; y
++) {
1083 for (x
= xmin
; x
<= xmax
; x
++) {
1084 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1085 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1086 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
1087 if (dist2
< rmax2
) {
1088 alpha
= VB
->ColorPtr
->data
[i
][3];
1089 if (dist2
>= rmin2
) {
1090 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1091 /* coverage is in [0,256] */
1092 alpha
= (alpha
* coverage
) >> 8;
1094 alpha
= (GLint
) (alpha
* alphaf
);
1095 if (ctx
->Texture
.MultiTextureEnabled
) {
1096 PB_WRITE_MULTITEX_PIXEL( PB
, x
, y
, z
,
1097 red
, green
, blue
, alpha
,
1101 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
,
1109 PB_CHECK_FLUSH(ctx
,PB
);
1114 /* Not texture mapped */
1115 for (i
= first
; i
<= last
; i
++) {
1116 if (VB
->ClipMask
[i
] == 0) {
1117 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1118 GLint xmin
, ymin
, xmax
, ymax
;
1120 GLint red
, green
, blue
, alpha
;
1121 GLfloat dsize
= psize
* dist
[i
];
1123 if (dsize
>= ctx
->Point
.Threshold
) {
1124 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1128 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1129 dsize
/= ctx
->Point
.Threshold
;
1130 alphaf
= dsize
* dsize
;
1132 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1133 rmax
= radius
+ 0.7071F
;
1134 rmin2
= MAX2(0.0, rmin
* rmin
);
1135 rmax2
= rmax
* rmax
;
1136 cscale
= 256.0F
/ (rmax2
- rmin2
);
1138 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1139 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1140 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1141 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1142 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1144 red
= VB
->ColorPtr
->data
[i
][0];
1145 green
= VB
->ColorPtr
->data
[i
][1];
1146 blue
= VB
->ColorPtr
->data
[i
][2];
1148 for (y
= ymin
; y
<= ymax
; y
++) {
1149 for (x
= xmin
; x
<= xmax
; x
++) {
1150 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1151 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1152 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
1153 if (dist2
< rmax2
) {
1154 alpha
= VB
->ColorPtr
->data
[i
][3];
1155 if (dist2
>= rmin2
) {
1156 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1157 /* coverage is in [0,256] */
1158 alpha
= (alpha
* coverage
) >> 8;
1160 alpha
= (GLint
) (alpha
* alphaf
);
1161 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, red
, green
, blue
, alpha
);
1165 PB_CHECK_FLUSH(ctx
,PB
);
1174 _mesa_print_points_function(GLcontext
*ctx
)
1176 printf("Point Func == ");
1177 if (ctx
->Driver
.PointsFunc
== size1_ci_points
)
1178 printf("size1_ci_points\n");
1179 else if (ctx
->Driver
.PointsFunc
== size1_rgba_points
)
1180 printf("size1_rgba_points\n");
1181 else if (ctx
->Driver
.PointsFunc
== general_ci_points
)
1182 printf("general_ci_points\n");
1183 else if (ctx
->Driver
.PointsFunc
== general_rgba_points
)
1184 printf("general_rgba_points\n");
1185 else if (ctx
->Driver
.PointsFunc
== textured_rgba_points
)
1186 printf("textured_rgba_points\n");
1187 else if (ctx
->Driver
.PointsFunc
== multitextured_rgba_points
)
1188 printf("multitextured_rgba_points\n");
1189 else if (ctx
->Driver
.PointsFunc
== antialiased_rgba_points
)
1190 printf("antialiased_rgba_points\n");
1191 else if (ctx
->Driver
.PointsFunc
== null_points
)
1192 printf("null_points\n");
1193 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_ci_points
)
1194 printf("dist_atten_general_ci_points\n");
1195 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_rgba_points
)
1196 printf("dist_atten_general_rgba_points\n");
1197 else if (ctx
->Driver
.PointsFunc
== dist_atten_textured_rgba_points
)
1198 printf("dist_atten_textured_rgba_points\n");
1199 else if (ctx
->Driver
.PointsFunc
== dist_atten_antialiased_rgba_points
)
1200 printf("dist_atten_antialiased_rgba_points\n");
1201 else if (!ctx
->Driver
.PointsFunc
)
1204 printf("Driver func %p\n", ctx
->Driver
.PointsFunc
);
1210 * Examine the current context to determine which point drawing function
1213 void gl_set_point_function( GLcontext
*ctx
)
1215 GLboolean rgbmode
= ctx
->Visual
.RGBAflag
;
1217 if (ctx
->RenderMode
==GL_RENDER
) {
1218 if (ctx
->NoRaster
) {
1219 ctx
->Driver
.PointsFunc
= null_points
;
1222 if (ctx
->Driver
.PointsFunc
) {
1223 /* Device driver will draw points. */
1224 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1228 if (!ctx
->Point
.Attenuated
) {
1229 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1230 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1232 else if (ctx
->Texture
.ReallyEnabled
) {
1233 if (ctx
->Texture
.MultiTextureEnabled
||
1234 ctx
->Light
.Model
.ColorControl
==GL_SEPARATE_SPECULAR_COLOR
) {
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);*/