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