ReactOS 0.4.15-dev-7842-g558ab78
vbrender.c
Go to the documentation of this file.
1/* $Id: vbrender.c,v 1.21 1998/01/18 15:04:48 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 2.6
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: vbrender.c,v $
26 * Revision 1.21 1998/01/18 15:04:48 brianp
27 * fixed clipmask bug in gl_reset_vb() (reported by Michael Callahan)
28 *
29 * Revision 1.20 1998/01/09 02:49:33 brianp
30 * cleaned-up gl_reset_vb(), added small GL_POLYGON optimization
31 *
32 * Revision 1.19 1997/12/29 23:49:57 brianp
33 * added a call to gl_update_lighting() in gl_reset_vb() to fix material bug
34 *
35 * Revision 1.18 1997/12/19 03:36:42 brianp
36 * check bit-wise AND of vertex clip masks to cull polygons sooner
37 *
38 * Revision 1.17 1997/12/09 02:56:57 brianp
39 * in render_clipped_polygon() only recompute window coords for new verts
40 *
41 * Revision 1.16 1997/11/20 00:00:47 brianp
42 * only call Driver.RasterSetup() once in render_clipped_polygon()
43 *
44 * Revision 1.15 1997/09/18 01:32:47 brianp
45 * fixed divide by zero problem for "weird" projection matrices
46 *
47 * Revision 1.14 1997/08/13 01:31:41 brianp
48 * cleaned up code involving LightTwoSide
49 *
50 * Revision 1.13 1997/07/24 01:25:27 brianp
51 * changed precompiled header symbol from PCH to PC_HEADER
52 *
53 * Revision 1.12 1997/07/11 02:19:52 brianp
54 * flat-shaded quads in a strip were miscolored if clipped (Randy Frank)
55 *
56 * Revision 1.11 1997/05/28 03:26:49 brianp
57 * added precompiled header (PCH) support
58 *
59 * Revision 1.10 1997/05/16 02:09:26 brianp
60 * clipped GL_TRIANGLE_STRIP triangles sometimes got wrong provoking vertex
61 *
62 * Revision 1.9 1997/04/30 02:20:00 brianp
63 * fixed a line clipping bug in GL_LINE_LOOPs
64 *
65 * Revision 1.8 1997/04/29 01:31:07 brianp
66 * added RasterSetup() function to device driver
67 *
68 * Revision 1.7 1997/04/24 00:30:17 brianp
69 * optimized glTexCoord2() code
70 *
71 * Revision 1.6 1997/04/20 19:47:06 brianp
72 * fixed an error message, added a comment
73 *
74 * Revision 1.5 1997/04/20 15:59:30 brianp
75 * removed VERTEX2_BIT stuff
76 *
77 * Revision 1.4 1997/04/20 15:27:34 brianp
78 * removed odd_flag from all polygon rendering functions
79 *
80 * Revision 1.3 1997/04/12 12:26:06 brianp
81 * now directly call ctx->Driver.Points/Line/Triangle/QuadFunc
82 *
83 * Revision 1.2 1997/04/07 03:01:11 brianp
84 * optimized vertex[234] code
85 *
86 * Revision 1.1 1997/04/02 03:14:14 brianp
87 * Initial revision
88 *
89 */
90
91
92/*
93 * Render points, lines, and polygons. The only entry point to this
94 * file is the gl_render_vb() function. This function is called after
95 * the vertex buffer has filled up or glEnd() has been called.
96 *
97 * This file basically only makes calls to the clipping functions and
98 * the point, line and triangle rasterizers via the function pointers.
99 * context->Driver.PointsFunc()
100 * context->Driver.LineFunc()
101 * context->Driver.TriangleFunc()
102 */
103
104
105#ifdef PC_HEADER
106#include "all.h"
107#else
108#include "clip.h"
109#include "context.h"
110#include "light.h"
111#include "macros.h"
112#include "matrix.h"
113#include "pb.h"
114#include "types.h"
115#include "vb.h"
116#include "vbrender.h"
117#include "xform.h"
118#endif
119
120
121/*
122 * This file implements rendering of points, lines and polygons defined by
123 * vertices in the vertex buffer.
124 */
125
126
127
128#ifdef PROFILE
129# define START_PROFILE \
130 { \
131 GLdouble t0 = gl_time();
132
133# define END_PROFILE( TIMER, COUNTER, INCR ) \
134 TIMER += (gl_time() - t0); \
135 COUNTER += INCR; \
136 }
137#else
138# define START_PROFILE
139# define END_PROFILE( TIMER, COUNTER, INCR )
140#endif
141
142
143
144
145/*
146 * Render a line segment from VB[v1] to VB[v2] when either one or both
147 * endpoints must be clipped.
148 */
150{
151 GLfloat ndc_x, ndc_y, ndc_z;
152 GLuint provoking_vertex;
153 struct vertex_buffer *VB = ctx->VB;
154
155 /* which vertex dictates the color when flat shading: */
156 provoking_vertex = v2;
157
158 /*
159 * Clipping may introduce new vertices. New vertices will be stored
160 * in the vertex buffer arrays starting with location VB->Free. After
161 * we've rendered the line, these extra vertices can be overwritten.
162 */
163 VB->Free = VB_MAX;
164
165 /* Clip against user clipping planes */
166 if (ctx->Transform.AnyClip) {
167 GLuint orig_v1 = v1, orig_v2 = v2;
168 if (gl_userclip_line( ctx, &v1, &v2 )==0)
169 return;
170 /* Apply projection matrix: clip = Proj * eye */
171 if (v1!=orig_v1) {
172 TRANSFORM_POINT( VB->Clip[v1], ctx->ProjectionMatrix, VB->Eye[v1] );
173 }
174 if (v2!=orig_v2) {
175 TRANSFORM_POINT( VB->Clip[v2], ctx->ProjectionMatrix, VB->Eye[v2] );
176 }
177 }
178
179 /* Clip against view volume */
180 if (gl_viewclip_line( ctx, &v1, &v2 )==0)
181 return;
182
183 /* Transform from clip coords to ndc: ndc = clip / W */
184 if (VB->Clip[v1][3] != 0.0F) {
185 GLfloat wInv = 1.0F / VB->Clip[v1][3];
186 ndc_x = VB->Clip[v1][0] * wInv;
187 ndc_y = VB->Clip[v1][1] * wInv;
188 ndc_z = VB->Clip[v1][2] * wInv;
189 }
190 else {
191 /* Can't divide by zero, so... */
192 ndc_x = ndc_y = ndc_z = 0.0F;
193 }
194
195 /* Map ndc coord to window coords. */
196 VB->Win[v1][0] = ndc_x * ctx->Viewport.Sx + ctx->Viewport.Tx;
197 VB->Win[v1][1] = ndc_y * ctx->Viewport.Sy + ctx->Viewport.Ty;
198 VB->Win[v1][2] = ndc_z * ctx->Viewport.Sz + ctx->Viewport.Tz;
199
200 /* Transform from clip coords to ndc: ndc = clip / W */
201 if (VB->Clip[v2][3] != 0.0F) {
202 GLfloat wInv = 1.0F / VB->Clip[v2][3];
203 ndc_x = VB->Clip[v2][0] * wInv;
204 ndc_y = VB->Clip[v2][1] * wInv;
205 ndc_z = VB->Clip[v2][2] * wInv;
206 }
207 else {
208 /* Can't divide by zero, so... */
209 ndc_x = ndc_y = ndc_z = 0.0F;
210 }
211
212 /* Map ndc coord to window coords. */
213 VB->Win[v2][0] = ndc_x * ctx->Viewport.Sx + ctx->Viewport.Tx;
214 VB->Win[v2][1] = ndc_y * ctx->Viewport.Sy + ctx->Viewport.Ty;
215 VB->Win[v2][2] = ndc_z * ctx->Viewport.Sz + ctx->Viewport.Tz;
216
217 if (ctx->Driver.RasterSetup) {
218 /* Device driver rasterization setup */
219 (*ctx->Driver.RasterSetup)( ctx, v1, v1+1 );
220 (*ctx->Driver.RasterSetup)( ctx, v2, v2+1 );
221 }
222
224 (*ctx->Driver.LineFunc)( ctx, v1, v2, provoking_vertex );
225 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
226}
227
228
229
230/*
231 * Compute Z offsets for a polygon with plane defined by (A,B,C,D)
232 * D is not needed.
233 */
235{
236 GLfloat ac, bc, m;
238
239 if (c<0.001F && c>-0.001F) {
240 /* to prevent underflow problems */
241 offset = 0.0F;
242 }
243 else {
244 ac = a / c;
245 bc = b / c;
246 if (ac<0.0F) ac = -ac;
247 if (bc<0.0F) bc = -bc;
248 m = MAX2( ac, bc );
249 /* m = sqrt( ac*ac + bc*bc ); */
250
251 offset = m * ctx->Polygon.OffsetFactor + ctx->Polygon.OffsetUnits;
252 }
253
254 ctx->PointZoffset = ctx->Polygon.OffsetPoint ? offset : 0.0F;
255 ctx->LineZoffset = ctx->Polygon.OffsetLine ? offset : 0.0F;
256 ctx->PolygonZoffset = ctx->Polygon.OffsetFill ? offset : 0.0F;
257}
258
259
260
261/*
262 * When glPolygonMode() is used to specify that the front/back rendering
263 * mode for polygons is not GL_FILL we end up calling this function.
264 */
266 GLuint n, GLuint vlist[],
267 GLuint pv, GLuint facing )
268{
269 GLenum mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
270 struct vertex_buffer *VB = ctx->VB;
271
272 if (mode==GL_POINT) {
273 GLint i, j;
274 GLboolean edge;
275
276 if ( ctx->Primitive==GL_TRIANGLES
277 || ctx->Primitive==GL_QUADS
278 || ctx->Primitive==GL_POLYGON) {
279 edge = GL_FALSE;
280 }
281 else {
282 edge = GL_TRUE;
283 }
284
285 for (i=0;i<n;i++) {
286 j = vlist[i];
287 if (edge || VB->Edgeflag[j]) {
288 (*ctx->Driver.PointsFunc)( ctx, j, j );
289 }
290 }
291 }
292 else if (mode==GL_LINE) {
293 GLuint i, j0, j1;
294 GLboolean edge;
295
296 ctx->StippleCounter = 0;
297
298 if ( ctx->Primitive==GL_TRIANGLES
299 || ctx->Primitive==GL_QUADS
300 || ctx->Primitive==GL_POLYGON) {
301 edge = GL_FALSE;
302 }
303 else {
304 edge = GL_TRUE;
305 }
306
307 /* draw the edges */
308 for (i=0;i<n;i++) {
309 j0 = (i==0) ? vlist[n-1] : vlist[i-1];
310 j1 = vlist[i];
311 if (edge || VB->Edgeflag[j0]) {
313 (*ctx->Driver.LineFunc)( ctx, j0, j1, pv );
314 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
315 }
316 }
317 }
318 else {
319 /* Fill the polygon */
320 GLuint j0, i;
321 j0 = vlist[0];
322 for (i=2;i<n;i++) {
324 (*ctx->Driver.TriangleFunc)( ctx, j0, vlist[i-1], vlist[i], pv );
325 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
326 }
327 }
328}
329
330
331/*
332 * Compute signed area of the n-sided polgyon specified by vertices vb->Win[]
333 * and vertex list vlist[].
334 * A clockwise polygon will return a negative area.
335 * A counter-clockwise polygon will return a positive area.
336 */
337static GLfloat polygon_area( const struct vertex_buffer *vb,
338 GLuint n, const GLuint vlist[] )
339{
340 GLfloat area = 0.0F;
341 GLint i;
342 for (i=0;i<n;i++) {
343 /* area = sum of trapezoids */
344 GLuint j0 = vlist[i];
345 GLuint j1 = vlist[(i+1)%n];
346 GLfloat x0 = vb->Win[j0][0];
347 GLfloat y0 = vb->Win[j0][1];
348 GLfloat x1 = vb->Win[j1][0];
349 GLfloat y1 = vb->Win[j1][1];
350 GLfloat trapArea = (x0-x1)*(y0+y1); /* Note: no divide by two here! */
351 area += trapArea;
352 }
353 return area * 0.5F; /* divide by two now! */
354}
355
356
357/*
358 * Render a polygon in which doesn't have to be clipped.
359 * Input: n - number of vertices
360 * vlist - list of vertices in the polygon.
361 */
362static void render_polygon( GLcontext *ctx, GLuint n, GLuint vlist[] )
363{
364 struct vertex_buffer *VB = ctx->VB;
365 GLuint pv;
366
367 /* which vertex dictates the color when flat shading: */
368 pv = (ctx->Primitive==GL_POLYGON) ? vlist[0] : vlist[n-1];
369
370 /* Compute orientation of polygon, do cull test, offset, etc */
371 {
372 GLuint facing; /* 0=front, 1=back */
373 GLfloat area = polygon_area( VB, n, vlist );
374
375 if (area==0.0F) {
376 /* polygon has zero area, don't draw it */
377 return;
378 }
379
380 facing = (area<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW);
381
382 if ((facing+1) & ctx->Polygon.CullBits) {
383 return; /* culled */
384 }
385
386 if (ctx->Polygon.OffsetAny) {
387 /* compute plane equation of polygon, apply offset */
388 GLuint j0 = vlist[0];
389 GLuint j1 = vlist[1];
390 GLuint j2 = vlist[2];
391 GLuint j3 = vlist[ (n==3) ? 0 : 3 ];
392 GLfloat ex = VB->Win[j1][0] - VB->Win[j3][0];
393 GLfloat ey = VB->Win[j1][1] - VB->Win[j3][1];
394 GLfloat ez = VB->Win[j1][2] - VB->Win[j3][2];
395 GLfloat fx = VB->Win[j2][0] - VB->Win[j0][0];
396 GLfloat fy = VB->Win[j2][1] - VB->Win[j0][1];
397 GLfloat fz = VB->Win[j2][2] - VB->Win[j0][2];
398 GLfloat a = ey*fz-ez*fy;
399 GLfloat b = ez*fx-ex*fz;
400 GLfloat c = ex*fy-ey*fx;
401 offset_polygon( ctx, a, b, c );
402 }
403
404 if (ctx->LightTwoSide) {
405 if (facing==1) {
406 /* use back color or index */
407 VB->Color = VB->Bcolor;
408 VB->Index = VB->Bindex;
409 }
410 else {
411 /* use front color or index */
412 VB->Color = VB->Fcolor;
413 VB->Index = VB->Findex;
414 }
415 }
416
417 /* Render the polygon! */
418 if (ctx->Polygon.Unfilled) {
419 unfilled_polygon( ctx, n, vlist, pv, facing );
420 }
421 else {
422 /* Draw filled polygon as a triangle fan */
423 GLint i;
424 GLuint j0 = vlist[0];
425 for (i=2;i<n;i++) {
427 (*ctx->Driver.TriangleFunc)( ctx, j0, vlist[i-1], vlist[i], pv );
428 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
429 }
430 }
431 }
432}
433
434
435
436/*
437 * Render a polygon in which at least one vertex has to be clipped.
438 * Input: n - number of vertices
439 * vlist - list of vertices in the polygon.
440 * CCW order = front facing.
441 */
443{
444 GLuint pv;
445 struct vertex_buffer *VB = ctx->VB;
446 GLfloat (*win)[3] = VB->Win;
447
448 /* which vertex dictates the color when flat shading: */
449 pv = (ctx->Primitive==GL_POLYGON) ? vlist[0] : vlist[n-1];
450
451 /*
452 * Clipping may introduce new vertices. New vertices will be stored
453 * in the vertex buffer arrays starting with location VB->Free. After
454 * we've rendered the polygon, these extra vertices can be overwritten.
455 */
456 VB->Free = VB_MAX;
457
458 /* Clip against user clipping planes in eye coord space. */
459 if (ctx->Transform.AnyClip) {
460 GLfloat *proj = ctx->ProjectionMatrix;
461 GLuint i;
462 n = gl_userclip_polygon( ctx, n, vlist );
463 if (n<3)
464 return;
465 /* Transform vertices from eye to clip coordinates: clip = Proj * eye */
466 for (i=0;i<n;i++) {
467 GLuint j = vlist[i];
468 TRANSFORM_POINT( VB->Clip[j], proj, VB->Eye[j] );
469 }
470 }
471
472 /* Clip against view volume in clip coord space */
473 n = gl_viewclip_polygon( ctx, n, vlist );
474 if (n<3)
475 return;
476
477 /* Transform new vertices from clip to ndc to window coords. */
478 /* ndc = clip / W window = viewport_mapping(ndc) */
479 /* Note that window Z values are scaled to the range of integer */
480 /* depth buffer values. */
481 {
482 GLfloat sx = ctx->Viewport.Sx;
483 GLfloat tx = ctx->Viewport.Tx;
484 GLfloat sy = ctx->Viewport.Sy;
485 GLfloat ty = ctx->Viewport.Ty;
486 GLfloat sz = ctx->Viewport.Sz;
487 GLfloat tz = ctx->Viewport.Tz;
488 GLuint i;
489 /* Only need to compute window coords for new vertices */
490 for (i=VB_MAX; i<VB->Free; i++) {
491 if (VB->Clip[i][3] != 0.0F) {
492 GLfloat wInv = 1.0F / VB->Clip[i][3];
493 win[i][0] = VB->Clip[i][0] * wInv * sx + tx;
494 win[i][1] = VB->Clip[i][1] * wInv * sy + ty;
495 win[i][2] = VB->Clip[i][2] * wInv * sz + tz;
496 }
497 else {
498 /* Can't divide by zero, so... */
499 win[i][0] = win[i][1] = win[i][2] = 0.0F;
500 }
501 }
502 if (ctx->Driver.RasterSetup && (VB->Free > VB_MAX)) {
503 /* Device driver raster setup for newly introduced vertices */
504 (*ctx->Driver.RasterSetup)(ctx, VB_MAX, VB->Free);
505 }
506
507#ifdef DEBUG
508 {
509 int i, j;
510 for (i=0;i<n;i++) {
511 j = vlist[i];
512 if (VB->ClipMask[j]) {
513 /* Uh oh! There should be no clip bits set in final polygon! */
514 int k, l;
515 printf("CLIPMASK %d %d %02x\n", i, j, VB->ClipMask[j]);
516 printf("%f %f %f %f\n", VB->Eye[j][0], VB->Eye[j][1],
517 VB->Eye[j][2], VB->Eye[j][3]);
518 printf("%f %f %f %f\n", VB->Clip[j][0], VB->Clip[j][1],
519 VB->Clip[j][2], VB->Clip[j][3]);
520 for (k=0;k<n;k++) {
521 l = vlist[k];
522 printf("%d %d %02x\n", k, l, VB->ClipMask[l]);
523 }
524 }
525 }
526 }
527#endif
528 }
529
530 /* Compute orientation of polygon, do cull test, offset, etc */
531 {
532 GLuint facing; /* 0=front, 1=back */
533 GLfloat area = polygon_area( VB, n, vlist );
534
535 if (area==0.0F) {
536 /* polygon has zero area, don't draw it */
537 return;
538 }
539
540 facing = (area<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW);
541
542 if ((facing+1) & ctx->Polygon.CullBits) {
543 return; /* culled */
544 }
545
546 if (ctx->Polygon.OffsetAny) {
547 /* compute plane equation of polygon, apply offset */
548 GLuint j0 = vlist[0];
549 GLuint j1 = vlist[1];
550 GLuint j2 = vlist[2];
551 GLuint j3 = vlist[ (n==3) ? 0 : 3 ];
552 GLfloat ex = win[j1][0] - win[j3][0];
553 GLfloat ey = win[j1][1] - win[j3][1];
554 GLfloat ez = win[j1][2] - win[j3][2];
555 GLfloat fx = win[j2][0] - win[j0][0];
556 GLfloat fy = win[j2][1] - win[j0][1];
557 GLfloat fz = win[j2][2] - win[j0][2];
558 GLfloat a = ey*fz-ez*fy;
559 GLfloat b = ez*fx-ex*fz;
560 GLfloat c = ex*fy-ey*fx;
561 offset_polygon( ctx, a, b, c );
562 }
563
564 if (ctx->LightTwoSide) {
565 if (facing==1) {
566 /* use back color or index */
567 VB->Color = VB->Bcolor;
568 VB->Index = VB->Bindex;
569 }
570 else {
571 /* use front color or index */
572 VB->Color = VB->Fcolor;
573 VB->Index = VB->Findex;
574 }
575 }
576
577 /* Render the polygon! */
578 if (ctx->Polygon.Unfilled) {
579 unfilled_polygon( ctx, n, vlist, pv, facing );
580 }
581 else {
582 /* Draw filled polygon as a triangle fan */
583 GLint i;
584 GLuint j0 = vlist[0];
585 for (i=2;i<n;i++) {
587 (*ctx->Driver.TriangleFunc)( ctx, j0, vlist[i-1], vlist[i], pv );
588 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
589 }
590 }
591 }
592}
593
594
595
596/*
597 * Render an un-clipped triangle.
598 * v0, v1, v2 - vertex indexes. CCW order = front facing
599 * pv - provoking vertex
600 */
603{
604 struct vertex_buffer *VB = ctx->VB;
605 GLfloat ex, ey, fx, fy, c;
606 GLuint facing; /* 0=front, 1=back */
607 GLfloat (*win)[3] = VB->Win;
608
609 /* Compute orientation of triangle */
610 ex = win[v1][0] - win[v0][0];
611 ey = win[v1][1] - win[v0][1];
612 fx = win[v2][0] - win[v0][0];
613 fy = win[v2][1] - win[v0][1];
614 c = ex*fy-ey*fx;
615
616 if (c==0.0F) {
617 /* polygon is perpindicular to view plane, don't draw it */
618 return;
619 }
620
621 facing = (c<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW);
622
623 if ((facing+1) & ctx->Polygon.CullBits) {
624 return; /* culled */
625 }
626
627 if (ctx->Polygon.OffsetAny) {
628 /* finish computing plane equation of polygon, compute offset */
629 GLfloat fz = win[v2][2] - win[v0][2];
630 GLfloat ez = win[v1][2] - win[v0][2];
631 GLfloat a = ey*fz-ez*fy;
632 GLfloat b = ez*fx-ex*fz;
633 offset_polygon( ctx, a, b, c );
634 }
635
636 if (ctx->LightTwoSide) {
637 if (facing==1) {
638 /* use back color or index */
639 VB->Color = VB->Bcolor;
640 VB->Index = VB->Bindex;
641 }
642 else {
643 /* use front color or index */
644 VB->Color = VB->Fcolor;
645 VB->Index = VB->Findex;
646 }
647 }
648
649 if (ctx->Polygon.Unfilled) {
650 GLuint vlist[3];
651 vlist[0] = v0;
652 vlist[1] = v1;
653 vlist[2] = v2;
654 unfilled_polygon( ctx, 3, vlist, pv, facing );
655 }
656 else {
658 (*ctx->Driver.TriangleFunc)( ctx, v0, v1, v2, pv );
659 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
660 }
661}
662
663
664
665/*
666 * Render an un-clipped quadrilateral.
667 * v0, v1, v2, v3 : CCW order = front facing
668 * pv - provoking vertex
669 */
671 GLuint v2, GLuint v3, GLuint pv )
672{
673 struct vertex_buffer *VB = ctx->VB;
674 GLfloat ex, ey, fx, fy, c;
675 GLuint facing; /* 0=front, 1=back */
676 GLfloat (*win)[3] = VB->Win;
677
678 /* Compute polygon orientation */
679 ex = win[v2][0] - win[v0][0];
680 ey = win[v2][1] - win[v0][1];
681 fx = win[v3][0] - win[v1][0];
682 fy = win[v3][1] - win[v1][1];
683 c = ex*fy-ey*fx;
684
685 if (c==0.0F) {
686 /* polygon is perpindicular to view plane, don't draw it */
687 return;
688 }
689
690 facing = (c<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW);
691
692 if ((facing+1) & ctx->Polygon.CullBits) {
693 return; /* culled */
694 }
695
696 if (ctx->Polygon.OffsetAny) {
697 /* finish computing plane equation of polygon, compute offset */
698 GLfloat ez = win[v2][2] - win[v0][2];
699 GLfloat fz = win[v3][2] - win[v1][2];
700 GLfloat a = ey*fz-ez*fy;
701 GLfloat b = ez*fx-ex*fz;
702 offset_polygon( ctx, a, b, c );
703 }
704
705 if (ctx->LightTwoSide) {
706 if (facing==1) {
707 /* use back color or index */
708 VB->Color = VB->Bcolor;
709 VB->Index = VB->Bindex;
710 }
711 else {
712 /* use front color or index */
713 VB->Color = VB->Fcolor;
714 VB->Index = VB->Findex;
715 }
716 }
717
718 /* Render the quad! */
719 if (ctx->Polygon.Unfilled) {
720 GLuint vlist[4];
721 vlist[0] = v0;
722 vlist[1] = v1;
723 vlist[2] = v2;
724 vlist[3] = v3;
725 unfilled_polygon( ctx, 4, vlist, pv, facing );
726 }
727 else {
729 (*ctx->Driver.QuadFunc)( ctx, v0, v1, v2, v3, pv );
730 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 2 )
731 }
732}
733
734
735
736/*
737 * When the vertex buffer is full, we transform/render it. Sometimes we
738 * have to copy the last vertex (or two) to the front of the vertex list
739 * to "continue" the primitive. For example: line or triangle strips.
740 * This function is a helper for that.
741 */
742static void copy_vertex( struct vertex_buffer *vb, GLuint dst, GLuint src )
743{
744 COPY_4V( vb->Clip[dst], vb->Clip[src] );
745 COPY_4V( vb->Eye[dst], vb->Eye[src] );
746 COPY_3V( vb->Win[dst], vb->Win[src] );
747 COPY_4V( vb->Fcolor[dst], vb->Fcolor[src] );
748 COPY_4V( vb->Bcolor[dst], vb->Bcolor[src] );
749 COPY_4V( vb->TexCoord[dst], vb->TexCoord[src] );
750 vb->Findex[dst] = vb->Findex[src];
751 vb->Bindex[dst] = vb->Bindex[src];
752 vb->Edgeflag[dst] = vb->Edgeflag[src];
753 vb->ClipMask[dst] = vb->ClipMask[src];
754 vb->MaterialMask[dst] = vb->MaterialMask[src];
755 vb->Material[dst][0] = vb->Material[src][0];
756 vb->Material[dst][1] = vb->Material[src][1];
757}
758
759
760
761
762/*
763 * Either the vertex buffer is full (VB->Count==VB_MAX) or glEnd() has been
764 * called. Render the primitives defined by the vertices and reset the
765 * buffer.
766 *
767 * This function won't be called if the device driver implements a
768 * RenderVB() function. If the device driver renders the vertex buffer
769 * then the driver must also call gl_reset_vb()!
770 *
771 * Input: allDone - GL_TRUE = caller is glEnd()
772 * GL_FALSE = calling because buffer is full.
773 */
775{
776 struct vertex_buffer *VB = ctx->VB;
777 GLuint vlist[VB_SIZE];
778
779 switch (ctx->Primitive) {
780 case GL_POINTS:
782 (*ctx->Driver.PointsFunc)( ctx, 0, VB->Count-1 );
783 END_PROFILE( ctx->PointTime, ctx->PointCount, VB->Count )
784 break;
785
786 case GL_LINES:
787 if (VB->ClipOrMask) {
788 GLuint i;
789 for (i=1;i<VB->Count;i+=2) {
790 if (VB->ClipMask[i-1] | VB->ClipMask[i]) {
791 render_clipped_line( ctx, i-1, i );
792 }
793 else {
795 (*ctx->Driver.LineFunc)( ctx, i-1, i, i );
796 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
797 }
798 ctx->StippleCounter = 0;
799 }
800 }
801 else {
802 GLuint i;
803 for (i=1;i<VB->Count;i+=2) {
805 (*ctx->Driver.LineFunc)( ctx, i-1, i, i );
806 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
807 ctx->StippleCounter = 0;
808 }
809 }
810 break;
811
812 case GL_LINE_STRIP:
813 if (VB->ClipOrMask) {
814 GLuint i;
815 for (i=1;i<VB->Count;i++) {
816 if (VB->ClipMask[i-1] | VB->ClipMask[i]) {
817 render_clipped_line( ctx, i-1, i );
818 }
819 else {
821 (*ctx->Driver.LineFunc)( ctx, i-1, i, i );
822 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
823 }
824 }
825 }
826 else {
827 /* no clipping needed */
828 GLuint i;
829 for (i=1;i<VB->Count;i++) {
831 (*ctx->Driver.LineFunc)( ctx, i-1, i, i );
832 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
833 }
834 }
835 break;
836
837 case GL_LINE_LOOP:
838 {
839 GLuint i;
840 if (VB->Start==0) {
841 i = 1; /* start at 0th vertex */
842 }
843 else {
844 i = 2; /* skip first vertex, we're saving it until glEnd */
845 }
846 while (i<VB->Count) {
847 if (VB->ClipMask[i-1] | VB->ClipMask[i]) {
848 render_clipped_line( ctx, i-1, i );
849 }
850 else {
852 (*ctx->Driver.LineFunc)( ctx, i-1, i, i );
853 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
854 }
855 i++;
856 }
857 }
858 break;
859
860 case GL_TRIANGLES:
861 if (VB->ClipOrMask) {
862 GLuint i;
863 for (i=2;i<VB->Count;i+=3) {
864 if (VB->ClipMask[i-2] & VB->ClipMask[i-1]
865 & VB->ClipMask[i] & CLIP_ALL_BITS) {
866 /* all points clipped by common plane */
867 continue;
868 }
869 else if (VB->ClipMask[i-2] | VB->ClipMask[i-1] | VB->ClipMask[i]) {
870 vlist[0] = i-2;
871 vlist[1] = i-1;
872 vlist[2] = i-0;
873 render_clipped_polygon( ctx, 3, vlist );
874 }
875 else {
876 if (ctx->DirectTriangles) {
878 (*ctx->Driver.TriangleFunc)( ctx, i-2, i-1, i, i );
879 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
880 }
881 else {
882 render_triangle( ctx, i-2, i-1, i, i );
883 }
884 }
885 }
886 }
887 else {
888 /* no clipping needed */
889 GLuint i;
890 if (ctx->DirectTriangles) {
891 for (i=2;i<VB->Count;i+=3) {
893 (*ctx->Driver.TriangleFunc)( ctx, i-2, i-1, i, i );
894 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
895 }
896 }
897 else {
898 for (i=2;i<VB->Count;i+=3) {
899 render_triangle( ctx, i-2, i-1, i, i );
900 }
901 }
902 }
903 break;
904
906 if (VB->ClipOrMask) {
907 GLuint i;
908 for (i=2;i<VB->Count;i++) {
909 if (VB->ClipMask[i-2] & VB->ClipMask[i-1]
910 & VB->ClipMask[i] & CLIP_ALL_BITS) {
911 /* all points clipped by common plane */
912 continue;
913 }
914 else if (VB->ClipMask[i-2] | VB->ClipMask[i-1] | VB->ClipMask[i]) {
915 if (i&1) {
916 /* reverse vertex order */
917 vlist[0] = i-1;
918 vlist[1] = i-2;
919 vlist[2] = i-0;
920 render_clipped_polygon( ctx, 3, vlist );
921 }
922 else {
923 vlist[0] = i-2;
924 vlist[1] = i-1;
925 vlist[2] = i-0;
926 render_clipped_polygon( ctx, 3, vlist );
927 }
928 }
929 else {
930 if (ctx->DirectTriangles) {
932 (*ctx->Driver.TriangleFunc)( ctx, i-2, i-1, i, i );
933 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
934 }
935 else {
936 if (i&1)
937 render_triangle( ctx, i, i-1, i-2, i );
938 else
939 render_triangle( ctx, i-2, i-1, i, i );
940 }
941 }
942 }
943 }
944 else {
945 /* no vertices were clipped */
946 GLuint i;
947 if (ctx->DirectTriangles) {
948 for (i=2;i<VB->Count;i++) {
950 (*ctx->Driver.TriangleFunc)( ctx, i-2, i-1, i, i );
951 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
952 }
953 }
954 else {
955 for (i=2;i<VB->Count;i++) {
956 if (i&1)
957 render_triangle( ctx, i, i-1, i-2, i );
958 else
959 render_triangle( ctx, i-2, i-1, i, i );
960 }
961 }
962 }
963 break;
964
965 case GL_TRIANGLE_FAN:
966 if (VB->ClipOrMask) {
967 GLuint i;
968 for (i=2;i<VB->Count;i++) {
969 if (VB->ClipMask[0] & VB->ClipMask[i-1] & VB->ClipMask[i]
970 & CLIP_ALL_BITS) {
971 /* all points clipped by common plane */
972 continue;
973 }
974 else if (VB->ClipMask[0] | VB->ClipMask[i-1] | VB->ClipMask[i]) {
975 vlist[0] = 0;
976 vlist[1] = i-1;
977 vlist[2] = i;
978 render_clipped_polygon( ctx, 3, vlist );
979 }
980 else {
981 if (ctx->DirectTriangles) {
983 (*ctx->Driver.TriangleFunc)( ctx, 0, i-1, i, i );
984 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
985 }
986 else {
987 render_triangle( ctx, 0, i-1, i, i );
988 }
989 }
990 }
991 }
992 else {
993 /* no clipping needed */
994 GLuint i;
995 if (ctx->DirectTriangles) {
996 for (i=2;i<VB->Count;i++) {
998 (*ctx->Driver.TriangleFunc)( ctx, 0, i-1, i, i );
999 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 1 )
1000 }
1001 }
1002 else {
1003 for (i=2;i<VB->Count;i++) {
1004 render_triangle( ctx, 0, i-1, i, i );
1005 }
1006 }
1007 }
1008 break;
1009
1010 case GL_QUADS:
1011 if (VB->ClipOrMask) {
1012 GLuint i;
1013 for (i=3;i<VB->Count;i+=4) {
1014 if (VB->ClipMask[i-3] & VB->ClipMask[i-2]
1015 & VB->ClipMask[i-1] & VB->ClipMask[i] & CLIP_ALL_BITS) {
1016 /* all points clipped by common plane */
1017 continue;
1018 }
1019 else if (VB->ClipMask[i-3] | VB->ClipMask[i-2]
1020 | VB->ClipMask[i-1] | VB->ClipMask[i]) {
1021 vlist[0] = i-3;
1022 vlist[1] = i-2;
1023 vlist[2] = i-1;
1024 vlist[3] = i-0;
1025 render_clipped_polygon( ctx, 4, vlist );
1026 }
1027 else {
1028 if (ctx->DirectTriangles) {
1030 (*ctx->Driver.QuadFunc)( ctx, i-3, i-2, i-1, i, i );
1031 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 2 )
1032 }
1033 else {
1034 render_quad( ctx, i-3, i-2, i-1, i, i );
1035 }
1036 }
1037 }
1038 }
1039 else {
1040 /* no vertices were clipped */
1041 GLuint i;
1042 if (ctx->DirectTriangles) {
1043 for (i=3;i<VB->Count;i+=4) {
1045 (*ctx->Driver.QuadFunc)( ctx, i-3, i-2, i-1, i, i );
1046 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 2 )
1047 }
1048 }
1049 else {
1050 for (i=3;i<VB->Count;i+=4) {
1051 render_quad( ctx, i-3, i-2, i-1, i, i );
1052 }
1053 }
1054 }
1055 break;
1056
1057 case GL_QUAD_STRIP:
1058 if (VB->ClipOrMask) {
1059 GLuint i;
1060 for (i=3;i<VB->Count;i+=2) {
1061 if (VB->ClipMask[i-2] & VB->ClipMask[i-3]
1062 & VB->ClipMask[i-1] & VB->ClipMask[i] & CLIP_ALL_BITS) {
1063 /* all points clipped by common plane */
1064 continue;
1065 }
1066 else if (VB->ClipMask[i-2] | VB->ClipMask[i-3]
1067 | VB->ClipMask[i-1] | VB->ClipMask[i]) {
1068 vlist[0] = i-1;
1069 vlist[1] = i-3;
1070 vlist[2] = i-2;
1071 vlist[3] = i-0;
1072 render_clipped_polygon( ctx, 4, vlist );
1073 }
1074 else {
1075 if (ctx->DirectTriangles) {
1077 (*ctx->Driver.QuadFunc)( ctx, i-3, i-2, i, i-1, i );
1078 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 2 )
1079 }
1080 else {
1081 render_quad( ctx, i-3, i-2, i, i-1, i );
1082 }
1083 }
1084 }
1085 }
1086 else {
1087 /* no clipping needed */
1088 GLuint i;
1089 if (ctx->DirectTriangles) {
1090 for (i=3;i<VB->Count;i+=2) {
1092 (*ctx->Driver.QuadFunc)( ctx, i-3, i-2, i, i-1, i );
1093 END_PROFILE( ctx->PolygonTime, ctx->PolygonCount, 2 )
1094 }
1095 }
1096 else {
1097 for (i=3;i<VB->Count;i+=2) {
1098 render_quad( ctx, i-3, i-2, i, i-1, i );
1099 }
1100 }
1101 }
1102 break;
1103
1104 case GL_POLYGON:
1105 if (VB->Count>2) {
1106 if (VB->ClipAndMask & CLIP_ALL_BITS) {
1107 /* all points clipped by common plane, draw nothing */
1108 break;
1109 }
1110 if (VB->ClipOrMask) {
1111 /* need clipping */
1112 GLuint i;
1113 for (i=0;i<VB->Count;i++) {
1114 vlist[i] = i;
1115 }
1116 render_clipped_polygon( ctx, VB->Count, vlist );
1117 }
1118 else {
1119 /* no clipping needed */
1120 static GLuint const_vlist[VB_SIZE];
1121 static GLboolean initFlag = GL_TRUE;
1122 if (initFlag) {
1123 /* vertex list always the same, never changes */
1124 GLuint i;
1125 for (i=0;i<VB_SIZE;i++) {
1126 const_vlist[i] = i;
1127 }
1128 initFlag = GL_FALSE;
1129 }
1130 render_polygon( ctx, VB->Count, const_vlist );
1131 }
1132 }
1133 break;
1134
1135 default:
1136 /* should never get here */
1137 gl_problem( ctx, "invalid mode in gl_render_vb" );
1138 }
1139
1140 gl_reset_vb( ctx, allDone );
1141}
1142
1143
1144#define CLIP_ALL_BITS 0x3f
1145
1146
1147/*
1148 * After we've rendered the primitives in the vertex buffer we call
1149 * this function to reset the vertex buffer. That is, we prepare it
1150 * for the next batch of vertices.
1151 * Input: ctx - the context
1152 * allDone - GL_TRUE = glEnd() was called
1153 * GL_FALSE = buffer was filled, more vertices to come
1154 */
1156{
1157 struct vertex_buffer *VB = ctx->VB;
1158
1159 /* save a few VB values for the end of this function */
1160 int oldCount = VB->Count;
1161 GLubyte clipOrMask = VB->ClipOrMask;
1162 GLboolean monoMaterial = VB->MonoMaterial;
1163 GLuint vertexSizeMask = VB->VertexSizeMask;
1164
1165 /* Special case for GL_LINE_LOOP */
1166 if (ctx->Primitive==GL_LINE_LOOP && allDone) {
1167 if (VB->ClipMask[VB->Count-1] | VB->ClipMask[0]) {
1168 render_clipped_line( ctx, VB->Count-1, 0 );
1169 }
1170 else {
1172 (*ctx->Driver.LineFunc)( ctx, VB->Count-1, 0, 0 );
1173 END_PROFILE( ctx->LineTime, ctx->LineCount, 1 )
1174 }
1175 }
1176
1177 if (allDone) {
1178 /* glEnd() was called so reset Vertex Buffer to default, empty state */
1179 VB->Start = VB->Count = 0;
1180 VB->ClipOrMask = 0;
1181 VB->ClipAndMask = CLIP_ALL_BITS;
1182 VB->MonoMaterial = GL_TRUE;
1183 VB->MonoNormal = GL_TRUE;
1184 VB->MonoColor = GL_TRUE;
1185 VB->VertexSizeMask = VERTEX3_BIT;
1186 if (VB->TexCoordSize!=2) {
1187 GLint i, n = VB->Count;
1188 for (i=0;i<n;i++) {
1189 VB->TexCoord[i][2] = 0.0F;
1190 VB->TexCoord[i][3] = 1.0F;
1191 }
1192 }
1193 if (ctx->Current.TexCoord[2]==0.0F && ctx->Current.TexCoord[3]==1.0F) {
1194 VB->TexCoordSize = 2;
1195 }
1196 else {
1197 VB->TexCoordSize = 4;
1198 }
1199 }
1200 else {
1201 /* The vertex buffer was filled but we didn't get a glEnd() call yet
1202 * have to "re-cycle" the vertex buffer.
1203 */
1204 switch (ctx->Primitive) {
1205 case GL_POINTS:
1206 ASSERT(VB->Start==0);
1207 VB->Start = VB->Count = 0;
1208 VB->ClipOrMask = 0;
1209 VB->ClipAndMask = CLIP_ALL_BITS;
1210 VB->MonoMaterial = GL_TRUE;
1211 VB->MonoNormal = GL_TRUE;
1212 break;
1213 case GL_LINES:
1214 ASSERT(VB->Start==0);
1215 VB->Start = VB->Count = 0;
1216 VB->ClipOrMask = 0;
1217 VB->ClipAndMask = CLIP_ALL_BITS;
1218 VB->MonoMaterial = GL_TRUE;
1219 VB->MonoNormal = GL_TRUE;
1220 break;
1221 case GL_LINE_STRIP:
1222 copy_vertex( VB, 0, VB->Count-1 ); /* copy last vertex to front */
1223 VB->Start = VB->Count = 1;
1224 VB->ClipOrMask = VB->ClipMask[0];
1225 VB->ClipAndMask = VB->ClipMask[0];
1226 VB->MonoMaterial = VB->MaterialMask[0] ? GL_FALSE : GL_TRUE;
1227 break;
1228 case GL_LINE_LOOP:
1229 ASSERT(VB->Count==VB_MAX);
1230 copy_vertex( VB, 1, VB_MAX-1 );
1231 VB->Start = VB->Count = 2;
1232 VB->ClipOrMask = VB->ClipMask[0] | VB->ClipMask[1];
1233 VB->ClipAndMask = VB->ClipMask[0] & VB->ClipMask[1];
1234 VB->MonoMaterial = !(VB->MaterialMask[0] | VB->MaterialMask[1]);
1235 break;
1236 case GL_TRIANGLES:
1237 ASSERT(VB->Start==0);
1238 VB->Start = VB->Count = 0;
1239 VB->ClipOrMask = 0;
1240 VB->ClipAndMask = CLIP_ALL_BITS;
1241 VB->MonoMaterial = GL_TRUE;
1242 VB->MonoNormal = GL_TRUE;
1243 break;
1244 case GL_TRIANGLE_STRIP:
1245 copy_vertex( VB, 0, VB_MAX-2 );
1246 copy_vertex( VB, 1, VB_MAX-1 );
1247 VB->Start = VB->Count = 2;
1248 VB->ClipOrMask = VB->ClipMask[0] | VB->ClipMask[1];
1249 VB->ClipAndMask = VB->ClipMask[0] & VB->ClipMask[1];
1250 VB->MonoMaterial = !(VB->MaterialMask[0] | VB->MaterialMask[1]);
1251 break;
1252 case GL_TRIANGLE_FAN:
1253 copy_vertex( VB, 1, VB_MAX-1 );
1254 VB->Start = VB->Count = 2;
1255 VB->ClipOrMask = VB->ClipMask[0] | VB->ClipMask[1];
1256 VB->ClipAndMask = VB->ClipMask[0] & VB->ClipMask[1];
1257 VB->MonoMaterial = !(VB->MaterialMask[0] | VB->MaterialMask[1]);
1258 break;
1259 case GL_QUADS:
1260 ASSERT(VB->Start==0);
1261 VB->Start = VB->Count = 0;
1262 VB->ClipOrMask = 0;
1263 VB->ClipAndMask = CLIP_ALL_BITS;
1264 VB->MonoMaterial = GL_TRUE;
1265 VB->MonoNormal = GL_TRUE;
1266 break;
1267 case GL_QUAD_STRIP:
1268 copy_vertex( VB, 0, VB_MAX-2 );
1269 copy_vertex( VB, 1, VB_MAX-1 );
1270 VB->Start = VB->Count = 2;
1271 VB->ClipOrMask = VB->ClipMask[0] | VB->ClipMask[1];
1272 VB->ClipAndMask = VB->ClipMask[0] & VB->ClipMask[1];
1273 VB->MonoMaterial = !(VB->MaterialMask[0] | VB->MaterialMask[1]);
1274 break;
1275 case GL_POLYGON:
1276 copy_vertex( VB, 1, VB_MAX-1 );
1277 VB->Start = VB->Count = 2;
1278 VB->ClipOrMask = VB->ClipMask[0] | VB->ClipMask[1];
1279 VB->ClipAndMask = VB->ClipMask[0] & VB->ClipMask[1];
1280 VB->MonoMaterial = !(VB->MaterialMask[0] | VB->MaterialMask[1]);
1281 break;
1282 default:
1283 /* should never get here */
1284 gl_problem(ctx, "Bad primitive type in gl_reset_vb()");
1285 }
1286 }
1287
1288 if (clipOrMask) {
1289 /* reset clip masks to zero */
1290 MEMSET( VB->ClipMask + VB->Start, 0,
1291 (oldCount - VB->Start) * sizeof(VB->ClipMask[0]) );
1292 }
1293
1294 if (!monoMaterial) {
1295 /* reset material masks to zero */
1296 MEMSET( VB->MaterialMask + VB->Start, 0,
1297 (oldCount - VB->Start) * sizeof(VB->MaterialMask[0]) );
1299 }
1300
1301 if (vertexSizeMask!=VERTEX3_BIT) {
1302 /* reset object W coords to one */
1303 GLint i, n;
1304 GLfloat (*obj)[4] = VB->Obj + VB->Start;
1305 n = oldCount - VB->Start;
1306 for (i=0; i<n; i++) {
1307 obj[i][3] = 1.0F;
1308 }
1309 }
1310}
PBATCH_CONTEXT bc
Definition: batch.c:67
r l[0]
Definition: byte_order.h:168
GLuint gl_viewclip_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: clip.c:458
GLuint gl_userclip_line(GLcontext *ctx, GLuint *i, GLuint *j)
Definition: clip.c:798
GLuint gl_userclip_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: clip.c:902
GLuint gl_viewclip_line(GLcontext *ctx, GLuint *i, GLuint *j)
Definition: clip.c:283
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
#define printf
Definition: freeldr.h:93
unsigned char GLubyte
Definition: gl.h:157
#define GL_TRUE
Definition: gl.h:174
#define GL_POINT
Definition: gl.h:265
float GLfloat
Definition: gl.h:161
#define GL_QUADS
Definition: gl.h:197
#define GL_TRIANGLE_FAN
Definition: gl.h:196
#define GL_CW
Definition: gl.h:268
#define GL_LINE_STRIP
Definition: gl.h:193
#define GL_LINES
Definition: gl.h:191
unsigned int GLenum
Definition: gl.h:150
#define GL_TRIANGLES
Definition: gl.h:194
unsigned int GLuint
Definition: gl.h:159
#define GL_POINTS
Definition: gl.h:190
#define GL_LINE
Definition: gl.h:266
#define GL_FALSE
Definition: gl.h:173
#define GL_POLYGON
Definition: gl.h:199
#define GL_LINE_LOOP
Definition: gl.h:192
int GLint
Definition: gl.h:156
#define GL_TRIANGLE_STRIP
Definition: gl.h:195
unsigned char GLboolean
Definition: gl.h:151
#define GL_QUAD_STRIP
Definition: gl.h:198
GLbyte GLbyte tz
Definition: glext.h:8756
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum mode
Definition: glext.h:6217
GLenum GLenum dst
Definition: glext.h:6340
GLfloat v0
Definition: glext.h:6061
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:6064
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLbyte ty
Definition: glext.h:8756
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define c
Definition: ke_i.h:80
static real win[4][36]
GLint y0
Definition: linetemp.h:96
GLint x0
Definition: linetemp.h:95
#define MAX2(A, B)
Definition: macros.h:163
#define MEMSET(DST, VAL, N)
Definition: macros.h:241
#define COPY_3V(DST, SRC)
Definition: macros.h:98
#define COPY_4V(DST, SRC)
Definition: macros.h:102
#define ASSERT(a)
Definition: mode.c:44
int k
Definition: mpi.c:3369
int Count
Definition: noreturn.cpp:7
void gl_update_lighting(GLcontext *ctx)
Definition: light.c:770
static Real area(Real A[2], Real B[2], Real C[2])
Definition: polyDBG.cc:50
Definition: comerr.c:44
GLfloat TexCoord[VB_SIZE][4]
Definition: vb.h:117
GLubyte Bcolor[VB_SIZE][4]
Definition: vb.h:108
GLuint MaterialMask[VB_SIZE]
Definition: vb.h:134
GLfloat Win[VB_SIZE][3]
Definition: vb.h:103
GLfloat Clip[VB_SIZE][4]
Definition: vb.h:102
GLubyte Fcolor[VB_SIZE][4]
Definition: vb.h:107
GLboolean Edgeflag[VB_SIZE]
Definition: vb.h:115
struct gl_material Material[VB_SIZE][2]
Definition: vb.h:135
GLuint Bindex[VB_SIZE]
Definition: vb.h:112
GLfloat Eye[VB_SIZE][4]
Definition: vb.h:101
GLuint Findex[VB_SIZE]
Definition: vb.h:111
GLubyte ClipMask[VB_SIZE]
Definition: vb.h:119
GLfixed fx
Definition: tritemp.h:484
struct vertex_buffer * VB
Definition: tritemp.h:139
GLfixed fy
Definition: tritemp.h:490
#define VB_SIZE
Definition: vb.h:89
#define VB_MAX
Definition: vb.h:86
#define VERTEX3_BIT
Definition: vb.h:94
static void render_clipped_line(GLcontext *ctx, GLuint v1, GLuint v2)
Definition: vbrender.c:149
static void render_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: vbrender.c:362
static GLfloat polygon_area(const struct vertex_buffer *vb, GLuint n, const GLuint vlist[])
Definition: vbrender.c:337
static void unfilled_polygon(GLcontext *ctx, GLuint n, GLuint vlist[], GLuint pv, GLuint facing)
Definition: vbrender.c:265
#define START_PROFILE
Definition: vbrender.c:138
void gl_render_vb(GLcontext *ctx, GLboolean allDone)
Definition: vbrender.c:774
static void render_triangle(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
Definition: vbrender.c:601
void gl_reset_vb(GLcontext *ctx, GLboolean allDone)
Definition: vbrender.c:1155
#define END_PROFILE(TIMER, COUNTER, INCR)
Definition: vbrender.c:139
#define CLIP_ALL_BITS
Definition: vbrender.c:1144
static void render_clipped_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: vbrender.c:442
static void render_quad(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv)
Definition: vbrender.c:670
static void copy_vertex(struct vertex_buffer *vb, GLuint dst, GLuint src)
Definition: vbrender.c:742
static void offset_polygon(GLcontext *ctx, GLfloat a, GLfloat b, GLfloat c)
Definition: vbrender.c:234
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
#define TRANSFORM_POINT(Q, M, P)
Definition: xform.h:51