[OPENGL32][MESA] Downgrade Mesa library to version 2.6
[reactos.git] / dll / opengl / mesa / points.c
1 /* $Id: points.c,v 1.15 1998/02/03 23:46:00 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 2.5
6 * Copyright (C) 1995-1997 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24 /*
25 * $Log: points.c,v $
26 * Revision 1.15 1998/02/03 23:46:00 brianp
27 * fixed a few problems with condition expressions for Amiga StormC compiler
28 *
29 * Revision 1.14 1997/10/29 01:29:09 brianp
30 * added GL_EXT_point_parameters extension from Daniel Barrero
31 *
32 * Revision 1.13 1997/07/24 01:23:44 brianp
33 * changed precompiled header symbol from PCH to PC_HEADER
34 *
35 * Revision 1.12 1997/06/20 02:50:39 brianp
36 * changed color components from GLfixed to GLubyte
37 *
38 * Revision 1.11 1997/05/28 03:26:02 brianp
39 * added precompiled header (PCH) support
40 *
41 * Revision 1.10 1997/05/03 00:51:02 brianp
42 * removed calls to gl_texturing_enabled()
43 *
44 * Revision 1.9 1997/04/14 02:00:39 brianp
45 * #include "texstate.h" instead of "texture.h"
46 *
47 * Revision 1.8 1997/04/12 12:24:43 brianp
48 * replaced ctx->PointsFunc with ctx->Driver.PointsFunc
49 *
50 * Revision 1.7 1997/04/02 03:11:38 brianp
51 * replaced VB->Unclipped with VB->ClipMask
52 *
53 * Revision 1.6 1997/03/08 02:04:27 brianp
54 * better implementation of feedback function
55 *
56 * Revision 1.5 1997/02/09 18:43:52 brianp
57 * added GL_EXT_texture3D support
58 *
59 * Revision 1.4 1997/01/09 19:48:00 brianp
60 * now call gl_texturing_enabled()
61 *
62 * Revision 1.3 1996/11/08 02:21:21 brianp
63 * added null drawing function for GL_NO_RASTER
64 *
65 * Revision 1.2 1996/09/15 14:18:37 brianp
66 * now use GLframebuffer and GLvisual
67 *
68 * Revision 1.1 1996/09/13 01:38:16 brianp
69 * Initial revision
70 *
71 */
72
73
74 #ifdef PC_HEADER
75 #include "all.h"
76 #else
77 #include "context.h"
78 #include "feedback.h"
79 #include "dlist.h"
80 #include "macros.h"
81 #include "pb.h"
82 #include "span.h"
83 #include "texstate.h"
84 #include "types.h"
85 #include "vb.h"
86 #include "mmath.h"
87 #endif
88
89
90
91 void gl_PointSize( GLcontext *ctx, GLfloat size )
92 {
93 if (size<=0.0) {
94 gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
95 return;
96 }
97 if (INSIDE_BEGIN_END(ctx)) {
98 gl_error( ctx, GL_INVALID_OPERATION, "glPointSize" );
99 return;
100 }
101 ctx->Point.Size = size;
102 ctx->NewState |= NEW_RASTER_OPS;
103 }
104
105
106 /**********************************************************************/
107 /***** Rasterization *****/
108 /**********************************************************************/
109
110
111 /*
112 * There are 3 pairs (RGBA, CI) of point rendering functions:
113 * 1. simple: size=1 and no special rasterization functions (fastest)
114 * 2. size1: size=1 and any rasterization functions
115 * 3. general: any size and rasterization functions (slowest)
116 *
117 * All point rendering functions take the same two arguments: first and
118 * last which specify that the points specified by VB[first] through
119 * VB[last] are to be rendered.
120 */
121
122
123
124 /*
125 * Put points in feedback buffer.
126 */
127 static void feedback_points( GLcontext *ctx, GLuint first, GLuint last )
128 {
129 struct vertex_buffer *VB = ctx->VB;
130 GLuint i;
131 GLfloat invRedScale = ctx->Visual->InvRedScale;
132 GLfloat invGreenScale = ctx->Visual->InvGreenScale;
133 GLfloat invBlueScale = ctx->Visual->InvBlueScale;
134 GLfloat invAlphaScale = ctx->Visual->InvAlphaScale;
135
136 for (i=first;i<=last;i++) {
137 if (VB->ClipMask[i]==0) {
138 GLfloat x, y, z, w, invq;
139 GLfloat color[4], texcoord[4];
140
141 x = VB->Win[i][0];
142 y = VB->Win[i][1];
143 z = VB->Win[i][2] / DEPTH_SCALE;
144 w = VB->Clip[i][3];
145
146 /* convert color from integer back to a float in [0,1] */
147 if (ctx->Light.ShadeModel==GL_SMOOTH) {
148 /* smooth shading - colors are in fixed point */
149 color[0] = FixedToFloat(VB->Color[i][0]) * invRedScale;
150 color[1] = FixedToFloat(VB->Color[i][1]) * invGreenScale;
151 color[2] = FixedToFloat(VB->Color[i][2]) * invBlueScale;
152 color[3] = FixedToFloat(VB->Color[i][3]) * invAlphaScale;
153 }
154 else {
155 /* flat shading - colors are integers */
156 color[0] = VB->Color[i][0] * invRedScale;
157 color[1] = VB->Color[i][1] * invGreenScale;
158 color[2] = VB->Color[i][2] * invBlueScale;
159 color[3] = VB->Color[i][3] * invAlphaScale;
160 }
161 invq = 1.0F / VB->TexCoord[i][3];
162 texcoord[0] = VB->TexCoord[i][0] * invq;
163 texcoord[1] = VB->TexCoord[i][1] * invq;
164 texcoord[2] = VB->TexCoord[i][2] * invq;
165 texcoord[3] = VB->TexCoord[i][3];
166
167 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
168 gl_feedback_vertex( ctx, x, y, z, w, color,
169 (GLfloat) VB->Index[i], texcoord );
170 }
171 }
172 }
173
174
175
176 /*
177 * Put points in selection buffer.
178 */
179 static void select_points( GLcontext *ctx, GLuint first, GLuint last )
180 {
181 struct vertex_buffer *VB = ctx->VB;
182 GLuint i;
183
184 for (i=first;i<=last;i++) {
185 if (VB->ClipMask[i]==0) {
186 gl_update_hitflag( ctx, VB->Win[i][2] / DEPTH_SCALE );
187 }
188 }
189 }
190
191
192 /*
193 * CI points with size == 1.0
194 */
195 void size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
196 {
197 struct vertex_buffer *VB = ctx->VB;
198 struct pixel_buffer *PB = ctx->PB;
199 GLfloat *win;
200 GLint *pbx = PB->x, *pby = PB->y;
201 GLdepth *pbz = PB->z;
202 GLuint *pbi = PB->i;
203 GLuint pbcount = PB->count;
204 GLuint i;
205
206 win = &VB->Win[first][0];
207 for (i=first;i<=last;i++) {
208 if (VB->ClipMask[i]==0) {
209 pbx[pbcount] = (GLint) win[0];
210 pby[pbcount] = (GLint) win[1];
211 pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
212 pbi[pbcount] = VB->Index[i];
213 pbcount++;
214 }
215 win += 3;
216 }
217 PB->count = pbcount;
218 PB_CHECK_FLUSH(ctx, PB)
219 }
220
221
222
223 /*
224 * RGBA points with size == 1.0
225 */
226 static void size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
227 {
228 struct vertex_buffer *VB = ctx->VB;
229 struct pixel_buffer *PB = ctx->PB;
230 GLuint i;
231
232 for (i=first;i<=last;i++) {
233 if (VB->ClipMask[i]==0) {
234 GLint x, y, z;
235 GLint red, green, blue, alpha;
236
237 x = (GLint) VB->Win[i][0];
238 y = (GLint) VB->Win[i][1];
239 z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
240
241 red = VB->Color[i][0];
242 green = VB->Color[i][1];
243 blue = VB->Color[i][2];
244 alpha = VB->Color[i][3];
245
246 PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
247 }
248 }
249 PB_CHECK_FLUSH(ctx,PB)
250 }
251
252
253
254 /*
255 * General CI points.
256 */
257 static void general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
258 {
259 struct vertex_buffer *VB = ctx->VB;
260 struct pixel_buffer *PB = ctx->PB;
261 GLuint i;
262 GLint isize;
263
264 isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
265
266 for (i=first;i<=last;i++) {
267 if (VB->ClipMask[i]==0) {
268 GLint x, y, z;
269 GLint x0, x1, y0, y1;
270 GLint ix, iy;
271
272 x = (GLint) VB->Win[i][0];
273 y = (GLint) VB->Win[i][1];
274 z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
275
276 if (isize&1) {
277 /* odd size */
278 x0 = x - isize/2;
279 x1 = x + isize/2;
280 y0 = y - isize/2;
281 y1 = y + isize/2;
282 }
283 else {
284 /* even size */
285 x0 = (GLint) (x + 0.5F) - isize/2;
286 x1 = x0 + isize-1;
287 y0 = (GLint) (y + 0.5F) - isize/2;
288 y1 = y0 + isize-1;
289 }
290
291 PB_SET_INDEX( ctx, PB, VB->Index[i] );
292
293 for (iy=y0;iy<=y1;iy++) {
294 for (ix=x0;ix<=x1;ix++) {
295 PB_WRITE_PIXEL( PB, ix, iy, z );
296 }
297 }
298 PB_CHECK_FLUSH(ctx,PB)
299 }
300 }
301 }
302
303
304 /*
305 * General RGBA points.
306 */
307 static void general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
308 {
309 struct vertex_buffer *VB = ctx->VB;
310 struct pixel_buffer *PB = ctx->PB;
311 GLuint i;
312 GLint isize;
313
314 isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
315
316 for (i=first;i<=last;i++) {
317 if (VB->ClipMask[i]==0) {
318 GLint x, y, z;
319 GLint x0, x1, y0, y1;
320 GLint ix, iy;
321
322 x = (GLint) VB->Win[i][0];
323 y = (GLint) VB->Win[i][1];
324 z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
325
326 if (isize&1) {
327 /* odd size */
328 x0 = x - isize/2;
329 x1 = x + isize/2;
330 y0 = y - isize/2;
331 y1 = y + isize/2;
332 }
333 else {
334 /* even size */
335 x0 = (GLint) (x + 0.5F) - isize/2;
336 x1 = x0 + isize-1;
337 y0 = (GLint) (y + 0.5F) - isize/2;
338 y1 = y0 + isize-1;
339 }
340
341 PB_SET_COLOR( ctx, PB,
342 VB->Color[i][0],
343 VB->Color[i][1],
344 VB->Color[i][2],
345 VB->Color[i][3] );
346
347 for (iy=y0;iy<=y1;iy++) {
348 for (ix=x0;ix<=x1;ix++) {
349 PB_WRITE_PIXEL( PB, ix, iy, z );
350 }
351 }
352 PB_CHECK_FLUSH(ctx,PB)
353 }
354 }
355 }
356
357
358
359
360 /*
361 * Textured RGBA points.
362 */
363 static void textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
364 {
365 struct vertex_buffer *VB = ctx->VB;
366 struct pixel_buffer *PB = ctx->PB;
367 GLuint i;
368
369 for (i=first;i<=last;i++) {
370 if (VB->ClipMask[i]==0) {
371 GLint x, y, z;
372 GLint x0, x1, y0, y1;
373 GLint ix, iy;
374 GLint isize;
375 GLint red, green, blue, alpha;
376 GLfloat s, t, u;
377
378 x = (GLint) VB->Win[i][0];
379 y = (GLint) VB->Win[i][1];
380 z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
381
382 isize = (GLint)
383 (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
384 if (isize<1) {
385 isize = 1;
386 }
387
388 if (isize&1) {
389 /* odd size */
390 x0 = x - isize/2;
391 x1 = x + isize/2;
392 y0 = y - isize/2;
393 y1 = y + isize/2;
394 }
395 else {
396 /* even size */
397 x0 = (GLint) (x + 0.5F) - isize/2;
398 x1 = x0 + isize-1;
399 y0 = (GLint) (y + 0.5F) - isize/2;
400 y1 = y0 + isize-1;
401 }
402
403 red = VB->Color[i][0];
404 green = VB->Color[i][1];
405 blue = VB->Color[i][2];
406 alpha = VB->Color[i][3];
407 s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
408 t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
409 u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
410
411 /* don't think this is needed
412 PB_SET_COLOR( red, green, blue, alpha );
413 */
414
415 for (iy=y0;iy<=y1;iy++) {
416 for (ix=x0;ix<=x1;ix++) {
417 PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
418 }
419 }
420 PB_CHECK_FLUSH(ctx,PB)
421 }
422 }
423 }
424
425
426
427 /*
428 * Antialiased points with or without texture mapping.
429 */
430 static void antialiased_rgba_points( GLcontext *ctx,
431 GLuint first, GLuint last )
432 {
433 struct vertex_buffer *VB = ctx->VB;
434 struct pixel_buffer *PB = ctx->PB;
435 GLuint i;
436 GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
437
438 radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
439 rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
440 rmax = radius + 0.7071F;
441 rmin2 = rmin*rmin;
442 rmax2 = rmax*rmax;
443 cscale = 256.0F / (rmax2-rmin2);
444
445 if (ctx->Texture.Enabled) {
446 for (i=first;i<=last;i++) {
447 if (VB->ClipMask[i]==0) {
448 GLint xmin, ymin, xmax, ymax;
449 GLint x, y, z;
450 GLint red, green, blue, alpha;
451 GLfloat s, t, u;
452
453 xmin = (GLint) (VB->Win[i][0] - radius);
454 xmax = (GLint) (VB->Win[i][0] + radius);
455 ymin = (GLint) (VB->Win[i][1] - radius);
456 ymax = (GLint) (VB->Win[i][1] + radius);
457 z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
458
459 red = VB->Color[i][0];
460 green = VB->Color[i][1];
461 blue = VB->Color[i][2];
462 s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
463 t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
464 u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
465
466 for (y=ymin;y<=ymax;y++) {
467 for (x=xmin;x<=xmax;x++) {
468 GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
469 GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
470 GLfloat dist2 = dx*dx + dy*dy;
471 if (dist2<rmax2) {
472 alpha = VB->Color[i][3];
473 if (dist2>=rmin2) {
474 GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
475 /* coverage is in [0,256] */
476 alpha = (alpha * coverage) >> 8;
477 }
478 PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s, t, u );
479 }
480 }
481 }
482 PB_CHECK_FLUSH(ctx,PB)
483 }
484 }
485 }
486 else {
487 /* Not texture mapped */
488 for (i=first;i<=last;i++) {
489 if (VB->ClipMask[i]==0) {
490 GLint xmin, ymin, xmax, ymax;
491 GLint x, y, z;
492 GLint red, green, blue, alpha;
493
494 xmin = (GLint) (VB->Win[i][0] - radius);
495 xmax = (GLint) (VB->Win[i][0] + radius);
496 ymin = (GLint) (VB->Win[i][1] - radius);
497 ymax = (GLint) (VB->Win[i][1] + radius);
498 z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
499
500 red = VB->Color[i][0];
501 green = VB->Color[i][1];
502 blue = VB->Color[i][2];
503
504 for (y=ymin;y<=ymax;y++) {
505 for (x=xmin;x<=xmax;x++) {
506 GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
507 GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
508 GLfloat dist2 = dx*dx + dy*dy;
509 if (dist2<rmax2) {
510 alpha = VB->Color[i][3];
511 if (dist2>=rmin2) {
512 GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
513 /* coverage is in [0,256] */
514 alpha = (alpha * coverage) >> 8;
515 }
516 PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
517 }
518 }
519 }
520 PB_CHECK_FLUSH(ctx,PB)
521 }
522 }
523 }
524 }
525
526
527
528 /*
529 * Null rasterizer for measuring transformation speed.
530 */
531 static void null_points( GLcontext *ctx, GLuint first, GLuint last )
532 {
533 }
534
535 /* Definition of the functions for GL_EXT_point_parameters */
536
537 /*
538 * Examine the current context to determine which point drawing function
539 * should be used.
540 */
541 void gl_set_point_function( GLcontext *ctx )
542 {
543 GLboolean rgbmode = ctx->Visual->RGBAflag;
544
545 if (ctx->RenderMode==GL_RENDER) {
546 if (ctx->NoRaster) {
547 ctx->Driver.PointsFunc = null_points;
548 return;
549 }
550 if (ctx->Driver.PointsFunc) {
551 /* Device driver will draw points. */
552 ctx->Driver.PointsFunc = ctx->Driver.PointsFunc;
553 }
554 else {
555 if (ctx->Point.SmoothFlag && rgbmode) {
556 ctx->Driver.PointsFunc = antialiased_rgba_points;
557 }
558 else if (ctx->Texture.Enabled) {
559 ctx->Driver.PointsFunc = textured_rgba_points;
560 }
561 else if (ctx->Point.Size==1.0) {
562 /* size=1, any raster ops */
563 if (rgbmode)
564 ctx->Driver.PointsFunc = size1_rgba_points;
565 else
566 ctx->Driver.PointsFunc = size1_ci_points;
567 }
568 else {
569 /* every other kind of point rendering */
570 if (rgbmode)
571 ctx->Driver.PointsFunc = general_rgba_points;
572 else
573 ctx->Driver.PointsFunc = general_ci_points;
574 }
575 }
576 }
577 else if (ctx->RenderMode==GL_FEEDBACK) {
578 ctx->Driver.PointsFunc = feedback_points;
579 }
580 else {
581 /* GL_SELECT mode */
582 ctx->Driver.PointsFunc = select_points;
583 }
584
585 }
586