fe4810eaebecc85b06892fe9e500331a1a4ec417
[mesa.git] / src / mesa / main / points.c
1 /* $Id: points.c,v 1.11 2000/07/15 03:13:43 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "context.h"
33 #include "feedback.h"
34 #include "macros.h"
35 #include "mmath.h"
36 #include "pb.h"
37 #include "points.h"
38 #include "span.h"
39 #include "texstate.h"
40 #include "types.h"
41 #include "vb.h"
42 #endif
43
44
45
46 void
47 _mesa_PointSize( GLfloat size )
48 {
49 GET_CURRENT_CONTEXT(ctx);
50 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPointSize");
51
52 if (size <= 0.0) {
53 gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
54 return;
55 }
56
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;
61 if (size != 1.0)
62 ctx->TriangleCaps |= DD_POINT_SIZE;
63 ctx->NewState |= NEW_RASTER_OPS;
64 }
65 }
66
67
68
69 void
70 _mesa_PointParameterfEXT( GLenum pname, GLfloat param)
71 {
72 _mesa_PointParameterfvEXT(pname, &param);
73 }
74
75
76 void
77 _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
78 {
79 GET_CURRENT_CONTEXT(ctx);
80 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPointParameterfvEXT");
81
82 switch (pname) {
83 case GL_DISTANCE_ATTENUATION_EXT:
84 {
85 const GLboolean tmp = ctx->Point.Attenuated;
86 COPY_3V(ctx->Point.Params, params);
87 ctx->Point.Attenuated = (params[0] != 1.0 ||
88 params[1] != 0.0 ||
89 params[2] != 0.0);
90
91 if (tmp != ctx->Point.Attenuated) {
92 ctx->Enabled ^= ENABLE_POINT_ATTEN;
93 ctx->TriangleCaps ^= DD_POINT_ATTEN;
94 ctx->NewState |= NEW_RASTER_OPS;
95 }
96 }
97 break;
98 case GL_POINT_SIZE_MIN_EXT:
99 if (*params < 0.0F) {
100 gl_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" );
101 return;
102 }
103 ctx->Point.MinSize = *params;
104 break;
105 case GL_POINT_SIZE_MAX_EXT:
106 if (*params < 0.0F) {
107 gl_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" );
108 return;
109 }
110 ctx->Point.MaxSize = *params;
111 break;
112 case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
113 if (*params < 0.0F) {
114 gl_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" );
115 return;
116 }
117 ctx->Point.Threshold = *params;
118 break;
119 default:
120 gl_error( ctx, GL_INVALID_ENUM, "glPointParameterfvEXT" );
121 return;
122 }
123
124 ctx->NewState |= NEW_RASTER_OPS;
125 }
126
127
128 /**********************************************************************/
129 /***** Rasterization *****/
130 /**********************************************************************/
131
132
133 /*
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)
138 *
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.
142 */
143
144
145
146
147
148 /*
149 * CI points with size == 1.0
150 */
151 static void
152 size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
153 {
154 struct vertex_buffer *VB = ctx->VB;
155 struct pixel_buffer *PB = ctx->PB;
156 GLfloat *win;
157 GLint *pbx = PB->x, *pby = PB->y;
158 GLdepth *pbz = PB->z;
159 GLuint *pbi = PB->index;
160 GLuint pbcount = PB->count;
161 GLuint i;
162
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];
170 pbcount++;
171 }
172 win += 3;
173 }
174 PB->count = pbcount;
175 PB_CHECK_FLUSH(ctx, PB);
176 }
177
178
179
180 /*
181 * RGBA points with size == 1.0
182 */
183 static void
184 size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
185 {
186 struct vertex_buffer *VB = ctx->VB;
187 struct pixel_buffer *PB = ctx->PB;
188 GLuint i;
189
190 for (i = first; i <= last; i++) {
191 if (VB->ClipMask[i] == 0) {
192 GLint x, y, z;
193 GLint red, green, blue, alpha;
194
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);
198
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];
203
204 PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
205 }
206 }
207 PB_CHECK_FLUSH(ctx, PB);
208 }
209
210
211
212 /*
213 * General CI points.
214 */
215 static void
216 general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
217 {
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;
222 GLuint i;
223
224 for (i = first; i <= last; i++) {
225 if (VB->ClipMask[i] == 0) {
226 GLint x0, x1, y0, y1;
227 GLint ix, iy;
228
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);
232
233 if (isize & 1) {
234 /* odd size */
235 x0 = x - radius;
236 x1 = x + radius;
237 y0 = y - radius;
238 y1 = y + radius;
239 }
240 else {
241 /* even size */
242 x0 = (GLint) (x + 1.5F) - radius;
243 x1 = x0 + isize - 1;
244 y0 = (GLint) (y + 1.5F) - radius;
245 y1 = y0 + isize - 1;
246 }
247
248 PB_SET_INDEX( PB, VB->IndexPtr->data[i] );
249
250 for (iy = y0; iy <= y1; iy++) {
251 for (ix = x0; ix <= x1; ix++) {
252 PB_WRITE_PIXEL( PB, ix, iy, z );
253 }
254 }
255 PB_CHECK_FLUSH(ctx,PB);
256 }
257 }
258 }
259
260
261 /*
262 * General RGBA points.
263 */
264 static void
265 general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
266 {
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;
271 GLuint i;
272
273 for (i = first; i <= last; i++) {
274 if (VB->ClipMask[i] == 0) {
275 GLint x0, x1, y0, y1;
276 GLint ix, iy;
277
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);
281
282 if (isize & 1) {
283 /* odd size */
284 x0 = x - radius;
285 x1 = x + radius;
286 y0 = y - radius;
287 y1 = y + radius;
288 }
289 else {
290 /* even size */
291 x0 = (GLint) (x + 1.5F) - radius;
292 x1 = x0 + isize - 1;
293 y0 = (GLint) (y + 1.5F) - radius;
294 y1 = y0 + isize - 1;
295 }
296
297 PB_SET_COLOR( PB,
298 VB->ColorPtr->data[i][0],
299 VB->ColorPtr->data[i][1],
300 VB->ColorPtr->data[i][2],
301 VB->ColorPtr->data[i][3] );
302
303 for (iy = y0; iy <= y1; iy++) {
304 for (ix = x0; ix <= x1; ix++) {
305 PB_WRITE_PIXEL( PB, ix, iy, z );
306 }
307 }
308 PB_CHECK_FLUSH(ctx,PB);
309 }
310 }
311 }
312
313
314
315
316 /*
317 * Textured RGBA points.
318 */
319 static void
320 textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
321 {
322 struct vertex_buffer *VB = ctx->VB;
323 struct pixel_buffer *PB = ctx->PB;
324 GLuint i;
325
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;
331 GLfloat s, t, u;
332
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);
337
338 if (isize < 1) {
339 isize = 1;
340 }
341 radius = isize >> 1;
342
343 if (isize & 1) {
344 /* odd size */
345 x0 = x - radius;
346 x1 = x + radius;
347 y0 = y - radius;
348 y1 = y + radius;
349 }
350 else {
351 /* even size */
352 x0 = (GLint) (x + 1.5F) - radius;
353 x1 = x0 + isize - 1;
354 y0 = (GLint) (y + 1.5F) - radius;
355 y1 = y0 + isize - 1;
356 }
357
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];
362
363 switch (VB->TexCoordPtr[0]->size) {
364 case 4:
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];
368 break;
369 case 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];
373 break;
374 case 2:
375 s = VB->TexCoordPtr[0]->data[i][0];
376 t = VB->TexCoordPtr[0]->data[i][1];
377 u = 0.0;
378 break;
379 case 1:
380 s = VB->TexCoordPtr[0]->data[i][0];
381 t = 0.0;
382 u = 0.0;
383 break;
384 default:
385 /* should never get here */
386 s = t = u = 0.0;
387 gl_problem(ctx, "unexpected texcoord size in textured_rgba_points()");
388 }
389
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,
393 s, t, u );
394 }
395 }
396
397 PB_CHECK_FLUSH(ctx, PB);
398 }
399 }
400 }
401
402
403 /*
404 * Multitextured RGBA points.
405 */
406 static void
407 multitextured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
408 {
409 struct vertex_buffer *VB = ctx->VB;
410 struct pixel_buffer *PB = ctx->PB;
411 GLuint i;
412
413 for (i = first; i <= last; i++) {
414 if (VB->ClipMask[i] == 0) {
415 GLint x0, x1, y0, y1;
416 GLint ix, iy;
417 GLint radius;
418 GLint red, green, blue, alpha;
419 GLint sRed, sGreen, sBlue;
420 GLfloat s, t, u;
421 GLfloat s1, t1, u1;
422
423 GLint x = (GLint) VB->Win.data[i][0];
424 GLint y = (GLint) VB->Win.data[i][1];
425 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
426 GLint isize = (GLint) (ctx->Point.Size + 0.5F);
427
428 if (isize < 1) {
429 isize = 1;
430 }
431 radius = isize >> 1;
432
433 if (isize & 1) {
434 /* odd size */
435 x0 = x - radius;
436 x1 = x + radius;
437 y0 = y - radius;
438 y1 = y + radius;
439 }
440 else {
441 /* even size */
442 x0 = (GLint) (x + 1.5F) - radius;
443 x1 = x0 + isize - 1;
444 y0 = (GLint) (y + 1.5F) - radius;
445 y1 = y0 + isize - 1;
446 }
447
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];
452 sRed = VB->Specular ? VB->Specular[i][0] : 0;
453 sGreen = VB->Specular ? VB->Specular[i][1] : 0;
454 sBlue = VB->Specular ? VB->Specular[i][2] : 0;
455
456 switch (VB->TexCoordPtr[0]->size) {
457 case 4:
458 s = VB->TexCoordPtr[0]->data[i][0]/VB->TexCoordPtr[0]->data[i][3];
459 t = VB->TexCoordPtr[0]->data[i][1]/VB->TexCoordPtr[0]->data[i][3];
460 u = VB->TexCoordPtr[0]->data[i][2]/VB->TexCoordPtr[0]->data[i][3];
461 break;
462 case 3:
463 s = VB->TexCoordPtr[0]->data[i][0];
464 t = VB->TexCoordPtr[0]->data[i][1];
465 u = VB->TexCoordPtr[0]->data[i][2];
466 break;
467 case 2:
468 s = VB->TexCoordPtr[0]->data[i][0];
469 t = VB->TexCoordPtr[0]->data[i][1];
470 u = 0.0;
471 break;
472 case 1:
473 s = VB->TexCoordPtr[0]->data[i][0];
474 t = 0.0;
475 u = 0.0;
476 break;
477 default:
478 /* should never get here */
479 s = t = u = 0.0;
480 gl_problem(ctx, "unexpected texcoord size in multitextured_rgba_points()");
481 }
482
483 switch (VB->TexCoordPtr[1]->size) {
484 case 4:
485 s1 = VB->TexCoordPtr[1]->data[i][0]/VB->TexCoordPtr[1]->data[i][3];
486 t1 = VB->TexCoordPtr[1]->data[i][1]/VB->TexCoordPtr[1]->data[i][3];
487 u1 = VB->TexCoordPtr[1]->data[i][2]/VB->TexCoordPtr[1]->data[i][3];
488 break;
489 case 3:
490 s1 = VB->TexCoordPtr[1]->data[i][0];
491 t1 = VB->TexCoordPtr[1]->data[i][1];
492 u1 = VB->TexCoordPtr[1]->data[i][2];
493 break;
494 case 2:
495 s1 = VB->TexCoordPtr[1]->data[i][0];
496 t1 = VB->TexCoordPtr[1]->data[i][1];
497 u1 = 0.0;
498 break;
499 case 1:
500 s1 = VB->TexCoordPtr[1]->data[i][0];
501 t1 = 0.0;
502 u1 = 0.0;
503 break;
504 default:
505 /* should never get here */
506 s1 = t1 = u1 = 0.0;
507 gl_problem(ctx, "unexpected texcoord size in multitextured_rgba_points()");
508 }
509
510 for (iy=y0;iy<=y1;iy++) {
511 for (ix=x0;ix<=x1;ix++) {
512 PB_WRITE_MULTITEX_SPEC_PIXEL( PB, ix, iy, z,
513 red, green, blue, alpha,
514 sRed, sGreen, sBlue,
515 s, t, u, s1, t1, u1 );
516 }
517 }
518 PB_CHECK_FLUSH(ctx, PB);
519 }
520 }
521 }
522
523
524 /*
525 * NOTES on aa point rasterization:
526 *
527 * Let d = distance of fragment center from vertex.
528 * if d < rmin2 then
529 * fragment has 100% coverage
530 * else if d > rmax2 then
531 * fragment has 0% coverage
532 * else
533 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
534 */
535
536
537 /*
538 * Antialiased points with or without texture mapping.
539 */
540 static void
541 antialiased_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
542 {
543 struct vertex_buffer *VB = ctx->VB;
544 struct pixel_buffer *PB = ctx->PB;
545 const GLfloat radius = ctx->Point.Size * 0.5F;
546 const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
547 const GLfloat rmax = radius + 0.7071F;
548 const GLfloat rmin2 = MAX2(0.0, rmin * rmin);
549 const GLfloat rmax2 = rmax * rmax;
550 const GLfloat cscale = 256.0F / (rmax2 - rmin2);
551 GLuint i;
552
553 if (ctx->Texture.ReallyEnabled) {
554 for (i = first; i <= last; i++) {
555 if (VB->ClipMask[i] == 0) {
556 GLint x, y;
557 GLint red, green, blue, alpha;
558 GLfloat s, t, u;
559 GLfloat s1, t1, u1;
560 GLfloat vx = VB->Win.data[i][0];
561 GLfloat vy = VB->Win.data[i][1];
562
563 GLint xmin = (GLint) (vx - radius);
564 GLint xmax = (GLint) (vx + radius);
565 GLint ymin = (GLint) (vy - radius);
566 GLint ymax = (GLint) (vy + radius);
567 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
568
569 red = VB->ColorPtr->data[i][0];
570 green = VB->ColorPtr->data[i][1];
571 blue = VB->ColorPtr->data[i][2];
572
573 switch (VB->TexCoordPtr[0]->size) {
574 case 4:
575 s = (VB->TexCoordPtr[0]->data[i][0]/
576 VB->TexCoordPtr[0]->data[i][3]);
577 t = (VB->TexCoordPtr[0]->data[i][1]/
578 VB->TexCoordPtr[0]->data[i][3]);
579 u = (VB->TexCoordPtr[0]->data[i][2]/
580 VB->TexCoordPtr[0]->data[i][3]);
581 break;
582 case 3:
583 s = VB->TexCoordPtr[0]->data[i][0];
584 t = VB->TexCoordPtr[0]->data[i][1];
585 u = VB->TexCoordPtr[0]->data[i][2];
586 break;
587 case 2:
588 s = VB->TexCoordPtr[0]->data[i][0];
589 t = VB->TexCoordPtr[0]->data[i][1];
590 u = 0.0;
591 break;
592 case 1:
593 s = VB->TexCoordPtr[0]->data[i][0];
594 t = 0.0;
595 u = 0.0;
596 break;
597 default:
598 /* should never get here */
599 s = t = u = 0.0;
600 gl_problem(ctx, "unexpected texcoord size in antialiased_rgba_points()");
601 }
602
603 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
604 /* Multitextured! This is probably a slow enough path that
605 there's no reason to specialize the multitexture case. */
606 switch (VB->TexCoordPtr[1]->size) {
607 case 4:
608 s1 = ( VB->TexCoordPtr[1]->data[i][0] /
609 VB->TexCoordPtr[1]->data[i][3]);
610 t1 = ( VB->TexCoordPtr[1]->data[i][1] /
611 VB->TexCoordPtr[1]->data[i][3]);
612 u1 = ( VB->TexCoordPtr[1]->data[i][2] /
613 VB->TexCoordPtr[1]->data[i][3]);
614 break;
615 case 3:
616 s1 = VB->TexCoordPtr[1]->data[i][0];
617 t1 = VB->TexCoordPtr[1]->data[i][1];
618 u1 = VB->TexCoordPtr[1]->data[i][2];
619 break;
620 case 2:
621 s1 = VB->TexCoordPtr[1]->data[i][0];
622 t1 = VB->TexCoordPtr[1]->data[i][1];
623 u1 = 0.0;
624 break;
625 case 1:
626 s1 = VB->TexCoordPtr[1]->data[i][0];
627 t1 = 0.0;
628 u1 = 0.0;
629 break;
630 default:
631 /* should never get here */
632 s1 = t1 = u1 = 0.0;
633 gl_problem(ctx, "unexpected texcoord size in antialiased_rgba_points()");
634 }
635 }
636
637 /* translate by a half pixel to simplify math below */
638 vx -= 0.5F;
639 vx -= 0.5F;
640
641 for (y = ymin; y <= ymax; y++) {
642 for (x = xmin; x <= xmax; x++) {
643 const GLfloat dx = x - vx;
644 const GLfloat dy = y - vy;
645 const GLfloat dist2 = dx*dx + dy*dy;
646 if (dist2 < rmax2) {
647 alpha = VB->ColorPtr->data[i][3];
648 if (dist2 >= rmin2) {
649 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
650 /* coverage is in [0,256] */
651 alpha = (alpha * coverage) >> 8;
652 }
653 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
654 PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, red, green, blue,
655 alpha, s, t, u, s1, t1, u1 );
656 } else {
657 PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue,
658 alpha, s, t, u );
659 }
660 }
661 }
662 }
663
664 PB_CHECK_FLUSH(ctx,PB);
665 }
666 }
667 }
668 else {
669 /* Not texture mapped */
670 for (i=first;i<=last;i++) {
671 if (VB->ClipMask[i]==0) {
672 GLint xmin, ymin, xmax, ymax;
673 GLint x, y, z;
674 GLint red, green, blue, alpha;
675
676 xmin = (GLint) (VB->Win.data[i][0] - 0.0 - radius);
677 xmax = (GLint) (VB->Win.data[i][0] - 0.0 + radius);
678 ymin = (GLint) (VB->Win.data[i][1] - 0.0 - radius);
679 ymax = (GLint) (VB->Win.data[i][1] - 0.0 + radius);
680 z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
681
682 red = VB->ColorPtr->data[i][0];
683 green = VB->ColorPtr->data[i][1];
684 blue = VB->ColorPtr->data[i][2];
685
686 /*
687 printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
688 printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
689 */
690 for (y = ymin; y <= ymax; y++) {
691 for (x = xmin; x <= xmax; x++) {
692 const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
693 const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
694 const GLfloat dist2 = dx*dx + dy*dy;
695 if (dist2 < rmax2) {
696 alpha = VB->ColorPtr->data[i][3];
697 if (dist2 >= rmin2) {
698 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
699 /* coverage is in [0,256] */
700 alpha = (alpha * coverage) >> 8;
701 }
702 PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue,
703 alpha );
704 }
705 }
706 }
707 PB_CHECK_FLUSH(ctx,PB);
708 }
709 }
710 }
711 }
712
713
714
715 /*
716 * Null rasterizer for measuring transformation speed.
717 */
718 static void
719 null_points( GLcontext *ctx, GLuint first, GLuint last )
720 {
721 (void) ctx;
722 (void) first;
723 (void) last;
724 }
725
726
727
728 /* Definition of the functions for GL_EXT_point_parameters */
729
730 /* Calculates the distance attenuation formula of a vector of points in
731 * eye space coordinates
732 */
733 static void
734 dist3(GLfloat *out, GLuint first, GLuint last,
735 const GLcontext *ctx, const GLvector4f *v)
736 {
737 GLuint stride = v->stride;
738 const GLfloat *p = VEC_ELT(v, GLfloat, first);
739 GLuint i;
740
741 for (i = first ; i <= last ; i++, STRIDE_F(p, stride) ) {
742 GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
743 out[i] = 1.0F / (ctx->Point.Params[0] +
744 dist * (ctx->Point.Params[1] +
745 dist * ctx->Point.Params[2]));
746 }
747 }
748
749
750 static void
751 dist2(GLfloat *out, GLuint first, GLuint last,
752 const GLcontext *ctx, const GLvector4f *v)
753 {
754 GLuint stride = v->stride;
755 const GLfloat *p = VEC_ELT(v, GLfloat, first);
756 GLuint i;
757
758 for (i = first ; i <= last ; i++, STRIDE_F(p, stride) ) {
759 GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]);
760 out[i] = 1.0F / (ctx->Point.Params[0] +
761 dist * (ctx->Point.Params[1] +
762 dist * ctx->Point.Params[2]));
763 }
764 }
765
766
767 typedef void (*dist_func)(GLfloat *out, GLuint first, GLuint last,
768 const GLcontext *ctx, const GLvector4f *v);
769
770
771 static dist_func eye_dist_tab[5] = {
772 0,
773 0,
774 dist2,
775 dist3,
776 dist3
777 };
778
779
780 static void
781 clip_dist(GLfloat *out, GLuint first, GLuint last,
782 const GLcontext *ctx, GLvector4f *clip)
783 {
784 /* this is never called */
785 gl_problem(NULL, "clip_dist() called - dead code!\n");
786
787 (void) out;
788 (void) first;
789 (void) last;
790 (void) ctx;
791 (void) clip;
792
793 #if 0
794 GLuint i;
795 const GLfloat *from = (GLfloat *)clip_vec->start;
796 const GLuint stride = clip_vec->stride;
797
798 for (i = first ; i <= last ; i++ )
799 {
800 GLfloat dist = win[i][2];
801 out[i] = 1/(ctx->Point.Params[0]+
802 dist * (ctx->Point.Params[1] +
803 dist * ctx->Point.Params[2]));
804 }
805 #endif
806 }
807
808
809
810 /*
811 * Distance Attenuated General CI points.
812 */
813 static void
814 dist_atten_general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
815 {
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;
820 GLuint i;
821
822 if (ctx->NeedEyeCoords)
823 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
824 else
825 clip_dist( dist, first, last, ctx, VB->ClipPtr );
826
827 for (i=first;i<=last;i++) {
828 if (VB->ClipMask[i]==0) {
829 GLint x0, x1, y0, y1;
830 GLint ix, iy;
831 GLint isize, radius;
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];
836
837 if (dsize >= ctx->Point.Threshold) {
838 isize = (GLint) (MIN2(dsize, ctx->Point.MaxSize) + 0.5F);
839 }
840 else {
841 isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F);
842 }
843 radius = isize >> 1;
844
845 if (isize & 1) {
846 /* odd size */
847 x0 = x - radius;
848 x1 = x + radius;
849 y0 = y - radius;
850 y1 = y + radius;
851 }
852 else {
853 /* even size */
854 x0 = (GLint) (x + 1.5F) - radius;
855 x1 = x0 + isize - 1;
856 y0 = (GLint) (y + 1.5F) - radius;
857 y1 = y0 + isize - 1;
858 }
859
860 PB_SET_INDEX( PB, VB->IndexPtr->data[i] );
861
862 for (iy=y0;iy<=y1;iy++) {
863 for (ix=x0;ix<=x1;ix++) {
864 PB_WRITE_PIXEL( PB, ix, iy, z );
865 }
866 }
867 PB_CHECK_FLUSH(ctx,PB);
868 }
869 }
870 }
871
872 /*
873 * Distance Attenuated General RGBA points.
874 */
875 static void
876 dist_atten_general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
877 {
878 struct vertex_buffer *VB = ctx->VB;
879 struct pixel_buffer *PB = ctx->PB;
880 GLfloat dist[VB_SIZE];
881 const GLfloat psize = ctx->Point.Size;
882 GLuint i;
883
884 if (ctx->NeedEyeCoords)
885 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
886 else
887 clip_dist( dist, first, last, ctx, VB->ClipPtr );
888
889 for (i=first;i<=last;i++) {
890 if (VB->ClipMask[i]==0) {
891 GLint x0, x1, y0, y1;
892 GLint ix, iy;
893 GLint isize, radius;
894 GLint x = (GLint) VB->Win.data[i][0];
895 GLint y = (GLint) VB->Win.data[i][1];
896 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
897 GLfloat dsize=psize*dist[i];
898 GLubyte alpha;
899
900 if (dsize >= ctx->Point.Threshold) {
901 isize = (GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
902 alpha = VB->ColorPtr->data[i][3];
903 }
904 else {
905 isize = (GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
906 dsize /= ctx->Point.Threshold;
907 alpha = (GLint) (VB->ColorPtr->data[i][3]* (dsize*dsize));
908 }
909 radius = isize >> 1;
910
911 if (isize & 1) {
912 /* odd size */
913 x0 = x - radius;
914 x1 = x + radius;
915 y0 = y - radius;
916 y1 = y + radius;
917 }
918 else {
919 /* even size */
920 x0 = (GLint) (x + 1.5F) - radius;
921 x1 = x0 + isize - 1;
922 y0 = (GLint) (y + 1.5F) - radius;
923 y1 = y0 + isize - 1;
924 }
925
926 PB_SET_COLOR( PB,
927 VB->ColorPtr->data[i][0],
928 VB->ColorPtr->data[i][1],
929 VB->ColorPtr->data[i][2],
930 alpha );
931
932 for (iy=y0;iy<=y1;iy++) {
933 for (ix=x0;ix<=x1;ix++) {
934 PB_WRITE_PIXEL( PB, ix, iy, z );
935 }
936 }
937 PB_CHECK_FLUSH(ctx,PB);
938 }
939 }
940 }
941
942 /*
943 * Distance Attenuated Textured RGBA points.
944 */
945 static void
946 dist_atten_textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
947 {
948 struct vertex_buffer *VB = ctx->VB;
949 struct pixel_buffer *PB = ctx->PB;
950 GLfloat dist[VB_SIZE];
951 const GLfloat psize = ctx->Point.Size;
952 GLuint i;
953
954 if (ctx->NeedEyeCoords)
955 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
956 else
957 clip_dist( dist, first, last, ctx, VB->ClipPtr );
958
959 for (i=first;i<=last;i++) {
960 if (VB->ClipMask[i]==0) {
961 GLint x0, x1, y0, y1;
962 GLint ix, iy;
963 GLint isize, radius;
964 GLint red, green, blue, alpha;
965 GLfloat s, t, u;
966 GLfloat s1, t1, u1;
967
968 GLint x = (GLint) VB->Win.data[i][0];
969 GLint y = (GLint) VB->Win.data[i][1];
970 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
971
972 GLfloat dsize = psize*dist[i];
973 if(dsize >= ctx->Point.Threshold) {
974 isize = (GLint) (MIN2(dsize, ctx->Point.MaxSize) + 0.5F);
975 alpha = VB->ColorPtr->data[i][3];
976 }
977 else {
978 isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F);
979 dsize /= ctx->Point.Threshold;
980 alpha = (GLint) (VB->ColorPtr->data[i][3] * (dsize * dsize));
981 }
982
983 if (isize < 1) {
984 isize = 1;
985 }
986 radius = isize >> 1;
987
988 if (isize & 1) {
989 /* odd size */
990 x0 = x - radius;
991 x1 = x + radius;
992 y0 = y - radius;
993 y1 = y + radius;
994 }
995 else {
996 /* even size */
997 x0 = (GLint) (x + 1.5F) - radius;
998 x1 = x0 + isize - 1;
999 y0 = (GLint) (y + 1.5F) - radius;
1000 y1 = y0 + isize - 1;
1001 }
1002
1003 red = VB->ColorPtr->data[i][0];
1004 green = VB->ColorPtr->data[i][1];
1005 blue = VB->ColorPtr->data[i][2];
1006
1007 switch (VB->TexCoordPtr[0]->size) {
1008 case 4:
1009 s = (VB->TexCoordPtr[0]->data[i][0]/
1010 VB->TexCoordPtr[0]->data[i][3]);
1011 t = (VB->TexCoordPtr[0]->data[i][1]/
1012 VB->TexCoordPtr[0]->data[i][3]);
1013 u = (VB->TexCoordPtr[0]->data[i][2]/
1014 VB->TexCoordPtr[0]->data[i][3]);
1015 break;
1016 case 3:
1017 s = VB->TexCoordPtr[0]->data[i][0];
1018 t = VB->TexCoordPtr[0]->data[i][1];
1019 u = VB->TexCoordPtr[0]->data[i][2];
1020 break;
1021 case 2:
1022 s = VB->TexCoordPtr[0]->data[i][0];
1023 t = VB->TexCoordPtr[0]->data[i][1];
1024 u = 0.0;
1025 break;
1026 case 1:
1027 s = VB->TexCoordPtr[0]->data[i][0];
1028 t = 0.0;
1029 u = 0.0;
1030 break;
1031 default:
1032 /* should never get here */
1033 s = t = u = 0.0;
1034 gl_problem(ctx, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1035 }
1036
1037 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
1038 /* Multitextured! This is probably a slow enough path that
1039 there's no reason to specialize the multitexture case. */
1040 switch (VB->TexCoordPtr[1]->size) {
1041 case 4:
1042 s1 = ( VB->TexCoordPtr[1]->data[i][0] /
1043 VB->TexCoordPtr[1]->data[i][3] );
1044 t1 = ( VB->TexCoordPtr[1]->data[i][1] /
1045 VB->TexCoordPtr[1]->data[i][3] );
1046 u1 = ( VB->TexCoordPtr[1]->data[i][2] /
1047 VB->TexCoordPtr[1]->data[i][3] );
1048 break;
1049 case 3:
1050 s1 = VB->TexCoordPtr[1]->data[i][0];
1051 t1 = VB->TexCoordPtr[1]->data[i][1];
1052 u1 = VB->TexCoordPtr[1]->data[i][2];
1053 break;
1054 case 2:
1055 s1 = VB->TexCoordPtr[1]->data[i][0];
1056 t1 = VB->TexCoordPtr[1]->data[i][1];
1057 u1 = 0.0;
1058 break;
1059 case 1:
1060 s1 = VB->TexCoordPtr[1]->data[i][0];
1061 t1 = 0.0;
1062 u1 = 0.0;
1063 break;
1064 default:
1065 /* should never get here */
1066 s1 = t1 = u1 = 0.0;
1067 gl_problem(ctx, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1068 }
1069 }
1070
1071 /* don't think this is needed
1072 PB_SET_COLOR( red, green, blue, alpha );
1073 */
1074
1075 for (iy=y0;iy<=y1;iy++) {
1076 for (ix=x0;ix<=x1;ix++) {
1077 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
1078 PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u, s1, t1, u1 );
1079 } else {
1080 PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
1081 }
1082 }
1083 }
1084 PB_CHECK_FLUSH(ctx,PB);
1085 }
1086 }
1087 }
1088
1089 /*
1090 * Distance Attenuated Antialiased points with or without texture mapping.
1091 */
1092 static void
1093 dist_atten_antialiased_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
1094 {
1095 struct vertex_buffer *VB = ctx->VB;
1096 struct pixel_buffer *PB = ctx->PB;
1097 GLfloat dist[VB_SIZE];
1098 const GLfloat psize = ctx->Point.Size;
1099 GLuint i;
1100
1101 if (ctx->NeedEyeCoords)
1102 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
1103 else
1104 clip_dist( dist, first, last, ctx, VB->ClipPtr );
1105
1106 if (ctx->Texture.ReallyEnabled) {
1107 for (i=first;i<=last;i++) {
1108 if (VB->ClipMask[i]==0) {
1109 GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaf;
1110 GLint xmin, ymin, xmax, ymax;
1111 GLint x, y, z;
1112 GLint red, green, blue, alpha;
1113 GLfloat s, t, u;
1114 GLfloat s1, t1, u1;
1115 GLfloat dsize = psize * dist[i];
1116
1117 if (dsize >= ctx->Point.Threshold) {
1118 radius = MIN2(dsize, ctx->Point.MaxSize) * 0.5F;
1119 alphaf = 1.0F;
1120 }
1121 else {
1122 radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F);
1123 dsize /= ctx->Point.Threshold;
1124 alphaf = (dsize*dsize);
1125 }
1126 rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
1127 rmax = radius + 0.7071F;
1128 rmin2 = MAX2(0.0, rmin * rmin);
1129 rmax2 = rmax * rmax;
1130 cscale = 256.0F / (rmax2 - rmin2);
1131
1132 xmin = (GLint) (VB->Win.data[i][0] - radius);
1133 xmax = (GLint) (VB->Win.data[i][0] + radius);
1134 ymin = (GLint) (VB->Win.data[i][1] - radius);
1135 ymax = (GLint) (VB->Win.data[i][1] + radius);
1136 z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
1137
1138 red = VB->ColorPtr->data[i][0];
1139 green = VB->ColorPtr->data[i][1];
1140 blue = VB->ColorPtr->data[i][2];
1141
1142 switch (VB->TexCoordPtr[0]->size) {
1143 case 4:
1144 s = (VB->TexCoordPtr[0]->data[i][0]/
1145 VB->TexCoordPtr[0]->data[i][3]);
1146 t = (VB->TexCoordPtr[0]->data[i][1]/
1147 VB->TexCoordPtr[0]->data[i][3]);
1148 u = (VB->TexCoordPtr[0]->data[i][2]/
1149 VB->TexCoordPtr[0]->data[i][3]);
1150 break;
1151 case 3:
1152 s = VB->TexCoordPtr[0]->data[i][0];
1153 t = VB->TexCoordPtr[0]->data[i][1];
1154 u = VB->TexCoordPtr[0]->data[i][2];
1155 break;
1156 case 2:
1157 s = VB->TexCoordPtr[0]->data[i][0];
1158 t = VB->TexCoordPtr[0]->data[i][1];
1159 u = 0.0;
1160 break;
1161 case 1:
1162 s = VB->TexCoordPtr[0]->data[i][0];
1163 t = 0.0;
1164 u = 0.0;
1165 break;
1166 default:
1167 /* should never get here */
1168 s = t = u = 0.0;
1169 gl_problem(ctx, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1170 }
1171
1172 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
1173 /* Multitextured! This is probably a slow enough path that
1174 there's no reason to specialize the multitexture case. */
1175 switch (VB->TexCoordPtr[1]->size) {
1176 case 4:
1177 s1 = ( VB->TexCoordPtr[1]->data[i][0] /
1178 VB->TexCoordPtr[1]->data[i][3] );
1179 t1 = ( VB->TexCoordPtr[1]->data[i][1] /
1180 VB->TexCoordPtr[1]->data[i][3] );
1181 u1 = ( VB->TexCoordPtr[1]->data[i][2] /
1182 VB->TexCoordPtr[1]->data[i][3] );
1183 break;
1184 case 3:
1185 s1 = VB->TexCoordPtr[1]->data[i][0];
1186 t1 = VB->TexCoordPtr[1]->data[i][1];
1187 u1 = VB->TexCoordPtr[1]->data[i][2];
1188 break;
1189 case 2:
1190 s1 = VB->TexCoordPtr[1]->data[i][0];
1191 t1 = VB->TexCoordPtr[1]->data[i][1];
1192 u1 = 0.0;
1193 break;
1194 case 1:
1195 s1 = VB->TexCoordPtr[1]->data[i][0];
1196 t1 = 0.0;
1197 u1 = 0.0;
1198 break;
1199 default:
1200 /* should never get here */
1201 s = t = u = 0.0;
1202 gl_problem(ctx, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1203 }
1204 }
1205
1206 for (y = ymin; y <= ymax; y++) {
1207 for (x = xmin; x <= xmax; x++) {
1208 const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
1209 const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
1210 const GLfloat dist2 = dx*dx + dy*dy;
1211 if (dist2 < rmax2) {
1212 alpha = VB->ColorPtr->data[i][3];
1213 if (dist2 >= rmin2) {
1214 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
1215 /* coverage is in [0,256] */
1216 alpha = (alpha * coverage) >> 8;
1217 }
1218 alpha = (GLint) (alpha * alphaf);
1219 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
1220 PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, red, green, blue,
1221 alpha, s, t, u, s1, t1, u1 );
1222 } else {
1223 PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha,
1224 s, t, u );
1225 }
1226 }
1227 }
1228 }
1229 PB_CHECK_FLUSH(ctx,PB);
1230 }
1231 }
1232 }
1233 else {
1234 /* Not texture mapped */
1235 for (i = first; i <= last; i++) {
1236 if (VB->ClipMask[i] == 0) {
1237 GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaf;
1238 GLint xmin, ymin, xmax, ymax;
1239 GLint x, y, z;
1240 GLint red, green, blue, alpha;
1241 GLfloat dsize = psize * dist[i];
1242
1243 if (dsize >= ctx->Point.Threshold) {
1244 radius = MIN2(dsize, ctx->Point.MaxSize) * 0.5F;
1245 alphaf = 1.0F;
1246 }
1247 else {
1248 radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F);
1249 dsize /= ctx->Point.Threshold;
1250 alphaf = dsize * dsize;
1251 }
1252 rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
1253 rmax = radius + 0.7071F;
1254 rmin2 = MAX2(0.0, rmin * rmin);
1255 rmax2 = rmax * rmax;
1256 cscale = 256.0F / (rmax2 - rmin2);
1257
1258 xmin = (GLint) (VB->Win.data[i][0] - radius);
1259 xmax = (GLint) (VB->Win.data[i][0] + radius);
1260 ymin = (GLint) (VB->Win.data[i][1] - radius);
1261 ymax = (GLint) (VB->Win.data[i][1] + radius);
1262 z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
1263
1264 red = VB->ColorPtr->data[i][0];
1265 green = VB->ColorPtr->data[i][1];
1266 blue = VB->ColorPtr->data[i][2];
1267
1268 for (y = ymin; y <= ymax; y++) {
1269 for (x = xmin; x <= xmax; x++) {
1270 const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
1271 const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
1272 const GLfloat dist2 = dx * dx + dy * dy;
1273 if (dist2 < rmax2) {
1274 alpha = VB->ColorPtr->data[i][3];
1275 if (dist2 >= rmin2) {
1276 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
1277 /* coverage is in [0,256] */
1278 alpha = (alpha * coverage) >> 8;
1279 }
1280 alpha = (GLint) (alpha * alphaf);
1281 PB_WRITE_RGBA_PIXEL(PB, x, y, z, red, green, blue, alpha);
1282 }
1283 }
1284 }
1285 PB_CHECK_FLUSH(ctx,PB);
1286 }
1287 }
1288 }
1289 }
1290
1291
1292 #ifdef DEBUG
1293 void
1294 _mesa_print_points_function(GLcontext *ctx)
1295 {
1296 printf("Point Func == ");
1297 if (ctx->Driver.PointsFunc == size1_ci_points)
1298 printf("size1_ci_points\n");
1299 else if (ctx->Driver.PointsFunc == size1_rgba_points)
1300 printf("size1_rgba_points\n");
1301 else if (ctx->Driver.PointsFunc == general_ci_points)
1302 printf("general_ci_points\n");
1303 else if (ctx->Driver.PointsFunc == general_rgba_points)
1304 printf("general_rgba_points\n");
1305 else if (ctx->Driver.PointsFunc == textured_rgba_points)
1306 printf("textured_rgba_points\n");
1307 else if (ctx->Driver.PointsFunc == multitextured_rgba_points)
1308 printf("multitextured_rgba_points\n");
1309 else if (ctx->Driver.PointsFunc == antialiased_rgba_points)
1310 printf("antialiased_rgba_points\n");
1311 else if (ctx->Driver.PointsFunc == null_points)
1312 printf("null_points\n");
1313 else if (ctx->Driver.PointsFunc == dist_atten_general_ci_points)
1314 printf("dist_atten_general_ci_points\n");
1315 else if (ctx->Driver.PointsFunc == dist_atten_general_rgba_points)
1316 printf("dist_atten_general_rgba_points\n");
1317 else if (ctx->Driver.PointsFunc == dist_atten_textured_rgba_points)
1318 printf("dist_atten_textured_rgba_points\n");
1319 else if (ctx->Driver.PointsFunc == dist_atten_antialiased_rgba_points)
1320 printf("dist_atten_antialiased_rgba_points\n");
1321 else if (!ctx->Driver.PointsFunc)
1322 printf("NULL\n");
1323 else
1324 printf("Driver func %p\n", ctx->Driver.PointsFunc);
1325 }
1326 #endif
1327
1328
1329 /*
1330 * Examine the current context to determine which point drawing function
1331 * should be used.
1332 */
1333 void gl_set_point_function( GLcontext *ctx )
1334 {
1335 GLboolean rgbmode = ctx->Visual->RGBAflag;
1336
1337 if (ctx->RenderMode==GL_RENDER) {
1338 if (ctx->NoRaster) {
1339 ctx->Driver.PointsFunc = null_points;
1340 return;
1341 }
1342 if (ctx->Driver.PointsFunc) {
1343 /* Device driver will draw points. */
1344 ctx->IndirectTriangles &= ~DD_POINT_SW_RASTERIZE;
1345 return;
1346 }
1347
1348 if (!ctx->Point.Attenuated) {
1349 if (ctx->Point.SmoothFlag && rgbmode) {
1350 ctx->Driver.PointsFunc = antialiased_rgba_points;
1351 }
1352 else if (ctx->Texture.ReallyEnabled) {
1353 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D ||
1354 ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
1355 ctx->Driver.PointsFunc = multitextured_rgba_points;
1356 }
1357 else {
1358 ctx->Driver.PointsFunc = textured_rgba_points;
1359 }
1360 }
1361 else if (ctx->Point.Size==1.0) {
1362 /* size=1, any raster ops */
1363 if (rgbmode)
1364 ctx->Driver.PointsFunc = size1_rgba_points;
1365 else
1366 ctx->Driver.PointsFunc = size1_ci_points;
1367 }
1368 else {
1369 /* every other kind of point rendering */
1370 if (rgbmode)
1371 ctx->Driver.PointsFunc = general_rgba_points;
1372 else
1373 ctx->Driver.PointsFunc = general_ci_points;
1374 }
1375 }
1376 else if(ctx->Point.SmoothFlag && rgbmode) {
1377 ctx->Driver.PointsFunc = dist_atten_antialiased_rgba_points;
1378 }
1379 else if (ctx->Texture.ReallyEnabled) {
1380 ctx->Driver.PointsFunc = dist_atten_textured_rgba_points;
1381 }
1382 else {
1383 /* every other kind of point rendering */
1384 if (rgbmode)
1385 ctx->Driver.PointsFunc = dist_atten_general_rgba_points;
1386 else
1387 ctx->Driver.PointsFunc = dist_atten_general_ci_points;
1388 }
1389 }
1390 else if (ctx->RenderMode==GL_FEEDBACK) {
1391 ctx->Driver.PointsFunc = gl_feedback_points;
1392 }
1393 else {
1394 /* GL_SELECT mode */
1395 ctx->Driver.PointsFunc = gl_select_points;
1396 }
1397
1398 /*_mesa_print_points_function(ctx);*/
1399 }
1400