Basic work to support deep color channels:
[mesa.git] / src / mesa / main / points.c
1 /* $Id: points.c,v 1.17 2000/10/28 18:34:48 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.4
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, *fog;
157 GLint *pbx = PB->x, *pby = PB->y;
158 GLdepth *pbz = PB->z;
159 GLfixed *pbfog = PB->fog;
160 GLuint *pbi = PB->index;
161 GLuint pbcount = PB->count;
162 GLuint i;
163
164 win = &VB->Win.data[first][0];
165 fog = &VB->FogCoordPtr->data[first];
166
167 for (i = first; i <= last; i++) {
168 if (VB->ClipMask[i] == 0) {
169 pbx[pbcount] = (GLint) win[0];
170 pby[pbcount] = (GLint) win[1];
171 pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
172 pbfog[pbcount] = FloatToFixed(fog[i]);
173 pbi[pbcount] = VB->IndexPtr->data[i];
174 pbcount++;
175 }
176 win += 3;
177 }
178 PB->count = pbcount;
179 PB_CHECK_FLUSH(ctx, PB);
180 }
181
182
183
184 /*
185 * RGBA points with size == 1.0
186 */
187 static void
188 size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
189 {
190 struct vertex_buffer *VB = ctx->VB;
191 struct pixel_buffer *PB = ctx->PB;
192 GLuint i;
193
194 for (i = first; i <= last; i++) {
195 if (VB->ClipMask[i] == 0) {
196 GLint x, y, z;
197 GLint fog;
198 GLint red, green, blue, alpha;
199
200 x = (GLint) VB->Win.data[i][0];
201 y = (GLint) VB->Win.data[i][1];
202 z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
203
204 fog = FloatToFixed( VB->FogCoordPtr->data[i] );
205
206 red = VB->ColorPtr->data[i][0];
207 green = VB->ColorPtr->data[i][1];
208 blue = VB->ColorPtr->data[i][2];
209 alpha = VB->ColorPtr->data[i][3];
210
211 PB_WRITE_RGBA_PIXEL( PB, x, y, z, fog, red, green, blue, alpha );
212 }
213 }
214 PB_CHECK_FLUSH(ctx, PB);
215 }
216
217
218
219 /*
220 * General CI points.
221 */
222 static void
223 general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
224 {
225 struct vertex_buffer *VB = ctx->VB;
226 struct pixel_buffer *PB = ctx->PB;
227 const GLint isize = (GLint) (ctx->Point.Size + 0.5F);
228 GLint radius = isize >> 1;
229 GLuint i;
230
231 for (i = first; i <= last; i++) {
232 if (VB->ClipMask[i] == 0) {
233 GLint x0, x1, y0, y1;
234 GLint ix, iy;
235
236 GLint x = (GLint) VB->Win.data[i][0];
237 GLint y = (GLint) VB->Win.data[i][1];
238 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
239
240 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
241
242 if (isize & 1) {
243 /* odd size */
244 x0 = x - radius;
245 x1 = x + radius;
246 y0 = y - radius;
247 y1 = y + radius;
248 }
249 else {
250 /* even size */
251 x0 = (GLint) (x + 1.5F) - radius;
252 x1 = x0 + isize - 1;
253 y0 = (GLint) (y + 1.5F) - radius;
254 y1 = y0 + isize - 1;
255 }
256
257 PB_SET_INDEX( PB, VB->IndexPtr->data[i] );
258
259 for (iy = y0; iy <= y1; iy++) {
260 for (ix = x0; ix <= x1; ix++) {
261 PB_WRITE_PIXEL( PB, ix, iy, z, fog );
262 }
263 }
264 PB_CHECK_FLUSH(ctx,PB);
265 }
266 }
267 }
268
269
270 /*
271 * General RGBA points.
272 */
273 static void
274 general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
275 {
276 struct vertex_buffer *VB = ctx->VB;
277 struct pixel_buffer *PB = ctx->PB;
278 GLint isize = (GLint) (ctx->Point.Size + 0.5F);
279 GLint radius = isize >> 1;
280 GLuint i;
281
282 for (i = first; i <= last; i++) {
283 if (VB->ClipMask[i] == 0) {
284 GLint x0, x1, y0, y1;
285 GLint ix, iy;
286
287 GLint x = (GLint) VB->Win.data[i][0];
288 GLint y = (GLint) VB->Win.data[i][1];
289 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
290
291 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
292
293 if (isize & 1) {
294 /* odd size */
295 x0 = x - radius;
296 x1 = x + radius;
297 y0 = y - radius;
298 y1 = y + radius;
299 }
300 else {
301 /* even size */
302 x0 = (GLint) (x + 1.5F) - radius;
303 x1 = x0 + isize - 1;
304 y0 = (GLint) (y + 1.5F) - radius;
305 y1 = y0 + isize - 1;
306 }
307
308 PB_SET_COLOR( PB,
309 VB->ColorPtr->data[i][0],
310 VB->ColorPtr->data[i][1],
311 VB->ColorPtr->data[i][2],
312 VB->ColorPtr->data[i][3] );
313
314 for (iy = y0; iy <= y1; iy++) {
315 for (ix = x0; ix <= x1; ix++) {
316 PB_WRITE_PIXEL( PB, ix, iy, z, fog );
317 }
318 }
319 PB_CHECK_FLUSH(ctx,PB);
320 }
321 }
322 }
323
324
325
326
327 /*
328 * Textured RGBA points.
329 */
330 static void
331 textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
332 {
333 struct vertex_buffer *VB = ctx->VB;
334 struct pixel_buffer *PB = ctx->PB;
335 GLuint i;
336
337 for (i = first; i <= last; i++) {
338 if (VB->ClipMask[i] == 0) {
339 GLint x0, x1, y0, y1;
340 GLint ix, iy, radius;
341 GLint red, green, blue, alpha;
342 GLfloat s, t, u;
343
344 GLint x = (GLint) VB->Win.data[i][0];
345 GLint y = (GLint) VB->Win.data[i][1];
346 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
347 GLint isize = (GLint) (ctx->Point.Size + 0.5F);
348
349 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
350
351 if (isize < 1) {
352 isize = 1;
353 }
354 radius = isize >> 1;
355
356 if (isize & 1) {
357 /* odd size */
358 x0 = x - radius;
359 x1 = x + radius;
360 y0 = y - radius;
361 y1 = y + radius;
362 }
363 else {
364 /* even size */
365 x0 = (GLint) (x + 1.5F) - radius;
366 x1 = x0 + isize - 1;
367 y0 = (GLint) (y + 1.5F) - radius;
368 y1 = y0 + isize - 1;
369 }
370
371 red = VB->ColorPtr->data[i][0];
372 green = VB->ColorPtr->data[i][1];
373 blue = VB->ColorPtr->data[i][2];
374 alpha = VB->ColorPtr->data[i][3];
375
376 switch (VB->TexCoordPtr[0]->size) {
377 case 4:
378 s = VB->TexCoordPtr[0]->data[i][0]/VB->TexCoordPtr[0]->data[i][3];
379 t = VB->TexCoordPtr[0]->data[i][1]/VB->TexCoordPtr[0]->data[i][3];
380 u = VB->TexCoordPtr[0]->data[i][2]/VB->TexCoordPtr[0]->data[i][3];
381 break;
382 case 3:
383 s = VB->TexCoordPtr[0]->data[i][0];
384 t = VB->TexCoordPtr[0]->data[i][1];
385 u = VB->TexCoordPtr[0]->data[i][2];
386 break;
387 case 2:
388 s = VB->TexCoordPtr[0]->data[i][0];
389 t = VB->TexCoordPtr[0]->data[i][1];
390 u = 0.0;
391 break;
392 case 1:
393 s = VB->TexCoordPtr[0]->data[i][0];
394 t = 0.0;
395 u = 0.0;
396 break;
397 default:
398 /* should never get here */
399 s = t = u = 0.0;
400 gl_problem(ctx, "unexpected texcoord size in textured_rgba_points()");
401 }
402
403 for (iy = y0; iy <= y1; iy++) {
404 for (ix = x0; ix <= x1; ix++) {
405 PB_WRITE_TEX_PIXEL( PB, ix, iy, z, fog, red, green, blue, alpha,
406 s, t, u );
407 }
408 }
409
410 PB_CHECK_FLUSH(ctx, PB);
411 }
412 }
413 }
414
415
416 /*
417 * Multitextured RGBA points.
418 */
419 static void
420 multitextured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
421 {
422 struct vertex_buffer *VB = ctx->VB;
423 struct pixel_buffer *PB = ctx->PB;
424 GLuint i;
425
426 for (i = first; i <= last; i++) {
427 if (VB->ClipMask[i] == 0) {
428 const GLint red = VB->ColorPtr->data[i][0];
429 const GLint green = VB->ColorPtr->data[i][1];
430 const GLint blue = VB->ColorPtr->data[i][2];
431 const GLint alpha = VB->ColorPtr->data[i][3];
432 const GLint sRed = VB->SecondaryColorPtr->data ? VB->SecondaryColorPtr->data[i][0] : 0;
433 const GLint sGreen = VB->SecondaryColorPtr->data ? VB->SecondaryColorPtr->data[i][1] : 0;
434 const GLint sBlue = VB->SecondaryColorPtr->data ? VB->SecondaryColorPtr->data[i][2] : 0;
435 const GLint x = (GLint) VB->Win.data[i][0];
436 const GLint y = (GLint) VB->Win.data[i][1];
437 const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
438 GLint x0, x1, y0, y1;
439 GLint ix, iy;
440 GLfloat texcoord[MAX_TEXTURE_UNITS][4];
441 GLint radius, u;
442 GLint isize = (GLint) (ctx->Point.Size + 0.5F);
443
444 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
445
446 if (isize < 1) {
447 isize = 1;
448 }
449 radius = isize >> 1;
450
451 if (isize & 1) {
452 /* odd size */
453 x0 = x - radius;
454 x1 = x + radius;
455 y0 = y - radius;
456 y1 = y + radius;
457 }
458 else {
459 /* even size */
460 x0 = (GLint) (x + 1.5F) - radius;
461 x1 = x0 + isize - 1;
462 y0 = (GLint) (y + 1.5F) - radius;
463 y1 = y0 + isize - 1;
464 }
465
466 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
467 if (ctx->Texture.Unit[u].ReallyEnabled) {
468 switch (VB->TexCoordPtr[0]->size) {
469 case 4:
470 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
471 VB->TexCoordPtr[u]->data[i][3];
472 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
473 VB->TexCoordPtr[u]->data[i][3];
474 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
475 VB->TexCoordPtr[u]->data[i][3];
476 break;
477 case 3:
478 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
479 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
480 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
481 break;
482 case 2:
483 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
484 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
485 texcoord[u][2] = 0.0;
486 break;
487 case 1:
488 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
489 texcoord[u][1] = 0.0;
490 texcoord[u][2] = 0.0;
491 break;
492 default:
493 /* should never get here */
494 gl_problem(ctx, "unexpected texcoord size");
495 }
496 }
497 }
498
499 for (iy = y0; iy <= y1; iy++) {
500 for (ix = x0; ix <= x1; ix++) {
501 PB_WRITE_MULTITEX_SPEC_PIXEL( PB, ix, iy, z, fog,
502 red, green, blue, alpha,
503 sRed, sGreen, sBlue,
504 texcoord );
505 }
506 }
507 PB_CHECK_FLUSH(ctx, PB);
508 }
509 }
510 }
511
512
513 /*
514 * NOTES on aa point rasterization:
515 *
516 * Let d = distance of fragment center from vertex.
517 * if d < rmin2 then
518 * fragment has 100% coverage
519 * else if d > rmax2 then
520 * fragment has 0% coverage
521 * else
522 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
523 */
524
525
526 /*
527 * Antialiased points with or without texture mapping.
528 */
529 static void
530 antialiased_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
531 {
532 struct vertex_buffer *VB = ctx->VB;
533 struct pixel_buffer *PB = ctx->PB;
534 const GLfloat radius = ctx->Point.Size * 0.5F;
535 const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
536 const GLfloat rmax = radius + 0.7071F;
537 const GLfloat rmin2 = MAX2(0.0, rmin * rmin);
538 const GLfloat rmax2 = rmax * rmax;
539 const GLfloat cscale = 256.0F / (rmax2 - rmin2);
540 GLuint i;
541
542 if (ctx->Texture.ReallyEnabled) {
543 for (i = first; i <= last; i++) {
544 if (VB->ClipMask[i] == 0) {
545 GLint x, y;
546 GLfloat vx = VB->Win.data[i][0];
547 GLfloat vy = VB->Win.data[i][1];
548 const GLint xmin = (GLint) (vx - radius);
549 const GLint xmax = (GLint) (vx + radius);
550 const GLint ymin = (GLint) (vy - radius);
551 const GLint ymax = (GLint) (vy + radius);
552 const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
553 const GLint red = VB->ColorPtr->data[i][0];
554 const GLint green = VB->ColorPtr->data[i][1];
555 const GLint blue = VB->ColorPtr->data[i][2];
556 GLfloat texcoord[MAX_TEXTURE_UNITS][4];
557 GLint u, alpha;
558
559 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
560
561 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
562 if (ctx->Texture.Unit[u].ReallyEnabled) {
563 switch (VB->TexCoordPtr[0]->size) {
564 case 4:
565 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
566 VB->TexCoordPtr[u]->data[i][3];
567 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
568 VB->TexCoordPtr[u]->data[i][3];
569 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
570 VB->TexCoordPtr[u]->data[i][3];
571 break;
572 case 3:
573 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
574 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
575 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
576 break;
577 case 2:
578 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
579 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
580 texcoord[u][2] = 0.0;
581 break;
582 case 1:
583 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
584 texcoord[u][1] = 0.0;
585 texcoord[u][2] = 0.0;
586 break;
587 default:
588 /* should never get here */
589 gl_problem(ctx, "unexpected texcoord size in antialiased_rgba_points()");
590 }
591 }
592 }
593
594 /* translate by a half pixel to simplify math below */
595 vx -= 0.5F;
596 vx -= 0.5F;
597
598 for (y = ymin; y <= ymax; y++) {
599 for (x = xmin; x <= xmax; x++) {
600 const GLfloat dx = x - vx;
601 const GLfloat dy = y - vy;
602 const GLfloat dist2 = dx*dx + dy*dy;
603 if (dist2 < rmax2) {
604 alpha = VB->ColorPtr->data[i][3];
605 if (dist2 >= rmin2) {
606 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
607 /* coverage is in [0,256] */
608 alpha = (alpha * coverage) >> 8;
609 }
610 if (ctx->Texture.MultiTextureEnabled) {
611 PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, fog,
612 red, green, blue,
613 alpha, texcoord );
614 }
615 else {
616 PB_WRITE_TEX_PIXEL( PB, x,y,z, fog,
617 red, green, blue, alpha,
618 texcoord[0][0],
619 texcoord[0][1],
620 texcoord[0][2] );
621 }
622 }
623 }
624 }
625
626 PB_CHECK_FLUSH(ctx,PB);
627 }
628 }
629 }
630 else {
631 /* Not texture mapped */
632 for (i=first;i<=last;i++) {
633 if (VB->ClipMask[i]==0) {
634 const GLint xmin = (GLint) (VB->Win.data[i][0] - 0.0 - radius);
635 const GLint xmax = (GLint) (VB->Win.data[i][0] - 0.0 + radius);
636 const GLint ymin = (GLint) (VB->Win.data[i][1] - 0.0 - radius);
637 const GLint ymax = (GLint) (VB->Win.data[i][1] - 0.0 + radius);
638 const GLint red = VB->ColorPtr->data[i][0];
639 const GLint green = VB->ColorPtr->data[i][1];
640 const GLint blue = VB->ColorPtr->data[i][2];
641 const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
642 GLint x, y;
643
644 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
645
646 /*
647 printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
648 printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
649 */
650 for (y = ymin; y <= ymax; y++) {
651 for (x = xmin; x <= xmax; x++) {
652 const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
653 const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
654 const GLfloat dist2 = dx*dx + dy*dy;
655 if (dist2 < rmax2) {
656 GLint alpha = VB->ColorPtr->data[i][3];
657 if (dist2 >= rmin2) {
658 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
659 /* coverage is in [0,256] */
660 alpha = (alpha * coverage) >> 8;
661 }
662 PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog,
663 red, green, blue, alpha);
664 }
665 }
666 }
667 PB_CHECK_FLUSH(ctx,PB);
668 }
669 }
670 }
671 }
672
673
674
675 /*
676 * Null rasterizer for measuring transformation speed.
677 */
678 static void
679 null_points( GLcontext *ctx, GLuint first, GLuint last )
680 {
681 (void) ctx;
682 (void) first;
683 (void) last;
684 }
685
686
687
688 /* Definition of the functions for GL_EXT_point_parameters */
689
690 /* Calculates the distance attenuation formula of a vector of points in
691 * eye space coordinates
692 */
693 static void
694 dist3(GLfloat *out, GLuint first, GLuint last,
695 const GLcontext *ctx, const GLvector4f *v)
696 {
697 GLuint stride = v->stride;
698 const GLfloat *p = VEC_ELT(v, GLfloat, first);
699 GLuint i;
700
701 for (i = first ; i <= last ; i++, STRIDE_F(p, stride) ) {
702 GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
703 out[i] = 1.0F / (ctx->Point.Params[0] +
704 dist * (ctx->Point.Params[1] +
705 dist * ctx->Point.Params[2]));
706 }
707 }
708
709
710 static void
711 dist2(GLfloat *out, GLuint first, GLuint last,
712 const GLcontext *ctx, const GLvector4f *v)
713 {
714 GLuint stride = v->stride;
715 const GLfloat *p = VEC_ELT(v, GLfloat, first);
716 GLuint i;
717
718 for (i = first ; i <= last ; i++, STRIDE_F(p, stride) ) {
719 GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]);
720 out[i] = 1.0F / (ctx->Point.Params[0] +
721 dist * (ctx->Point.Params[1] +
722 dist * ctx->Point.Params[2]));
723 }
724 }
725
726
727 typedef void (*dist_func)(GLfloat *out, GLuint first, GLuint last,
728 const GLcontext *ctx, const GLvector4f *v);
729
730
731 static dist_func eye_dist_tab[5] = {
732 0,
733 0,
734 dist2,
735 dist3,
736 dist3
737 };
738
739
740
741 /*
742 * Distance Attenuated General CI points.
743 */
744 static void
745 dist_atten_general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
746 {
747 struct vertex_buffer *VB = ctx->VB;
748 struct pixel_buffer *PB = ctx->PB;
749 GLfloat dist[VB_SIZE];
750 const GLfloat psize = ctx->Point.Size;
751 GLuint i;
752
753 ASSERT(ctx->NeedEyeCoords);
754 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
755
756
757 for (i=first;i<=last;i++) {
758 if (VB->ClipMask[i]==0) {
759 GLint x0, x1, y0, y1;
760 GLint ix, iy;
761 GLint isize, radius;
762 GLint x = (GLint) VB->Win.data[i][0];
763 GLint y = (GLint) VB->Win.data[i][1];
764 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
765 GLfloat dsize = psize * dist[i];
766
767 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
768
769 if (dsize >= ctx->Point.Threshold) {
770 isize = (GLint) (MIN2(dsize, ctx->Point.MaxSize) + 0.5F);
771 }
772 else {
773 isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F);
774 }
775 radius = isize >> 1;
776
777 if (isize & 1) {
778 /* odd size */
779 x0 = x - radius;
780 x1 = x + radius;
781 y0 = y - radius;
782 y1 = y + radius;
783 }
784 else {
785 /* even size */
786 x0 = (GLint) (x + 1.5F) - radius;
787 x1 = x0 + isize - 1;
788 y0 = (GLint) (y + 1.5F) - radius;
789 y1 = y0 + isize - 1;
790 }
791
792 PB_SET_INDEX( PB, VB->IndexPtr->data[i] );
793
794 for (iy=y0;iy<=y1;iy++) {
795 for (ix=x0;ix<=x1;ix++) {
796 PB_WRITE_PIXEL( PB, ix, iy, z, fog );
797 }
798 }
799 PB_CHECK_FLUSH(ctx,PB);
800 }
801 }
802 }
803
804 /*
805 * Distance Attenuated General RGBA points.
806 */
807 static void
808 dist_atten_general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
809 {
810 struct vertex_buffer *VB = ctx->VB;
811 struct pixel_buffer *PB = ctx->PB;
812 GLfloat dist[VB_SIZE];
813 const GLfloat psize = ctx->Point.Size;
814 GLuint i;
815
816 ASSERT (ctx->NeedEyeCoords);
817 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
818
819 for (i=first;i<=last;i++) {
820 if (VB->ClipMask[i]==0) {
821 GLint x0, x1, y0, y1;
822 GLint ix, iy;
823 GLint isize, radius;
824 GLint x = (GLint) VB->Win.data[i][0];
825 GLint y = (GLint) VB->Win.data[i][1];
826 GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
827 GLfloat dsize=psize*dist[i];
828 GLchan alpha;
829 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
830
831 if (dsize >= ctx->Point.Threshold) {
832 isize = (GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
833 alpha = VB->ColorPtr->data[i][3];
834 }
835 else {
836 isize = (GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
837 dsize /= ctx->Point.Threshold;
838 alpha = (GLint) (VB->ColorPtr->data[i][3]* (dsize*dsize));
839 }
840 radius = isize >> 1;
841
842 if (isize & 1) {
843 /* odd size */
844 x0 = x - radius;
845 x1 = x + radius;
846 y0 = y - radius;
847 y1 = y + radius;
848 }
849 else {
850 /* even size */
851 x0 = (GLint) (x + 1.5F) - radius;
852 x1 = x0 + isize - 1;
853 y0 = (GLint) (y + 1.5F) - radius;
854 y1 = y0 + isize - 1;
855 }
856
857 PB_SET_COLOR( PB,
858 VB->ColorPtr->data[i][0],
859 VB->ColorPtr->data[i][1],
860 VB->ColorPtr->data[i][2],
861 alpha );
862
863 for (iy = y0; iy <= y1; iy++) {
864 for (ix = x0; ix <= x1; ix++) {
865 PB_WRITE_PIXEL( PB, ix, iy, z, fog );
866 }
867 }
868 PB_CHECK_FLUSH(ctx,PB);
869 }
870 }
871 }
872
873 /*
874 * Distance Attenuated Textured RGBA points.
875 */
876 static void
877 dist_atten_textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
878 {
879 struct vertex_buffer *VB = ctx->VB;
880 struct pixel_buffer *PB = ctx->PB;
881 GLfloat dist[VB_SIZE];
882 const GLfloat psize = ctx->Point.Size;
883 GLuint i;
884
885 ASSERT(ctx->NeedEyeCoords);
886 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
887
888 for (i=first;i<=last;i++) {
889 if (VB->ClipMask[i]==0) {
890 const GLint x = (GLint) VB->Win.data[i][0];
891 const GLint y = (GLint) VB->Win.data[i][1];
892 const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
893 const GLint red = VB->ColorPtr->data[i][0];
894 const GLint green = VB->ColorPtr->data[i][1];
895 const GLint blue = VB->ColorPtr->data[i][2];
896 GLfloat texcoord[MAX_TEXTURE_UNITS][4];
897 GLint x0, x1, y0, y1;
898 GLint ix, iy, alpha, u;
899 GLint isize, radius;
900 GLfloat dsize = psize*dist[i];
901
902 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
903
904 /* compute point size and alpha */
905 if (dsize >= ctx->Point.Threshold) {
906 isize = (GLint) (MIN2(dsize, ctx->Point.MaxSize) + 0.5F);
907 alpha = VB->ColorPtr->data[i][3];
908 }
909 else {
910 isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F);
911 dsize /= ctx->Point.Threshold;
912 alpha = (GLint) (VB->ColorPtr->data[i][3] * (dsize * dsize));
913 }
914 if (isize < 1) {
915 isize = 1;
916 }
917 radius = isize >> 1;
918
919 if (isize & 1) {
920 /* odd size */
921 x0 = x - radius;
922 x1 = x + radius;
923 y0 = y - radius;
924 y1 = y + radius;
925 }
926 else {
927 /* even size */
928 x0 = (GLint) (x + 1.5F) - radius;
929 x1 = x0 + isize - 1;
930 y0 = (GLint) (y + 1.5F) - radius;
931 y1 = y0 + isize - 1;
932 }
933
934 /* get texture coordinates */
935 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
936 if (ctx->Texture.Unit[u].ReallyEnabled) {
937 switch (VB->TexCoordPtr[0]->size) {
938 case 4:
939 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
940 VB->TexCoordPtr[u]->data[i][3];
941 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
942 VB->TexCoordPtr[u]->data[i][3];
943 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
944 VB->TexCoordPtr[u]->data[i][3];
945 break;
946 case 3:
947 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
948 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
949 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
950 break;
951 case 2:
952 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
953 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
954 texcoord[u][2] = 0.0;
955 break;
956 case 1:
957 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
958 texcoord[u][1] = 0.0;
959 texcoord[u][2] = 0.0;
960 break;
961 default:
962 /* should never get here */
963 gl_problem(ctx, "unexpected texcoord size");
964 }
965 }
966 }
967
968 for (iy = y0; iy <= y1; iy++) {
969 for (ix = x0; ix <= x1; ix++) {
970 if (ctx->Texture.MultiTextureEnabled) {
971 PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, fog,
972 red, green, blue, alpha,
973 texcoord );
974 }
975 else {
976 PB_WRITE_TEX_PIXEL( PB, ix, iy, z, fog,
977 red, green, blue, alpha,
978 texcoord[0][0],
979 texcoord[0][1],
980 texcoord[0][2] );
981 }
982 }
983 }
984 PB_CHECK_FLUSH(ctx,PB);
985 }
986 }
987 }
988
989 /*
990 * Distance Attenuated Antialiased points with or without texture mapping.
991 */
992 static void
993 dist_atten_antialiased_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
994 {
995 struct vertex_buffer *VB = ctx->VB;
996 struct pixel_buffer *PB = ctx->PB;
997 GLfloat dist[VB_SIZE];
998 const GLfloat psize = ctx->Point.Size;
999 GLuint i;
1000
1001 ASSERT(ctx->NeedEyeCoords);
1002 (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
1003
1004 if (ctx->Texture.ReallyEnabled) {
1005 for (i=first;i<=last;i++) {
1006 if (VB->ClipMask[i]==0) {
1007 GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaf;
1008 GLint xmin, ymin, xmax, ymax;
1009 GLint x, y, z;
1010 GLint red, green, blue, alpha;
1011 GLfloat texcoord[MAX_TEXTURE_UNITS][4];
1012 GLfloat dsize = psize * dist[i];
1013 GLint u;
1014
1015 GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
1016
1017 if (dsize >= ctx->Point.Threshold) {
1018 radius = MIN2(dsize, ctx->Point.MaxSize) * 0.5F;
1019 alphaf = 1.0F;
1020 }
1021 else {
1022 radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F);
1023 dsize /= ctx->Point.Threshold;
1024 alphaf = (dsize*dsize);
1025 }
1026 rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
1027 rmax = radius + 0.7071F;
1028 rmin2 = MAX2(0.0, rmin * rmin);
1029 rmax2 = rmax * rmax;
1030 cscale = 256.0F / (rmax2 - rmin2);
1031
1032 xmin = (GLint) (VB->Win.data[i][0] - radius);
1033 xmax = (GLint) (VB->Win.data[i][0] + radius);
1034 ymin = (GLint) (VB->Win.data[i][1] - radius);
1035 ymax = (GLint) (VB->Win.data[i][1] + radius);
1036 z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
1037
1038 red = VB->ColorPtr->data[i][0];
1039 green = VB->ColorPtr->data[i][1];
1040 blue = VB->ColorPtr->data[i][2];
1041
1042 /* get texture coordinates */
1043 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1044 if (ctx->Texture.Unit[u].ReallyEnabled) {
1045 switch (VB->TexCoordPtr[0]->size) {
1046 case 4:
1047 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
1048 VB->TexCoordPtr[u]->data[i][3];
1049 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
1050 VB->TexCoordPtr[u]->data[i][3];
1051 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
1052 VB->TexCoordPtr[u]->data[i][3];
1053 break;
1054 case 3:
1055 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
1056 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
1057 texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
1058 break;
1059 case 2:
1060 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
1061 texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
1062 texcoord[u][2] = 0.0;
1063 break;
1064 case 1:
1065 texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
1066 texcoord[u][1] = 0.0;
1067 texcoord[u][2] = 0.0;
1068 break;
1069 default:
1070 /* should never get here */
1071 gl_problem(ctx, "unexpected texcoord size");
1072 }
1073 }
1074 }
1075
1076 for (y = ymin; y <= ymax; y++) {
1077 for (x = xmin; x <= xmax; x++) {
1078 const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
1079 const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
1080 const GLfloat dist2 = dx*dx + dy*dy;
1081 if (dist2 < rmax2) {
1082 alpha = VB->ColorPtr->data[i][3];
1083 if (dist2 >= rmin2) {
1084 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
1085 /* coverage is in [0,256] */
1086 alpha = (alpha * coverage) >> 8;
1087 }
1088 alpha = (GLint) (alpha * alphaf);
1089 if (ctx->Texture.MultiTextureEnabled) {
1090 PB_WRITE_MULTITEX_PIXEL( PB, x, y, z, fog,
1091 red, green, blue, alpha,
1092 texcoord );
1093 }
1094 else {
1095 PB_WRITE_TEX_PIXEL( PB, x,y,z, fog,
1096 red, green, blue, alpha,
1097 texcoord[0][0],
1098 texcoord[0][1],
1099 texcoord[0][2] );
1100 }
1101 }
1102 }
1103 }
1104 PB_CHECK_FLUSH(ctx,PB);
1105 }
1106 }
1107 }
1108 else {
1109 /* Not texture mapped */
1110 for (i = first; i <= last; i++) {
1111 if (VB->ClipMask[i] == 0) {
1112 GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaf;
1113 GLint xmin, ymin, xmax, ymax;
1114 GLint x, y, z;
1115 GLfixed fog;
1116 GLint red, green, blue, alpha;
1117 GLfloat dsize = psize * dist[i];
1118
1119 if (dsize >= ctx->Point.Threshold) {
1120 radius = MIN2(dsize, ctx->Point.MaxSize) * 0.5F;
1121 alphaf = 1.0F;
1122 }
1123 else {
1124 radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F);
1125 dsize /= ctx->Point.Threshold;
1126 alphaf = dsize * dsize;
1127 }
1128 rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
1129 rmax = radius + 0.7071F;
1130 rmin2 = MAX2(0.0, rmin * rmin);
1131 rmax2 = rmax * rmax;
1132 cscale = 256.0F / (rmax2 - rmin2);
1133
1134 xmin = (GLint) (VB->Win.data[i][0] - radius);
1135 xmax = (GLint) (VB->Win.data[i][0] + radius);
1136 ymin = (GLint) (VB->Win.data[i][1] - radius);
1137 ymax = (GLint) (VB->Win.data[i][1] + radius);
1138 z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
1139
1140 fog = FloatToFixed( VB->FogCoordPtr->data[i] );
1141
1142 red = VB->ColorPtr->data[i][0];
1143 green = VB->ColorPtr->data[i][1];
1144 blue = VB->ColorPtr->data[i][2];
1145
1146 for (y = ymin; y <= ymax; y++) {
1147 for (x = xmin; x <= xmax; x++) {
1148 const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
1149 const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
1150 const GLfloat dist2 = dx * dx + dy * dy;
1151 if (dist2 < rmax2) {
1152 alpha = VB->ColorPtr->data[i][3];
1153 if (dist2 >= rmin2) {
1154 GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
1155 /* coverage is in [0,256] */
1156 alpha = (alpha * coverage) >> 8;
1157 }
1158 alpha = (GLint) (alpha * alphaf);
1159 PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog,
1160 red, green, blue, alpha);
1161 }
1162 }
1163 }
1164 PB_CHECK_FLUSH(ctx,PB);
1165 }
1166 }
1167 }
1168 }
1169
1170
1171 #ifdef DEBUG
1172 void
1173 _mesa_print_points_function(GLcontext *ctx)
1174 {
1175 printf("Point Func == ");
1176 if (ctx->Driver.PointsFunc == size1_ci_points)
1177 printf("size1_ci_points\n");
1178 else if (ctx->Driver.PointsFunc == size1_rgba_points)
1179 printf("size1_rgba_points\n");
1180 else if (ctx->Driver.PointsFunc == general_ci_points)
1181 printf("general_ci_points\n");
1182 else if (ctx->Driver.PointsFunc == general_rgba_points)
1183 printf("general_rgba_points\n");
1184 else if (ctx->Driver.PointsFunc == textured_rgba_points)
1185 printf("textured_rgba_points\n");
1186 else if (ctx->Driver.PointsFunc == multitextured_rgba_points)
1187 printf("multitextured_rgba_points\n");
1188 else if (ctx->Driver.PointsFunc == antialiased_rgba_points)
1189 printf("antialiased_rgba_points\n");
1190 else if (ctx->Driver.PointsFunc == null_points)
1191 printf("null_points\n");
1192 else if (ctx->Driver.PointsFunc == dist_atten_general_ci_points)
1193 printf("dist_atten_general_ci_points\n");
1194 else if (ctx->Driver.PointsFunc == dist_atten_general_rgba_points)
1195 printf("dist_atten_general_rgba_points\n");
1196 else if (ctx->Driver.PointsFunc == dist_atten_textured_rgba_points)
1197 printf("dist_atten_textured_rgba_points\n");
1198 else if (ctx->Driver.PointsFunc == dist_atten_antialiased_rgba_points)
1199 printf("dist_atten_antialiased_rgba_points\n");
1200 else if (!ctx->Driver.PointsFunc)
1201 printf("NULL\n");
1202 else
1203 printf("Driver func %p\n", ctx->Driver.PointsFunc);
1204 }
1205 #endif
1206
1207
1208 /*
1209 * Examine the current context to determine which point drawing function
1210 * should be used.
1211 */
1212 void gl_set_point_function( GLcontext *ctx )
1213 {
1214 GLboolean rgbmode = ctx->Visual.RGBAflag;
1215
1216 if (ctx->RenderMode==GL_RENDER) {
1217 if (ctx->NoRaster) {
1218 ctx->Driver.PointsFunc = null_points;
1219 return;
1220 }
1221 if (ctx->Driver.PointsFunc) {
1222 /* Device driver will draw points. */
1223 ctx->IndirectTriangles &= ~DD_POINT_SW_RASTERIZE;
1224 return;
1225 }
1226
1227 if (!ctx->Point.Attenuated) {
1228 if (ctx->Point.SmoothFlag && rgbmode) {
1229 ctx->Driver.PointsFunc = antialiased_rgba_points;
1230 }
1231 else if (ctx->Texture.ReallyEnabled) {
1232 if (ctx->Texture.MultiTextureEnabled ||
1233 ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR ||
1234 ctx->Fog.ColorSumEnabled) {
1235 ctx->Driver.PointsFunc = multitextured_rgba_points;
1236 }
1237 else {
1238 ctx->Driver.PointsFunc = textured_rgba_points;
1239 }
1240 }
1241 else if (ctx->Point.Size==1.0) {
1242 /* size=1, any raster ops */
1243 if (rgbmode)
1244 ctx->Driver.PointsFunc = size1_rgba_points;
1245 else
1246 ctx->Driver.PointsFunc = size1_ci_points;
1247 }
1248 else {
1249 /* every other kind of point rendering */
1250 if (rgbmode)
1251 ctx->Driver.PointsFunc = general_rgba_points;
1252 else
1253 ctx->Driver.PointsFunc = general_ci_points;
1254 }
1255 }
1256 else if(ctx->Point.SmoothFlag && rgbmode) {
1257 ctx->Driver.PointsFunc = dist_atten_antialiased_rgba_points;
1258 }
1259 else if (ctx->Texture.ReallyEnabled) {
1260 ctx->Driver.PointsFunc = dist_atten_textured_rgba_points;
1261 }
1262 else {
1263 /* every other kind of point rendering */
1264 if (rgbmode)
1265 ctx->Driver.PointsFunc = dist_atten_general_rgba_points;
1266 else
1267 ctx->Driver.PointsFunc = dist_atten_general_ci_points;
1268 }
1269 }
1270 else if (ctx->RenderMode==GL_FEEDBACK) {
1271 ctx->Driver.PointsFunc = gl_feedback_points;
1272 }
1273 else {
1274 /* GL_SELECT mode */
1275 ctx->Driver.PointsFunc = gl_select_points;
1276 }
1277
1278 /*_mesa_print_points_function(ctx);*/
1279 }
1280