1 /* $Id: s_points.c,v 1.1 2000/10/31 18:00:04 keithw 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.
40 /**********************************************************************/
41 /***** Rasterization *****/
42 /**********************************************************************/
46 * There are 3 pairs (RGBA, CI) of point rendering functions:
47 * 1. simple: size=1 and no special rasterization functions (fastest)
48 * 2. size1: size=1 and any rasterization functions
49 * 3. general: any size and rasterization functions (slowest)
51 * All point rendering functions take the same two arguments: first and
52 * last which specify that the points specified by VB[first] through
53 * VB[last] are to be rendered.
61 * CI points with size == 1.0
64 size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
66 struct vertex_buffer
*VB
= ctx
->VB
;
67 struct pixel_buffer
*PB
= ctx
->PB
;
69 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
71 GLfixed
*pbfog
= PB
->fog
;
72 GLuint
*pbi
= PB
->index
;
73 GLuint pbcount
= PB
->count
;
76 win
= &VB
->Win
.data
[first
][0];
77 fog
= &VB
->FogCoordPtr
->data
[first
];
79 for (i
= first
; i
<= last
; i
++) {
80 if (VB
->ClipMask
[i
] == 0) {
81 pbx
[pbcount
] = (GLint
) win
[0];
82 pby
[pbcount
] = (GLint
) win
[1];
83 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
84 pbfog
[pbcount
] = FloatToFixed(fog
[i
]);
85 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
91 PB_CHECK_FLUSH(ctx
, PB
);
97 * RGBA points with size == 1.0
100 size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
102 struct vertex_buffer
*VB
= ctx
->VB
;
103 struct pixel_buffer
*PB
= ctx
->PB
;
106 for (i
= first
; i
<= last
; i
++) {
107 if (VB
->ClipMask
[i
] == 0) {
110 GLint red
, green
, blue
, alpha
;
112 x
= (GLint
) VB
->Win
.data
[i
][0];
113 y
= (GLint
) VB
->Win
.data
[i
][1];
114 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
116 fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
118 red
= VB
->ColorPtr
->data
[i
][0];
119 green
= VB
->ColorPtr
->data
[i
][1];
120 blue
= VB
->ColorPtr
->data
[i
][2];
121 alpha
= VB
->ColorPtr
->data
[i
][3];
123 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, fog
, red
, green
, blue
, alpha
);
126 PB_CHECK_FLUSH(ctx
, PB
);
135 general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
137 struct vertex_buffer
*VB
= ctx
->VB
;
138 struct pixel_buffer
*PB
= ctx
->PB
;
139 const GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
140 GLint radius
= isize
>> 1;
143 for (i
= first
; i
<= last
; i
++) {
144 if (VB
->ClipMask
[i
] == 0) {
145 GLint x0
, x1
, y0
, y1
;
148 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
149 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
150 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
152 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
163 x0
= (GLint
) (x
+ 1.5F
) - radius
;
165 y0
= (GLint
) (y
+ 1.5F
) - radius
;
169 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
171 for (iy
= y0
; iy
<= y1
; iy
++) {
172 for (ix
= x0
; ix
<= x1
; ix
++) {
173 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
176 PB_CHECK_FLUSH(ctx
,PB
);
183 * General RGBA points.
186 general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
188 struct vertex_buffer
*VB
= ctx
->VB
;
189 struct pixel_buffer
*PB
= ctx
->PB
;
190 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
191 GLint radius
= isize
>> 1;
194 for (i
= first
; i
<= last
; i
++) {
195 if (VB
->ClipMask
[i
] == 0) {
196 GLint x0
, x1
, y0
, y1
;
199 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
200 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
201 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
203 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
214 x0
= (GLint
) (x
+ 1.5F
) - radius
;
216 y0
= (GLint
) (y
+ 1.5F
) - radius
;
221 VB
->ColorPtr
->data
[i
][0],
222 VB
->ColorPtr
->data
[i
][1],
223 VB
->ColorPtr
->data
[i
][2],
224 VB
->ColorPtr
->data
[i
][3] );
226 for (iy
= y0
; iy
<= y1
; iy
++) {
227 for (ix
= x0
; ix
<= x1
; ix
++) {
228 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
231 PB_CHECK_FLUSH(ctx
,PB
);
240 * Textured RGBA points.
243 textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
245 struct vertex_buffer
*VB
= ctx
->VB
;
246 struct pixel_buffer
*PB
= ctx
->PB
;
249 for (i
= first
; i
<= last
; i
++) {
250 if (VB
->ClipMask
[i
] == 0) {
251 GLint x0
, x1
, y0
, y1
;
252 GLint ix
, iy
, radius
;
253 GLint red
, green
, blue
, alpha
;
256 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
257 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
258 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
259 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
261 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
277 x0
= (GLint
) (x
+ 1.5F
) - radius
;
279 y0
= (GLint
) (y
+ 1.5F
) - radius
;
283 red
= VB
->ColorPtr
->data
[i
][0];
284 green
= VB
->ColorPtr
->data
[i
][1];
285 blue
= VB
->ColorPtr
->data
[i
][2];
286 alpha
= VB
->ColorPtr
->data
[i
][3];
288 switch (VB
->TexCoordPtr
[0]->size
) {
290 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
291 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
292 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
295 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
296 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
297 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
300 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
301 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
305 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
310 /* should never get here */
312 gl_problem(ctx
, "unexpected texcoord size in textured_rgba_points()");
315 for (iy
= y0
; iy
<= y1
; iy
++) {
316 for (ix
= x0
; ix
<= x1
; ix
++) {
317 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, fog
, red
, green
, blue
, alpha
,
322 PB_CHECK_FLUSH(ctx
, PB
);
329 * Multitextured RGBA points.
332 multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
334 struct vertex_buffer
*VB
= ctx
->VB
;
335 struct pixel_buffer
*PB
= ctx
->PB
;
338 for (i
= first
; i
<= last
; i
++) {
339 if (VB
->ClipMask
[i
] == 0) {
340 const GLint red
= VB
->ColorPtr
->data
[i
][0];
341 const GLint green
= VB
->ColorPtr
->data
[i
][1];
342 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
343 const GLint alpha
= VB
->ColorPtr
->data
[i
][3];
344 const GLint sRed
= VB
->SecondaryColorPtr
->data
? VB
->SecondaryColorPtr
->data
[i
][0] : 0;
345 const GLint sGreen
= VB
->SecondaryColorPtr
->data
? VB
->SecondaryColorPtr
->data
[i
][1] : 0;
346 const GLint sBlue
= VB
->SecondaryColorPtr
->data
? VB
->SecondaryColorPtr
->data
[i
][2] : 0;
347 const GLint x
= (GLint
) VB
->Win
.data
[i
][0];
348 const GLint y
= (GLint
) VB
->Win
.data
[i
][1];
349 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
350 GLint x0
, x1
, y0
, y1
;
352 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
354 GLint isize
= (GLint
) (ctx
->Point
.Size
+ 0.5F
);
356 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
372 x0
= (GLint
) (x
+ 1.5F
) - radius
;
374 y0
= (GLint
) (y
+ 1.5F
) - radius
;
378 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
379 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
380 switch (VB
->TexCoordPtr
[0]->size
) {
382 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
383 VB
->TexCoordPtr
[u
]->data
[i
][3];
384 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
385 VB
->TexCoordPtr
[u
]->data
[i
][3];
386 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
387 VB
->TexCoordPtr
[u
]->data
[i
][3];
390 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
391 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
392 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
395 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
396 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
397 texcoord
[u
][2] = 0.0;
400 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
401 texcoord
[u
][1] = 0.0;
402 texcoord
[u
][2] = 0.0;
405 /* should never get here */
406 gl_problem(ctx
, "unexpected texcoord size");
411 for (iy
= y0
; iy
<= y1
; iy
++) {
412 for (ix
= x0
; ix
<= x1
; ix
++) {
413 PB_WRITE_MULTITEX_SPEC_PIXEL( PB
, ix
, iy
, z
, fog
,
414 red
, green
, blue
, alpha
,
419 PB_CHECK_FLUSH(ctx
, PB
);
426 * NOTES on aa point rasterization:
428 * Let d = distance of fragment center from vertex.
430 * fragment has 100% coverage
431 * else if d > rmax2 then
432 * fragment has 0% coverage
434 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
439 * Antialiased points with or without texture mapping.
442 antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
444 struct vertex_buffer
*VB
= ctx
->VB
;
445 struct pixel_buffer
*PB
= ctx
->PB
;
446 const GLfloat radius
= ctx
->Point
.Size
* 0.5F
;
447 const GLfloat rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
448 const GLfloat rmax
= radius
+ 0.7071F
;
449 const GLfloat rmin2
= MAX2(0.0, rmin
* rmin
);
450 const GLfloat rmax2
= rmax
* rmax
;
451 const GLfloat cscale
= 256.0F
/ (rmax2
- rmin2
);
454 if (ctx
->Texture
.ReallyEnabled
) {
455 for (i
= first
; i
<= last
; i
++) {
456 if (VB
->ClipMask
[i
] == 0) {
458 GLfloat vx
= VB
->Win
.data
[i
][0];
459 GLfloat vy
= VB
->Win
.data
[i
][1];
460 const GLint xmin
= (GLint
) (vx
- radius
);
461 const GLint xmax
= (GLint
) (vx
+ radius
);
462 const GLint ymin
= (GLint
) (vy
- radius
);
463 const GLint ymax
= (GLint
) (vy
+ radius
);
464 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
465 const GLint red
= VB
->ColorPtr
->data
[i
][0];
466 const GLint green
= VB
->ColorPtr
->data
[i
][1];
467 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
468 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
471 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
473 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
474 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
475 switch (VB
->TexCoordPtr
[0]->size
) {
477 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
478 VB
->TexCoordPtr
[u
]->data
[i
][3];
479 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
480 VB
->TexCoordPtr
[u
]->data
[i
][3];
481 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
482 VB
->TexCoordPtr
[u
]->data
[i
][3];
485 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
486 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
487 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
490 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
491 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
492 texcoord
[u
][2] = 0.0;
495 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
496 texcoord
[u
][1] = 0.0;
497 texcoord
[u
][2] = 0.0;
500 /* should never get here */
501 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
506 /* translate by a half pixel to simplify math below */
510 for (y
= ymin
; y
<= ymax
; y
++) {
511 for (x
= xmin
; x
<= xmax
; x
++) {
512 const GLfloat dx
= x
- vx
;
513 const GLfloat dy
= y
- vy
;
514 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
516 alpha
= VB
->ColorPtr
->data
[i
][3];
517 if (dist2
>= rmin2
) {
518 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
519 /* coverage is in [0,256] */
520 alpha
= (alpha
* coverage
) >> 8;
522 if (ctx
->Texture
.MultiTextureEnabled
) {
523 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, fog
,
528 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, fog
,
529 red
, green
, blue
, alpha
,
538 PB_CHECK_FLUSH(ctx
,PB
);
543 /* Not texture mapped */
544 for (i
=first
;i
<=last
;i
++) {
545 if (VB
->ClipMask
[i
]==0) {
546 const GLint xmin
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 - radius
);
547 const GLint xmax
= (GLint
) (VB
->Win
.data
[i
][0] - 0.0 + radius
);
548 const GLint ymin
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 - radius
);
549 const GLint ymax
= (GLint
) (VB
->Win
.data
[i
][1] - 0.0 + radius
);
550 const GLint red
= VB
->ColorPtr
->data
[i
][0];
551 const GLint green
= VB
->ColorPtr
->data
[i
][1];
552 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
553 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
556 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
559 printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
560 printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
562 for (y
= ymin
; y
<= ymax
; y
++) {
563 for (x
= xmin
; x
<= xmax
; x
++) {
564 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
565 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
566 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
568 GLint alpha
= VB
->ColorPtr
->data
[i
][3];
569 if (dist2
>= rmin2
) {
570 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
571 /* coverage is in [0,256] */
572 alpha
= (alpha
* coverage
) >> 8;
574 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
,
575 red
, green
, blue
, alpha
);
579 PB_CHECK_FLUSH(ctx
,PB
);
588 * Null rasterizer for measuring transformation speed.
591 null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
600 /* Definition of the functions for GL_EXT_point_parameters */
602 /* Calculates the distance attenuation formula of a vector of points in
603 * eye space coordinates
606 dist3(GLfloat
*out
, GLuint first
, GLuint last
,
607 const GLcontext
*ctx
, const GLvector4f
*v
)
609 GLuint stride
= v
->stride
;
610 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
613 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
614 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
615 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
616 dist
* (ctx
->Point
.Params
[1] +
617 dist
* ctx
->Point
.Params
[2]));
623 dist2(GLfloat
*out
, GLuint first
, GLuint last
,
624 const GLcontext
*ctx
, const GLvector4f
*v
)
626 GLuint stride
= v
->stride
;
627 const GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
630 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) ) {
631 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
632 out
[i
] = 1.0F
/ (ctx
->Point
.Params
[0] +
633 dist
* (ctx
->Point
.Params
[1] +
634 dist
* ctx
->Point
.Params
[2]));
639 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
640 const GLcontext
*ctx
, const GLvector4f
*v
);
643 static dist_func eye_dist_tab
[5] = {
654 * Distance Attenuated General CI points.
657 dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
659 struct vertex_buffer
*VB
= ctx
->VB
;
660 struct pixel_buffer
*PB
= ctx
->PB
;
661 GLfloat dist
[VB_SIZE
];
662 const GLfloat psize
= ctx
->Point
.Size
;
665 ASSERT(ctx
->NeedEyeCoords
);
666 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
669 for (i
=first
;i
<=last
;i
++) {
670 if (VB
->ClipMask
[i
]==0) {
671 GLint x0
, x1
, y0
, y1
;
674 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
675 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
676 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
677 GLfloat dsize
= psize
* dist
[i
];
679 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
681 if (dsize
>= ctx
->Point
.Threshold
) {
682 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
685 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
698 x0
= (GLint
) (x
+ 1.5F
) - radius
;
700 y0
= (GLint
) (y
+ 1.5F
) - radius
;
704 PB_SET_INDEX( PB
, VB
->IndexPtr
->data
[i
] );
706 for (iy
=y0
;iy
<=y1
;iy
++) {
707 for (ix
=x0
;ix
<=x1
;ix
++) {
708 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
711 PB_CHECK_FLUSH(ctx
,PB
);
717 * Distance Attenuated General RGBA points.
720 dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
722 struct vertex_buffer
*VB
= ctx
->VB
;
723 struct pixel_buffer
*PB
= ctx
->PB
;
724 GLfloat dist
[VB_SIZE
];
725 const GLfloat psize
= ctx
->Point
.Size
;
728 ASSERT (ctx
->NeedEyeCoords
);
729 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
731 for (i
=first
;i
<=last
;i
++) {
732 if (VB
->ClipMask
[i
]==0) {
733 GLint x0
, x1
, y0
, y1
;
736 GLint x
= (GLint
) VB
->Win
.data
[i
][0];
737 GLint y
= (GLint
) VB
->Win
.data
[i
][1];
738 GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
739 GLfloat dsize
=psize
*dist
[i
];
741 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
743 if (dsize
>= ctx
->Point
.Threshold
) {
744 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
745 alpha
= VB
->ColorPtr
->data
[i
][3];
748 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
749 dsize
/= ctx
->Point
.Threshold
;
750 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
763 x0
= (GLint
) (x
+ 1.5F
) - radius
;
765 y0
= (GLint
) (y
+ 1.5F
) - radius
;
770 VB
->ColorPtr
->data
[i
][0],
771 VB
->ColorPtr
->data
[i
][1],
772 VB
->ColorPtr
->data
[i
][2],
775 for (iy
= y0
; iy
<= y1
; iy
++) {
776 for (ix
= x0
; ix
<= x1
; ix
++) {
777 PB_WRITE_PIXEL( PB
, ix
, iy
, z
, fog
);
780 PB_CHECK_FLUSH(ctx
,PB
);
786 * Distance Attenuated Textured RGBA points.
789 dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
791 struct vertex_buffer
*VB
= ctx
->VB
;
792 struct pixel_buffer
*PB
= ctx
->PB
;
793 GLfloat dist
[VB_SIZE
];
794 const GLfloat psize
= ctx
->Point
.Size
;
797 ASSERT(ctx
->NeedEyeCoords
);
798 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
800 for (i
=first
;i
<=last
;i
++) {
801 if (VB
->ClipMask
[i
]==0) {
802 const GLint x
= (GLint
) VB
->Win
.data
[i
][0];
803 const GLint y
= (GLint
) VB
->Win
.data
[i
][1];
804 const GLint z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
805 const GLint red
= VB
->ColorPtr
->data
[i
][0];
806 const GLint green
= VB
->ColorPtr
->data
[i
][1];
807 const GLint blue
= VB
->ColorPtr
->data
[i
][2];
808 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
809 GLint x0
, x1
, y0
, y1
;
810 GLint ix
, iy
, alpha
, u
;
812 GLfloat dsize
= psize
*dist
[i
];
814 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
816 /* compute point size and alpha */
817 if (dsize
>= ctx
->Point
.Threshold
) {
818 isize
= (GLint
) (MIN2(dsize
, ctx
->Point
.MaxSize
) + 0.5F
);
819 alpha
= VB
->ColorPtr
->data
[i
][3];
822 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) + 0.5F
);
823 dsize
/= ctx
->Point
.Threshold
;
824 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3] * (dsize
* dsize
));
840 x0
= (GLint
) (x
+ 1.5F
) - radius
;
842 y0
= (GLint
) (y
+ 1.5F
) - radius
;
846 /* get texture coordinates */
847 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
848 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
849 switch (VB
->TexCoordPtr
[0]->size
) {
851 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
852 VB
->TexCoordPtr
[u
]->data
[i
][3];
853 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
854 VB
->TexCoordPtr
[u
]->data
[i
][3];
855 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
856 VB
->TexCoordPtr
[u
]->data
[i
][3];
859 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
860 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
861 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
864 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
865 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
866 texcoord
[u
][2] = 0.0;
869 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
870 texcoord
[u
][1] = 0.0;
871 texcoord
[u
][2] = 0.0;
874 /* should never get here */
875 gl_problem(ctx
, "unexpected texcoord size");
880 for (iy
= y0
; iy
<= y1
; iy
++) {
881 for (ix
= x0
; ix
<= x1
; ix
++) {
882 if (ctx
->Texture
.MultiTextureEnabled
) {
883 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, fog
,
884 red
, green
, blue
, alpha
,
888 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, fog
,
889 red
, green
, blue
, alpha
,
896 PB_CHECK_FLUSH(ctx
,PB
);
902 * Distance Attenuated Antialiased points with or without texture mapping.
905 dist_atten_antialiased_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
907 struct vertex_buffer
*VB
= ctx
->VB
;
908 struct pixel_buffer
*PB
= ctx
->PB
;
909 GLfloat dist
[VB_SIZE
];
910 const GLfloat psize
= ctx
->Point
.Size
;
913 ASSERT(ctx
->NeedEyeCoords
);
914 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
916 if (ctx
->Texture
.ReallyEnabled
) {
917 for (i
=first
;i
<=last
;i
++) {
918 if (VB
->ClipMask
[i
]==0) {
919 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
920 GLint xmin
, ymin
, xmax
, ymax
;
922 GLint red
, green
, blue
, alpha
;
923 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
924 GLfloat dsize
= psize
* dist
[i
];
927 GLfixed fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
929 if (dsize
>= ctx
->Point
.Threshold
) {
930 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
934 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
935 dsize
/= ctx
->Point
.Threshold
;
936 alphaf
= (dsize
*dsize
);
938 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
939 rmax
= radius
+ 0.7071F
;
940 rmin2
= MAX2(0.0, rmin
* rmin
);
942 cscale
= 256.0F
/ (rmax2
- rmin2
);
944 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
945 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
946 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
947 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
948 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
950 red
= VB
->ColorPtr
->data
[i
][0];
951 green
= VB
->ColorPtr
->data
[i
][1];
952 blue
= VB
->ColorPtr
->data
[i
][2];
954 /* get texture coordinates */
955 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
956 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
957 switch (VB
->TexCoordPtr
[0]->size
) {
959 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0] /
960 VB
->TexCoordPtr
[u
]->data
[i
][3];
961 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1] /
962 VB
->TexCoordPtr
[u
]->data
[i
][3];
963 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2] /
964 VB
->TexCoordPtr
[u
]->data
[i
][3];
967 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
968 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
969 texcoord
[u
][2] = VB
->TexCoordPtr
[u
]->data
[i
][2];
972 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
973 texcoord
[u
][1] = VB
->TexCoordPtr
[u
]->data
[i
][1];
974 texcoord
[u
][2] = 0.0;
977 texcoord
[u
][0] = VB
->TexCoordPtr
[u
]->data
[i
][0];
978 texcoord
[u
][1] = 0.0;
979 texcoord
[u
][2] = 0.0;
982 /* should never get here */
983 gl_problem(ctx
, "unexpected texcoord size");
988 for (y
= ymin
; y
<= ymax
; y
++) {
989 for (x
= xmin
; x
<= xmax
; x
++) {
990 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
991 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
992 const GLfloat dist2
= dx
*dx
+ dy
*dy
;
994 alpha
= VB
->ColorPtr
->data
[i
][3];
995 if (dist2
>= rmin2
) {
996 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
997 /* coverage is in [0,256] */
998 alpha
= (alpha
* coverage
) >> 8;
1000 alpha
= (GLint
) (alpha
* alphaf
);
1001 if (ctx
->Texture
.MultiTextureEnabled
) {
1002 PB_WRITE_MULTITEX_PIXEL( PB
, x
, y
, z
, fog
,
1003 red
, green
, blue
, alpha
,
1007 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, fog
,
1008 red
, green
, blue
, alpha
,
1016 PB_CHECK_FLUSH(ctx
,PB
);
1021 /* Not texture mapped */
1022 for (i
= first
; i
<= last
; i
++) {
1023 if (VB
->ClipMask
[i
] == 0) {
1024 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
, alphaf
;
1025 GLint xmin
, ymin
, xmax
, ymax
;
1028 GLint red
, green
, blue
, alpha
;
1029 GLfloat dsize
= psize
* dist
[i
];
1031 if (dsize
>= ctx
->Point
.Threshold
) {
1032 radius
= MIN2(dsize
, ctx
->Point
.MaxSize
) * 0.5F
;
1036 radius
= (MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
) * 0.5F
);
1037 dsize
/= ctx
->Point
.Threshold
;
1038 alphaf
= dsize
* dsize
;
1040 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1041 rmax
= radius
+ 0.7071F
;
1042 rmin2
= MAX2(0.0, rmin
* rmin
);
1043 rmax2
= rmax
* rmax
;
1044 cscale
= 256.0F
/ (rmax2
- rmin2
);
1046 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1047 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1048 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1049 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1050 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1052 fog
= FloatToFixed( VB
->FogCoordPtr
->data
[i
] );
1054 red
= VB
->ColorPtr
->data
[i
][0];
1055 green
= VB
->ColorPtr
->data
[i
][1];
1056 blue
= VB
->ColorPtr
->data
[i
][2];
1058 for (y
= ymin
; y
<= ymax
; y
++) {
1059 for (x
= xmin
; x
<= xmax
; x
++) {
1060 const GLfloat dx
= x
+ 0.5F
- VB
->Win
.data
[i
][0];
1061 const GLfloat dy
= y
+ 0.5F
- VB
->Win
.data
[i
][1];
1062 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
1063 if (dist2
< rmax2
) {
1064 alpha
= VB
->ColorPtr
->data
[i
][3];
1065 if (dist2
>= rmin2
) {
1066 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
1067 /* coverage is in [0,256] */
1068 alpha
= (alpha
* coverage
) >> 8;
1070 alpha
= (GLint
) (alpha
* alphaf
);
1071 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
,
1072 red
, green
, blue
, alpha
);
1076 PB_CHECK_FLUSH(ctx
,PB
);
1085 _mesa_print_points_function(GLcontext
*ctx
)
1087 printf("Point Func == ");
1088 if (ctx
->Driver
.PointsFunc
== size1_ci_points
)
1089 printf("size1_ci_points\n");
1090 else if (ctx
->Driver
.PointsFunc
== size1_rgba_points
)
1091 printf("size1_rgba_points\n");
1092 else if (ctx
->Driver
.PointsFunc
== general_ci_points
)
1093 printf("general_ci_points\n");
1094 else if (ctx
->Driver
.PointsFunc
== general_rgba_points
)
1095 printf("general_rgba_points\n");
1096 else if (ctx
->Driver
.PointsFunc
== textured_rgba_points
)
1097 printf("textured_rgba_points\n");
1098 else if (ctx
->Driver
.PointsFunc
== multitextured_rgba_points
)
1099 printf("multitextured_rgba_points\n");
1100 else if (ctx
->Driver
.PointsFunc
== antialiased_rgba_points
)
1101 printf("antialiased_rgba_points\n");
1102 else if (ctx
->Driver
.PointsFunc
== null_points
)
1103 printf("null_points\n");
1104 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_ci_points
)
1105 printf("dist_atten_general_ci_points\n");
1106 else if (ctx
->Driver
.PointsFunc
== dist_atten_general_rgba_points
)
1107 printf("dist_atten_general_rgba_points\n");
1108 else if (ctx
->Driver
.PointsFunc
== dist_atten_textured_rgba_points
)
1109 printf("dist_atten_textured_rgba_points\n");
1110 else if (ctx
->Driver
.PointsFunc
== dist_atten_antialiased_rgba_points
)
1111 printf("dist_atten_antialiased_rgba_points\n");
1112 else if (!ctx
->Driver
.PointsFunc
)
1115 printf("Driver func %p\n", ctx
->Driver
.PointsFunc
);
1121 * Examine the current context to determine which point drawing function
1125 _swrast_set_point_function( GLcontext
*ctx
)
1127 GLboolean rgbmode
= ctx
->Visual
.RGBAflag
;
1129 if (ctx
->RenderMode
==GL_RENDER
) {
1130 if (ctx
->NoRaster
) {
1131 ctx
->Driver
.PointsFunc
= null_points
;
1134 if (ctx
->Driver
.PointsFunc
) {
1135 /* Device driver will draw points. */
1136 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1140 if (!ctx
->Point
.Attenuated
) {
1141 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1142 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1144 else if (ctx
->Texture
.ReallyEnabled
) {
1145 if (ctx
->Texture
.MultiTextureEnabled
||
1146 ctx
->Light
.Model
.ColorControl
==GL_SEPARATE_SPECULAR_COLOR
||
1147 ctx
->Fog
.ColorSumEnabled
) {
1148 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1151 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1154 else if (ctx
->Point
.Size
==1.0) {
1155 /* size=1, any raster ops */
1157 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1159 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1162 /* every other kind of point rendering */
1164 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1166 ctx
->Driver
.PointsFunc
= general_ci_points
;
1169 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1170 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1172 else if (ctx
->Texture
.ReallyEnabled
) {
1173 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1176 /* every other kind of point rendering */
1178 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1180 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1183 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1184 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1187 /* GL_SELECT mode */
1188 ctx
->Driver
.PointsFunc
= gl_select_points
;
1191 /*_mesa_print_points_function(ctx);*/