ReactOS  0.4.13-dev-257-gfabbd7c
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;
237  GLfloat offset;
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  */
265 static void unfilled_polygon( GLcontext *ctx,
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  */
337 static 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  */
362 static 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  */
442 static void render_clipped_polygon( GLcontext *ctx, GLuint n, GLuint vlist[] )
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  */
601 static void render_triangle( GLcontext *ctx,
602  GLuint v0, GLuint v1, GLuint v2, GLuint pv )
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  */
670 static void render_quad( GLcontext *ctx, GLuint v0, GLuint v1,
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  */
742 static 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  */
774 void gl_render_vb( GLcontext *ctx, GLboolean allDone )
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 
905  case GL_TRIANGLE_STRIP:
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  */
1155 void gl_reset_vb( GLcontext *ctx, GLboolean allDone )
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]) );
1298  gl_update_lighting(ctx);
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 }
static void unfilled_polygon(GLcontext *ctx, GLuint n, GLuint vlist[], GLuint pv, GLuint facing)
Definition: vbrender.c:265
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3706
#define GL_TRIANGLES
Definition: gl.h:194
static void copy_vertex(struct vertex_buffer *vb, GLuint dst, GLuint src)
Definition: vbrender.c:742
#define MEMSET(DST, VAL, N)
Definition: macros.h:241
Definition: comerr.c:44
GLubyte Bcolor[VB_SIZE][4]
Definition: vb.h:108
#define CLIP_ALL_BITS
Definition: vbrender.c:1144
#define GL_QUADS
Definition: gl.h:197
#define GL_POINTS
Definition: gl.h:190
GLint x0
Definition: linetemp.h:95
LPBATCH_CONTEXT bc
Definition: batch.c:66
unsigned char GLubyte
Definition: gl.h:157
GLuint gl_viewclip_line(GLcontext *ctx, GLuint *i, GLuint *j)
Definition: clip.c:283
#define GL_FALSE
Definition: gl.h:173
GLuint gl_userclip_line(GLcontext *ctx, GLuint *i, GLuint *j)
Definition: clip.c:798
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
struct gl_polygon_attrib Polygon
Definition: types.h:1330
GLfloat v0
Definition: glext.h:6061
GLintptr offset
Definition: glext.h:5920
GLdouble n
Definition: glext.h:7729
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
struct gl_current_attrib Current
Definition: types.h:1320
#define START_PROFILE
Definition: vbrender.c:138
void gl_update_lighting(GLcontext *ctx)
Definition: light.c:770
GLfloat PointZoffset
Definition: types.h:1366
void gl_reset_vb(GLcontext *ctx, GLboolean allDone)
Definition: vbrender.c:1155
GLuint StippleCounter
Definition: types.h:1358
const GLfloat * m
Definition: glext.h:10848
#define GL_LINE_LOOP
Definition: gl.h:192
GLboolean DirectTriangles
Definition: types.h:1363
#define TRANSFORM_POINT(Q, M, P)
Definition: xform.h:51
#define VERTEX3_BIT
Definition: vb.h:94
GLubyte ClipMask[VB_SIZE]
Definition: vb.h:119
struct dd_function_table Driver
Definition: types.h:1276
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
GLfloat TexCoord[VB_SIZE][4]
Definition: vb.h:117
#define MAX2(A, B)
Definition: macros.h:163
static void offset_polygon(GLcontext *ctx, GLfloat a, GLfloat b, GLfloat c)
Definition: vbrender.c:234
unsigned char GLboolean
Definition: gl.h:151
#define GL_LINE
Definition: gl.h:266
GLuint MaterialMask[VB_SIZE]
Definition: vb.h:134
GLubyte Fcolor[VB_SIZE][4]
Definition: vb.h:107
#define GL_TRIANGLE_FAN
Definition: gl.h:196
static void render_triangle(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
Definition: vbrender.c:601
GLenum Primitive
Definition: types.h:1357
#define GL_LINE_STRIP
Definition: gl.h:193
#define COPY_3V(DST, SRC)
Definition: macros.h:98
GLbyte ty
Definition: glext.h:8756
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
r l[0]
Definition: byte_order.h:167
GLuint Findex[VB_SIZE]
Definition: vb.h:111
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
static void render_quad(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv)
Definition: vbrender.c:670
#define GL_POINT
Definition: gl.h:265
const GLubyte * c
Definition: glext.h:8905
struct gl_material Material[VB_SIZE][2]
Definition: vb.h:135
GLboolean LightTwoSide
Definition: types.h:1362
GLfloat PolygonZoffset
Definition: types.h:1364
#define GL_LINES
Definition: gl.h:191
struct gl_transform_attrib Transform
Definition: types.h:1335
GLfloat Clip[VB_SIZE][4]
Definition: vb.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct vertex_buffer * VB
Definition: tritemp.h:139
#define VB_MAX
Definition: vb.h:86
GLfixed fx
Definition: tritemp.h:482
GLuint gl_viewclip_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: clip.c:458
GLenum src
Definition: glext.h:6340
unsigned int GLenum
Definition: gl.h:150
GLuint Bindex[VB_SIZE]
Definition: vb.h:112
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:6064
GLenum mode
Definition: glext.h:6217
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
GLfloat Eye[VB_SIZE][4]
Definition: vb.h:101
static void render_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: vbrender.c:362
GLfloat LineZoffset
Definition: types.h:1365
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
#define GL_QUAD_STRIP
Definition: gl.h:198
#define VB_SIZE
Definition: vb.h:89
static void render_clipped_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: vbrender.c:442
unsigned int GLuint
Definition: gl.h:159
static real win[4][36]
#define GL_TRUE
Definition: gl.h:174
GLenum GLenum dst
Definition: glext.h:6340
#define END_PROFILE(TIMER, COUNTER, INCR)
Definition: vbrender.c:139
GLint y0
Definition: linetemp.h:96
struct gl_viewport_attrib Viewport
Definition: types.h:1336
GLbyte GLbyte tz
Definition: glext.h:8756
#define GL_CW
Definition: gl.h:268
static Real area(Real A[2], Real B[2], Real C[2])
Definition: polyDBG.cc:50
#define GL_POLYGON
Definition: gl.h:199
GLuint gl_userclip_polygon(GLcontext *ctx, GLuint n, GLuint vlist[])
Definition: clip.c:902
float GLfloat
Definition: gl.h:161
GLboolean Edgeflag[VB_SIZE]
Definition: vb.h:115
GLfloat ProjectionMatrix[16]
Definition: types.h:1292
GLfloat Win[VB_SIZE][3]
Definition: vb.h:103
#define c
Definition: ke_i.h:80
static void render_clipped_line(GLcontext *ctx, GLuint v1, GLuint v2)
Definition: vbrender.c:149
int GLint
Definition: gl.h:156
#define GL_TRIANGLE_STRIP
Definition: gl.h:195
GLfixed fy
Definition: tritemp.h:490
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
struct vertex_buffer * VB
Definition: types.h:1380
void gl_render_vb(GLcontext *ctx, GLboolean allDone)
Definition: vbrender.c:774
static GLfloat polygon_area(const struct vertex_buffer *vb, GLuint n, const GLuint vlist[])
Definition: vbrender.c:337
GLfloat GLfloat v1
Definition: glext.h:6062
int k
Definition: mpi.c:3369
#define F(x, y, z)
Definition: md5.c:51
#define COPY_4V(DST, SRC)
Definition: macros.h:102
#define printf
Definition: config.h:203