home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tnl / t_vb_render.cpp < prev    next >
C/C++ Source or Header  |  2002-12-11  |  106KB  |  1,870 lines

  1. /* $Id: t_vb_render.c,v 1.33 2002/10/29 20:29:04 brianp Exp $ */
  2. /*
  3.  * Render whole vertex buffers, including projection of vertices from
  4.  * clip space and clipping of primitives.
  5.  *
  6.  * This file makes calls to project vertices and to the point, line
  7.  * and triangle rasterizers via the function pointers:
  8.  *
  9.  *    context->Driver.Render.*
  10.  *
  11.  */
  12.  
  13.  
  14. #include "glheader.h"
  15. #include "context.h"
  16. #include "enums.h"
  17. #include "macros.h"
  18. #include "imports.h"
  19. #include "mtypes.h"
  20. #include "mmath.h"
  21.  
  22. #include "math/m_matrix.h"
  23. #include "math/m_xform.h"
  24.  
  25. #include "t_pipeline.h"
  26.  
  27.  
  28.  
  29. /**********************************************************************/
  30. /*                        Clip single primitives                      */
  31. /**********************************************************************/
  32.  
  33.  
  34.  
  35.  
  36. /* $Id: t_vb_cliptmp.h,v 1.16 2002/10/29 20:29:03 brianp Exp $ */
  37.  
  38.  
  39.  
  40.  
  41.  
  42. /* Clip a line against the viewport and user clip planes.
  43.  */
  44. static  void
  45. clip_line_4( GLcontext *ctx, GLuint i, GLuint j, GLubyte mask )
  46. {
  47.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  48.    struct vertex_buffer *VB = &tnl->vb;
  49.    interp_func interp = tnl->Driver.Render.Interp;
  50.    GLfloat (*coord)[4] = VB->ClipPtr->data;
  51.    GLuint ii = i, jj = j, p;
  52.  
  53.    VB->LastClipped = VB->FirstClipped;
  54.  
  55.    if (mask & 0x3f) {
  56.       do { if (mask & 0x01) { GLfloat dpI = coord[ii][0]*-1 + coord[ii][1]*0 + coord[ii][2]*0 + coord[ii][3]*1; GLfloat dpJ = coord[jj][0]*-1 + coord[jj][1]*0 + coord[jj][2]*0 + coord[jj][3]*1; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x01; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x01; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  57.       do { if (mask & 0x02) { GLfloat dpI = coord[ii][0]*1 + coord[ii][1]*0 + coord[ii][2]*0 + coord[ii][3]*1; GLfloat dpJ = coord[jj][0]*1 + coord[jj][1]*0 + coord[jj][2]*0 + coord[jj][3]*1; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x02; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x02; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  58.       do { if (mask & 0x04) { GLfloat dpI = coord[ii][0]*0 + coord[ii][1]*-1 + coord[ii][2]*0 + coord[ii][3]*1; GLfloat dpJ = coord[jj][0]*0 + coord[jj][1]*-1 + coord[jj][2]*0 + coord[jj][3]*1; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x04; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x04; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  59.       do { if (mask & 0x08) { GLfloat dpI = coord[ii][0]*0 + coord[ii][1]*1 + coord[ii][2]*0 + coord[ii][3]*1; GLfloat dpJ = coord[jj][0]*0 + coord[jj][1]*1 + coord[jj][2]*0 + coord[jj][3]*1; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x08; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x08; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  60.       do { if (mask & 0x20) { GLfloat dpI = coord[ii][0]*0 + coord[ii][1]*0 + coord[ii][2]*-1 + coord[ii][3]*1; GLfloat dpJ = coord[jj][0]*0 + coord[jj][1]*0 + coord[jj][2]*-1 + coord[jj][3]*1; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x20; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x20; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  61.       do { if (mask & 0x10) { GLfloat dpI = coord[ii][0]*0 + coord[ii][1]*0 + coord[ii][2]*1 + coord[ii][3]*1; GLfloat dpJ = coord[jj][0]*0 + coord[jj][1]*0 + coord[jj][2]*1 + coord[jj][3]*1; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x10; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x10; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  62.    }
  63.  
  64.    if (mask & 0x40) {
  65.       for (p=0;p<6;p++) {
  66.      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  67.             const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
  68.             const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
  69.             const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
  70.             const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
  71.         do { if (mask & 0x40) { GLfloat dpI = coord[ii][0]*a + coord[ii][1]*b + coord[ii][2]*c + coord[ii][3]*d; GLfloat dpJ = coord[jj][0]*a + coord[jj][1]*b + coord[jj][2]*c + coord[jj][3]*d; if (((((fi_type *) &(dpI))->i ^ ((fi_type *) &(dpJ))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; if ((((fi_type *) &(dpJ))->i & (1<<31))) { GLfloat t = dpI / (dpI - dpJ); VB->ClipMask[jj] |= 0x40; do { coord[newvert][0] = (((coord[ii])[0]) + ((t)) * (((coord[jj])[0]) - ((coord[ii])[0]))); coord[newvert][1] = (((coord[ii])[1]) + ((t)) * (((coord[jj])[1]) - ((coord[ii])[1]))); coord[newvert][2] = (((coord[ii])[2]) + ((t)) * (((coord[jj])[2]) - ((coord[ii])[2]))); coord[newvert][3] = (((coord[ii])[3]) + ((t)) * (((coord[jj])[3]) - ((coord[ii])[3]))); } while (0); interp( ctx, t, newvert, ii, jj, 0x0 ); jj = newvert; } else { GLfloat t = dpJ / (dpJ - dpI); VB->ClipMask[ii] |= 0x40; do { coord[newvert][0] = (((coord[jj])[0]) + ((t)) * (((coord[ii])[0]) - ((coord[jj])[0]))); coord[newvert][1] = (((coord[jj])[1]) + ((t)) * (((coord[ii])[1]) - ((coord[jj])[1]))); coord[newvert][2] = (((coord[jj])[2]) + ((t)) * (((coord[ii])[2]) - ((coord[jj])[2]))); coord[newvert][3] = (((coord[jj])[3]) + ((t)) * (((coord[ii])[3]) - ((coord[jj])[3]))); } while (0); interp( ctx, t, newvert, jj, ii, 0x0 ); ii = newvert; } } else if ((((fi_type *) &(dpI))->i & (1<<31))) return; } } while (0);
  72.      }
  73.       }
  74.    }
  75.  
  76.    if ((ctx->_TriangleCaps & 0x1) && j != jj)
  77.       tnl->Driver.Render.CopyPV( ctx, jj, j );
  78.  
  79.    tnl->Driver.Render.ClippedLine( ctx, ii, jj );
  80. }
  81.  
  82.  
  83. /* Clip a triangle against the viewport and user clip planes.
  84.  */
  85. static  void
  86. clip_tri_4( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask )
  87. {
  88.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  89.    struct vertex_buffer *VB = &tnl->vb;
  90.    interp_func interp = tnl->Driver.Render.Interp;
  91.    GLfloat (*coord)[4] = VB->ClipPtr->data;
  92.    GLuint pv = v2;
  93.    GLuint vlist[2][((2 * (6 + 6))+1)];
  94.    GLuint *inlist = vlist[0], *outlist = vlist[1];
  95.    GLuint p;
  96.    GLubyte *clipmask = VB->ClipMask;
  97.    GLuint n = 3;
  98.  
  99.    do { inlist[0] = v2; inlist[1] = v0; inlist[2] = v1; } while(0); /* pv rotated to slot zero */
  100.  
  101.    VB->LastClipped = VB->FirstClipped;
  102.  
  103.    if (mask & 0x3f) {
  104.       do { if (mask & 0x01) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*-1 + coord[idxPrev][1]*0 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*-1 + coord[idx][1]*0 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x01; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x01; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  105.       do { if (mask & 0x02) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*1 + coord[idxPrev][1]*0 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*1 + coord[idx][1]*0 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x02; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x02; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  106.       do { if (mask & 0x04) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*-1 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*-1 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x04; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x04; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  107.       do { if (mask & 0x08) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*1 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*1 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x08; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x08; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  108.       do { if (mask & 0x20) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*0 + coord[idxPrev][2]*-1 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*0 + coord[idx][2]*-1 + coord[idx][3]*1; clipmask[idxPrev] |= 0x20; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x20; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  109.       do { if (mask & 0x10) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*0 + coord[idxPrev][2]*1 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*0 + coord[idx][2]*1 + coord[idx][3]*1; clipmask[idxPrev] |= 0x10; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x10; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  110.    }
  111.  
  112.    if (mask & 0x40) {
  113.       for (p=0;p<6;p++) {
  114.          if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  115.             const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
  116.             const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
  117.             const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
  118.             const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
  119.             do { if (mask & 0x40) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*a + coord[idxPrev][1]*b + coord[idxPrev][2]*c + coord[idxPrev][3]*d; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*a + coord[idx][1]*b + coord[idx][2]*c + coord[idx][3]*d; clipmask[idxPrev] |= 0x40; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x40; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  120.          }
  121.       }
  122.    }
  123.  
  124.    if (ctx->_TriangleCaps & 0x1) {
  125.       if (pv != inlist[0]) {
  126.      ;
  127.      tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
  128.       }
  129.    }
  130.  
  131.    tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
  132. }
  133.  
  134.  
  135. /* Clip a quad against the viewport and user clip planes.
  136.  */
  137. static  void
  138. clip_quad_4( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3,
  139.                 GLubyte mask )
  140. {
  141.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  142.    struct vertex_buffer *VB = &tnl->vb;
  143.    interp_func interp = tnl->Driver.Render.Interp;
  144.    GLfloat (*coord)[4] = VB->ClipPtr->data;
  145.    GLuint pv = v3;
  146.    GLuint vlist[2][((2 * (6 + 6))+1)];
  147.    GLuint *inlist = vlist[0], *outlist = vlist[1];
  148.    GLuint p;
  149.    GLubyte *clipmask = VB->ClipMask;
  150.    GLuint n = 4;
  151.  
  152.    do { inlist[0] = v3; inlist[1] = v0; inlist[2] = v1; inlist[3] = v2; } while(0); /* pv rotated to slot zero */
  153.  
  154.    VB->LastClipped = VB->FirstClipped;
  155.  
  156.    if (mask & 0x3f) {
  157.       do { if (mask & 0x01) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*-1 + coord[idxPrev][1]*0 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*-1 + coord[idx][1]*0 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x01; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x01; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  158.       do { if (mask & 0x02) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*1 + coord[idxPrev][1]*0 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*1 + coord[idx][1]*0 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x02; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x02; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  159.       do { if (mask & 0x04) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*-1 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*-1 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x04; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x04; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  160.       do { if (mask & 0x08) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*1 + coord[idxPrev][2]*0 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*1 + coord[idx][2]*0 + coord[idx][3]*1; clipmask[idxPrev] |= 0x08; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x08; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  161.       do { if (mask & 0x20) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*0 + coord[idxPrev][2]*-1 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*0 + coord[idx][2]*-1 + coord[idx][3]*1; clipmask[idxPrev] |= 0x20; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x20; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  162.       do { if (mask & 0x10) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*0 + coord[idxPrev][1]*0 + coord[idxPrev][2]*1 + coord[idxPrev][3]*1; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*0 + coord[idx][1]*0 + coord[idx][2]*1 + coord[idx][3]*1; clipmask[idxPrev] |= 0x10; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x10; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  163.    }
  164.  
  165.    if (mask & 0x40) {
  166.       for (p=0;p<6;p++) {
  167.      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  168.             const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
  169.             const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
  170.             const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
  171.             const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
  172.         do { if (mask & 0x40) { GLuint idxPrev = inlist[0]; GLfloat dpPrev = coord[idxPrev][0]*a + coord[idxPrev][1]*b + coord[idxPrev][2]*c + coord[idxPrev][3]*d; GLuint outcount = 0; GLuint i; inlist[n] = inlist[0]; for (i = 1; i <= n; i++) { GLuint idx = inlist[i]; GLfloat dp = coord[idx][0]*a + coord[idx][1]*b + coord[idx][2]*c + coord[idx][3]*d; clipmask[idxPrev] |= 0x40; if (!(((fi_type *) &(dpPrev))->i & (1<<31))) { outlist[outcount++] = idxPrev; clipmask[idxPrev] &= ~0x40; } if (((((fi_type *) &(dp))->i ^ ((fi_type *) &(dpPrev))->i) & (1<<31))) { GLuint newvert = VB->LastClipped++; VB->ClipMask[newvert] = 0; outlist[outcount++] = newvert; if ((((fi_type *) &(dp))->i & (1<<31))) { GLfloat t = dp / (dp - dpPrev); do { coord[newvert][0] = (((coord[idx])[0]) + ((t)) * (((coord[idxPrev])[0]) - ((coord[idx])[0]))); coord[newvert][1] = (((coord[idx])[1]) + ((t)) * (((coord[idxPrev])[1]) - ((coord[idx])[1]))); coord[newvert][2] = (((coord[idx])[2]) + ((t)) * (((coord[idxPrev])[2]) - ((coord[idx])[2]))); coord[newvert][3] = (((coord[idx])[3]) + ((t)) * (((coord[idxPrev])[3]) - ((coord[idx])[3]))); } while (0); interp( ctx, t, newvert, idx, idxPrev, 0x1 ); } else { GLfloat t = dpPrev / (dpPrev - dp); do { coord[newvert][0] = (((coord[idxPrev])[0]) + ((t)) * (((coord[idx])[0]) - ((coord[idxPrev])[0]))); coord[newvert][1] = (((coord[idxPrev])[1]) + ((t)) * (((coord[idx])[1]) - ((coord[idxPrev])[1]))); coord[newvert][2] = (((coord[idxPrev])[2]) + ((t)) * (((coord[idx])[2]) - ((coord[idxPrev])[2]))); coord[newvert][3] = (((coord[idxPrev])[3]) + ((t)) * (((coord[idx])[3]) - ((coord[idxPrev])[3]))); } while (0); interp( ctx, t, newvert, idxPrev, idx, 0x0 ); } } idxPrev = idx; dpPrev = dp; } if (outcount < 3) return; { GLuint *tmp = inlist; inlist = outlist; outlist = tmp; n = outcount; } } } while (0);
  173.      }
  174.       }
  175.    }
  176.  
  177.    if (ctx->_TriangleCaps & 0x1) {
  178.       if (pv != inlist[0]) {
  179.      ;
  180.      tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
  181.       }
  182.    }
  183.  
  184.    tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
  185. }
  186.  
  187.  
  188.  
  189.  
  190. /**********************************************************************/
  191. /*              Clip and render whole begin/end objects               */
  192. /**********************************************************************/
  193.  
  194.  
  195.  
  196. /* Vertices, with the possibility of clipping.
  197.  */
  198.  
  199.  
  200.  
  201. static void clip_render_points_verts( GLcontext *ctx,
  202.                 GLuint start,
  203.                 GLuint count,
  204.                 GLuint flags )
  205. {
  206.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  207.    (void) flags;
  208.  
  209.    ctx->OcclusionResult = 0x1;
  210.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0000 );
  211.    tnl->Driver.Render.Points( ctx, start, count );
  212.    ;
  213. }
  214.  
  215. static void clip_render_lines_verts( GLcontext *ctx,
  216.                    GLuint start,
  217.                    GLuint count,
  218.                    GLuint flags )
  219. {
  220.    GLuint j;
  221.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  222.    (void) flags;
  223.  
  224.    ctx->OcclusionResult = 0x1;
  225.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0001 );
  226.    for (j=start+1; j<count; j+=2 ) {
  227.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  228.       do { GLubyte c1 = mask[j-1], c2 = mask[j]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, j-1, j ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, j-1, j, ormask ); } while (0);
  229.    }
  230.    ;
  231. }
  232.  
  233.  
  234. static void clip_render_line_strip_verts( GLcontext *ctx,
  235.                     GLuint start,
  236.                     GLuint count,
  237.                     GLuint flags )
  238. {
  239.    GLuint j;
  240.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  241.    (void) flags;
  242.  
  243.    ctx->OcclusionResult = 0x1;
  244.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0003 );
  245.  
  246.    if ((flags & 0x100)) {
  247.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  248.    }
  249.  
  250.    for (j=start+1; j<count; j++ )
  251.       do { GLubyte c1 = mask[j-1], c2 = mask[j]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, j-1, j ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, j-1, j, ormask ); } while (0);
  252.  
  253.    ;
  254. }
  255.  
  256.  
  257. static void clip_render_line_loop_verts( GLcontext *ctx,
  258.                    GLuint start,
  259.                    GLuint count,
  260.                    GLuint flags )
  261. {
  262.    GLuint i;
  263.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  264.  
  265.    (void) flags;
  266.  
  267.    ctx->OcclusionResult = 0x1;
  268.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0002 );
  269.  
  270.    if (start+1 < count) {
  271.       if ((flags & 0x100)) {
  272.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  273.      do { GLubyte c1 = mask[start], c2 = mask[start+1]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, start, start+1 ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, start, start+1, ormask ); } while (0);
  274.       }
  275.  
  276.       for ( i = start+2 ; i < count ; i++) {
  277.      do { GLubyte c1 = mask[i-1], c2 = mask[i]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, i-1, i ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, i-1, i, ormask ); } while (0);
  278.       }
  279.  
  280.       if ( (flags & 0x200)) {
  281.      do { GLubyte c1 = mask[count-1], c2 = mask[start]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, count-1, start ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, count-1, start, ormask ); } while (0);
  282.       }
  283.    }
  284.  
  285.    ;
  286. }
  287.  
  288.  
  289. static void clip_render_triangles_verts( GLcontext *ctx,
  290.                    GLuint start,
  291.                    GLuint count,
  292.                    GLuint flags )
  293. {
  294.    GLuint j;
  295.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  296.    (void) flags;
  297.  
  298.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0004 );
  299.    if ((ctx->_TriangleCaps & 0x10)) {
  300.       for (j=start+2; j<count; j+=3) {
  301.      /* Leave the edgeflags as supplied by the user.
  302.       */
  303.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  304.      do { GLubyte c1 = mask[j-2], c2 = mask[j-1], c3 = mask[j]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-2, j-1, j ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-2, j-1, j, ormask ); } while (0);
  305.       }
  306.    } else {
  307.       for (j=start+2; j<count; j+=3) {
  308.      do { GLubyte c1 = mask[j-2], c2 = mask[j-1], c3 = mask[j]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-2, j-1, j ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-2, j-1, j, ormask ); } while (0);
  309.       }
  310.    }
  311.    ;
  312. }
  313.  
  314.  
  315.  
  316. static void clip_render_tri_strip_verts( GLcontext *ctx,
  317.                    GLuint start,
  318.                    GLuint count,
  319.                    GLuint flags )
  320. {
  321.    GLuint j;
  322.    GLuint parity = 0;
  323.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  324.  
  325.    if ((flags & 0x400))
  326.       parity = 1;
  327.  
  328.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0005 );
  329.    if ((ctx->_TriangleCaps & 0x10)) {
  330.       for (j=start+2;j<count;j++,parity^=1) {
  331.      GLuint ej2 = j-2+parity;
  332.      GLuint ej1 = j-1-parity;
  333.      GLuint ej = j;
  334.      GLboolean ef2 = VB->EdgeFlag[ej2];
  335.      GLboolean ef1 = VB->EdgeFlag[ej1];
  336.      GLboolean ef = VB->EdgeFlag[ej];
  337.      if ((flags & 0x100)) {
  338.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  339.      }
  340.      VB->EdgeFlag[ej2] = 0x1;
  341.      VB->EdgeFlag[ej1] = 0x1;
  342.      VB->EdgeFlag[ej] = 0x1;
  343.      do { GLubyte c1 = mask[ej2], c2 = mask[ej1], c3 = mask[ej]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, ej2, ej1, ej ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, ej2, ej1, ej, ormask ); } while (0);
  344.      VB->EdgeFlag[ej2] = ef2;
  345.      VB->EdgeFlag[ej1] = ef1;
  346.      VB->EdgeFlag[ej] = ef;
  347.       }
  348.    } else {
  349.       for (j=start+2; j<count ; j++, parity^=1) {
  350.      do { GLubyte c1 = mask[j-2+parity], c2 = mask[j-1-parity], c3 = mask[j]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-2+parity, j-1-parity, j ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-2+parity, j-1-parity, j, ormask ); } while (0);
  351.       }
  352.    }
  353.    ;
  354. }
  355.  
  356.  
  357. static void clip_render_tri_fan_verts( GLcontext *ctx,
  358.                  GLuint start,
  359.                  GLuint count,
  360.                  GLuint flags )
  361. {
  362.    GLuint j;
  363.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  364.    (void) flags;
  365.  
  366.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0006 );
  367.    if ((ctx->_TriangleCaps & 0x10)) {
  368.       for (j=start+2;j<count;j++) {
  369.      /* For trifans, all edges are boundary.
  370.       */
  371.      GLuint ejs = start;
  372.      GLuint ej1 = j-1;
  373.      GLuint ej = j;
  374.      GLboolean efs = VB->EdgeFlag[ejs];
  375.      GLboolean ef1 = VB->EdgeFlag[ej1];
  376.      GLboolean ef = VB->EdgeFlag[ej];
  377.      if ((flags & 0x100)) {
  378.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  379.      }
  380.      VB->EdgeFlag[ejs] = 0x1;
  381.      VB->EdgeFlag[ej1] = 0x1;
  382.      VB->EdgeFlag[ej] = 0x1;
  383.      do { GLubyte c1 = mask[ejs], c2 = mask[ej1], c3 = mask[ej]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, ejs, ej1, ej ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, ejs, ej1, ej, ormask ); } while (0);
  384.      VB->EdgeFlag[ejs] = efs;
  385.      VB->EdgeFlag[ej1] = ef1;
  386.      VB->EdgeFlag[ej] = ef;
  387.       }
  388.    } else {
  389.       for (j=start+2;j<count;j++) {
  390.      do { GLubyte c1 = mask[start], c2 = mask[j-1], c3 = mask[j]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, start, j-1, j ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, start, j-1, j, ormask ); } while (0);
  391.       }
  392.    }
  393.  
  394.    ;
  395. }
  396.  
  397.  
  398. static void clip_render_poly_verts( GLcontext *ctx,
  399.                   GLuint start,
  400.                   GLuint count,
  401.                   GLuint flags )
  402. {
  403.    GLuint j = start+2;
  404.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  405.    (void) flags;
  406.  
  407.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0009 );
  408.    if ((ctx->_TriangleCaps & 0x10)) {
  409.       GLboolean efstart = VB->EdgeFlag[start];
  410.       GLboolean efcount = VB->EdgeFlag[count-1];
  411.  
  412.       /* If the primitive does not begin here, the first edge
  413.        * is non-boundary.
  414.        */
  415.       if (!(flags & 0x100))
  416.      VB->EdgeFlag[start] = 0x0;
  417.       else {
  418.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  419.       }
  420.  
  421.       /* If the primitive does not end here, the final edge is
  422.        * non-boundary.
  423.        */
  424.       if (!(flags & 0x200))
  425.      VB->EdgeFlag[count-1] = 0x0;
  426.  
  427.       /* Draw the first triangles (possibly zero)
  428.        */
  429.       if (j+1<count) {
  430.      GLboolean ef = VB->EdgeFlag[j];
  431.      VB->EdgeFlag[j] = 0x0;
  432.      do { GLubyte c1 = mask[j-1], c2 = mask[j], c3 = mask[start]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-1, j, start ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-1, j, start, ormask ); } while (0);
  433.      VB->EdgeFlag[j] = ef;
  434.      j++;
  435.  
  436.      /* Don't render the first edge again:
  437.       */
  438.      VB->EdgeFlag[start] = 0x0;
  439.  
  440.      for (;j+1<count;j++) {
  441.         GLboolean efj = VB->EdgeFlag[j];
  442.         VB->EdgeFlag[j] = 0x0;
  443.         do { GLubyte c1 = mask[j-1], c2 = mask[j], c3 = mask[start]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-1, j, start ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-1, j, start, ormask ); } while (0);
  444.         VB->EdgeFlag[j] = efj;
  445.      }
  446.       }
  447.  
  448.       /* Draw the last or only triangle
  449.        */
  450.       if (j < count)
  451.      do { GLubyte c1 = mask[j-1], c2 = mask[j], c3 = mask[start]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-1, j, start ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-1, j, start, ormask ); } while (0);
  452.  
  453.       /* Restore the first and last edgeflags:
  454.        */
  455.       VB->EdgeFlag[count-1] = efcount;
  456.       VB->EdgeFlag[start] = efstart;
  457.  
  458.    }
  459.    else {
  460.       for (j=start+2;j<count;j++) {
  461.      do { GLubyte c1 = mask[j-1], c2 = mask[j], c3 = mask[start]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, j-1, j, start ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, j-1, j, start, ormask ); } while (0);
  462.       }
  463.    }
  464.    ;
  465. }
  466.  
  467. static void clip_render_quads_verts( GLcontext *ctx,
  468.                    GLuint start,
  469.                    GLuint count,
  470.                    GLuint flags )
  471. {
  472.    GLuint j;
  473.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  474.    (void) flags;
  475.  
  476.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0007 );
  477.    if ((ctx->_TriangleCaps & 0x10)) {
  478.       for (j=start+3; j<count; j+=4) {
  479.      /* Use user-specified edgeflags for quads.
  480.       */
  481.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  482.      do { GLubyte c1 = mask[j-3], c2 = mask[j-2]; GLubyte c3 = mask[j-1], c4 = mask[j]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, j-3, j-2, j-1, j ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, j-3, j-2, j-1, j, ormask ); } while (0);
  483.       }
  484.    } else {
  485.       for (j=start+3; j<count; j+=4) {
  486.      do { GLubyte c1 = mask[j-3], c2 = mask[j-2]; GLubyte c3 = mask[j-1], c4 = mask[j]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, j-3, j-2, j-1, j ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, j-3, j-2, j-1, j, ormask ); } while (0);
  487.       }
  488.    }
  489.    ;
  490. }
  491.  
  492. static void clip_render_quad_strip_verts( GLcontext *ctx,
  493.                     GLuint start,
  494.                     GLuint count,
  495.                     GLuint flags )
  496. {
  497.    GLuint j;
  498.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  499.    (void) flags;
  500.  
  501.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0008 );
  502.    if ((ctx->_TriangleCaps & 0x10)) {
  503.       for (j=start+3;j<count;j+=2) {
  504.      /* All edges are boundary.  Set edgeflags to 1, draw the
  505.       * quad, and restore them to the original values.
  506.       */
  507.      GLboolean ef3 = VB->EdgeFlag[j-3];
  508.      GLboolean ef2 = VB->EdgeFlag[j-2];
  509.      GLboolean ef1 = VB->EdgeFlag[j-1];
  510.      GLboolean ef = VB->EdgeFlag[j];
  511.      if ((flags & 0x100)) {
  512.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  513.      }
  514.      VB->EdgeFlag[j-3] = 0x1;
  515.      VB->EdgeFlag[j-2] = 0x1;
  516.      VB->EdgeFlag[j-1] = 0x1;
  517.      VB->EdgeFlag[j] = 0x1;
  518.      do { GLubyte c1 = mask[j-1], c2 = mask[j-3]; GLubyte c3 = mask[j-2], c4 = mask[j]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, j-1, j-3, j-2, j ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, j-1, j-3, j-2, j, ormask ); } while (0);
  519.      VB->EdgeFlag[j-3] = ef3;
  520.      VB->EdgeFlag[j-2] = ef2;
  521.      VB->EdgeFlag[j-1] = ef1;
  522.      VB->EdgeFlag[j] = ef;
  523.       }
  524.    } else {
  525.       for (j=start+3;j<count;j+=2) {
  526.      do { GLubyte c1 = mask[j-1], c2 = mask[j-3]; GLubyte c3 = mask[j-2], c4 = mask[j]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, j-1, j-3, j-2, j ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, j-1, j-3, j-2, j, ormask ); } while (0);
  527.       }
  528.    }
  529.    ;
  530. }
  531.  
  532. static void clip_render_noop_verts( GLcontext *ctx,
  533.                   GLuint start,
  534.                   GLuint count,
  535.                   GLuint flags )
  536. {
  537.    (void)(ctx && start && count && flags);
  538. }
  539.  
  540. static void (*clip_render_tab_verts[0x0009+2])(GLcontext *,
  541.                                GLuint,
  542.                                GLuint,
  543.                                GLuint) =
  544. {
  545.    clip_render_points_verts,
  546.    clip_render_lines_verts,
  547.    clip_render_line_loop_verts,
  548.    clip_render_line_strip_verts,
  549.    clip_render_triangles_verts,
  550.    clip_render_tri_strip_verts,
  551.    clip_render_tri_fan_verts,
  552.    clip_render_quads_verts,
  553.    clip_render_quad_strip_verts,
  554.    clip_render_poly_verts,
  555.    clip_render_noop_verts,
  556. };
  557.  
  558.  
  559.  
  560. /* Elts, with the possibility of clipping.
  561.  */
  562.  
  563. static void clip_render_points_elts( GLcontext *ctx,
  564.                 GLuint start,
  565.                 GLuint count,
  566.                 GLuint flags )
  567. {
  568.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  569.    (void) flags;
  570.  
  571.    ctx->OcclusionResult = 0x1;
  572.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0000 );
  573.    tnl->Driver.Render.Points( ctx, start, count );
  574.    ;
  575. }
  576.  
  577. static void clip_render_lines_elts( GLcontext *ctx,
  578.                    GLuint start,
  579.                    GLuint count,
  580.                    GLuint flags )
  581. {
  582.    GLuint j;
  583.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  584.    (void) flags;
  585.  
  586.    ctx->OcclusionResult = 0x1;
  587.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0001 );
  588.    for (j=start+1; j<count; j+=2 ) {
  589.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  590.       do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j]]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, elt[j-1], elt[j] ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, elt[j-1], elt[j], ormask ); } while (0);
  591.    }
  592.    ;
  593. }
  594.  
  595.  
  596. static void clip_render_line_strip_elts( GLcontext *ctx,
  597.                     GLuint start,
  598.                     GLuint count,
  599.                     GLuint flags )
  600. {
  601.    GLuint j;
  602.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  603.    (void) flags;
  604.  
  605.    ctx->OcclusionResult = 0x1;
  606.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0003 );
  607.  
  608.    if ((flags & 0x100)) {
  609.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  610.    }
  611.  
  612.    for (j=start+1; j<count; j++ )
  613.       do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j]]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, elt[j-1], elt[j] ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, elt[j-1], elt[j], ormask ); } while (0);
  614.  
  615.    ;
  616. }
  617.  
  618.  
  619. static void clip_render_line_loop_elts( GLcontext *ctx,
  620.                    GLuint start,
  621.                    GLuint count,
  622.                    GLuint flags )
  623. {
  624.    GLuint i;
  625.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  626.  
  627.    (void) flags;
  628.  
  629.    ctx->OcclusionResult = 0x1;
  630.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0002 );
  631.  
  632.    if (start+1 < count) {
  633.       if ((flags & 0x100)) {
  634.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  635.      do { GLubyte c1 = mask[elt[start]], c2 = mask[elt[start+1]]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, elt[start], elt[start+1] ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, elt[start], elt[start+1], ormask ); } while (0);
  636.       }
  637.  
  638.       for ( i = start+2 ; i < count ; i++) {
  639.      do { GLubyte c1 = mask[elt[i-1]], c2 = mask[elt[i]]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, elt[i-1], elt[i] ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, elt[i-1], elt[i], ormask ); } while (0);
  640.       }
  641.  
  642.       if ( (flags & 0x200)) {
  643.      do { GLubyte c1 = mask[elt[count-1]], c2 = mask[elt[start]]; GLubyte ormask = c1|c2; if (!ormask) LineFunc( ctx, elt[count-1], elt[start] ); else if (!(c1 & c2 & 0x3f)) clip_line_4( ctx, elt[count-1], elt[start], ormask ); } while (0);
  644.       }
  645.    }
  646.  
  647.    ;
  648. }
  649.  
  650.  
  651. static void clip_render_triangles_elts( GLcontext *ctx,
  652.                    GLuint start,
  653.                    GLuint count,
  654.                    GLuint flags )
  655. {
  656.    GLuint j;
  657.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  658.    (void) flags;
  659.  
  660.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0004 );
  661.    if ((ctx->_TriangleCaps & 0x10)) {
  662.       for (j=start+2; j<count; j+=3) {
  663.      /* Leave the edgeflags as supplied by the user.
  664.       */
  665.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  666.      do { GLubyte c1 = mask[elt[j-2]], c2 = mask[elt[j-1]], c3 = mask[elt[j]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-2], elt[j-1], elt[j] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-2], elt[j-1], elt[j], ormask ); } while (0);
  667.       }
  668.    } else {
  669.       for (j=start+2; j<count; j+=3) {
  670.      do { GLubyte c1 = mask[elt[j-2]], c2 = mask[elt[j-1]], c3 = mask[elt[j]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-2], elt[j-1], elt[j] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-2], elt[j-1], elt[j], ormask ); } while (0);
  671.       }
  672.    }
  673.    ;
  674. }
  675.  
  676.  
  677.  
  678. static void clip_render_tri_strip_elts( GLcontext *ctx,
  679.                    GLuint start,
  680.                    GLuint count,
  681.                    GLuint flags )
  682. {
  683.    GLuint j;
  684.    GLuint parity = 0;
  685.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  686.  
  687.    if ((flags & 0x400))
  688.       parity = 1;
  689.  
  690.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0005 );
  691.    if ((ctx->_TriangleCaps & 0x10)) {
  692.       for (j=start+2;j<count;j++,parity^=1) {
  693.      GLuint ej2 = elt[j-2+parity];
  694.      GLuint ej1 = elt[j-1-parity];
  695.      GLuint ej = elt[j];
  696.      GLboolean ef2 = VB->EdgeFlag[ej2];
  697.      GLboolean ef1 = VB->EdgeFlag[ej1];
  698.      GLboolean ef = VB->EdgeFlag[ej];
  699.      if ((flags & 0x100)) {
  700.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  701.      }
  702.      VB->EdgeFlag[ej2] = 0x1;
  703.      VB->EdgeFlag[ej1] = 0x1;
  704.      VB->EdgeFlag[ej] = 0x1;
  705.      do { GLubyte c1 = mask[ej2], c2 = mask[ej1], c3 = mask[ej]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, ej2, ej1, ej ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, ej2, ej1, ej, ormask ); } while (0);
  706.      VB->EdgeFlag[ej2] = ef2;
  707.      VB->EdgeFlag[ej1] = ef1;
  708.      VB->EdgeFlag[ej] = ef;
  709.       }
  710.    } else {
  711.       for (j=start+2; j<count ; j++, parity^=1) {
  712.      do { GLubyte c1 = mask[elt[j-2+parity]], c2 = mask[elt[j-1-parity]], c3 = mask[elt[j]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-2+parity], elt[j-1-parity], elt[j] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-2+parity], elt[j-1-parity], elt[j], ormask ); } while (0);
  713.       }
  714.    }
  715.    ;
  716. }
  717.  
  718.  
  719. static void clip_render_tri_fan_elts( GLcontext *ctx,
  720.                  GLuint start,
  721.                  GLuint count,
  722.                  GLuint flags )
  723. {
  724.    GLuint j;
  725.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  726.    (void) flags;
  727.  
  728.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0006 );
  729.    if ((ctx->_TriangleCaps & 0x10)) {
  730.       for (j=start+2;j<count;j++) {
  731.      /* For trifans, all edges are boundary.
  732.       */
  733.      GLuint ejs = elt[start];
  734.      GLuint ej1 = elt[j-1];
  735.      GLuint ej = elt[j];
  736.      GLboolean efs = VB->EdgeFlag[ejs];
  737.      GLboolean ef1 = VB->EdgeFlag[ej1];
  738.      GLboolean ef = VB->EdgeFlag[ej];
  739.      if ((flags & 0x100)) {
  740.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  741.      }
  742.      VB->EdgeFlag[ejs] = 0x1;
  743.      VB->EdgeFlag[ej1] = 0x1;
  744.      VB->EdgeFlag[ej] = 0x1;
  745.      do { GLubyte c1 = mask[ejs], c2 = mask[ej1], c3 = mask[ej]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, ejs, ej1, ej ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, ejs, ej1, ej, ormask ); } while (0);
  746.      VB->EdgeFlag[ejs] = efs;
  747.      VB->EdgeFlag[ej1] = ef1;
  748.      VB->EdgeFlag[ej] = ef;
  749.       }
  750.    } else {
  751.       for (j=start+2;j<count;j++) {
  752.      do { GLubyte c1 = mask[elt[start]], c2 = mask[elt[j-1]], c3 = mask[elt[j]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[start], elt[j-1], elt[j] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[start], elt[j-1], elt[j], ormask ); } while (0);
  753.       }
  754.    }
  755.  
  756.    ;
  757. }
  758.  
  759.  
  760. static void clip_render_poly_elts( GLcontext *ctx,
  761.                   GLuint start,
  762.                   GLuint count,
  763.                   GLuint flags )
  764. {
  765.    GLuint j = start+2;
  766.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  767.    (void) flags;
  768.  
  769.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0009 );
  770.    if ((ctx->_TriangleCaps & 0x10)) {
  771.       GLboolean efstart = VB->EdgeFlag[elt[start]];
  772.       GLboolean efcount = VB->EdgeFlag[elt[count-1]];
  773.  
  774.       /* If the primitive does not begin here, the first edge
  775.        * is non-boundary.
  776.        */
  777.       if (!(flags & 0x100))
  778.      VB->EdgeFlag[elt[start]] = 0x0;
  779.       else {
  780.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  781.       }
  782.  
  783.       /* If the primitive does not end here, the final edge is
  784.        * non-boundary.
  785.        */
  786.       if (!(flags & 0x200))
  787.      VB->EdgeFlag[elt[count-1]] = 0x0;
  788.  
  789.       /* Draw the first triangles (possibly zero)
  790.        */
  791.       if (j+1<count) {
  792.      GLboolean ef = VB->EdgeFlag[elt[j]];
  793.      VB->EdgeFlag[elt[j]] = 0x0;
  794.      do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j]], c3 = mask[elt[start]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-1], elt[j], elt[start] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-1], elt[j], elt[start], ormask ); } while (0);
  795.      VB->EdgeFlag[elt[j]] = ef;
  796.      j++;
  797.  
  798.      /* Don't render the first edge again:
  799.       */
  800.      VB->EdgeFlag[elt[start]] = 0x0;
  801.  
  802.      for (;j+1<count;j++) {
  803.         GLboolean efj = VB->EdgeFlag[elt[j]];
  804.         VB->EdgeFlag[elt[j]] = 0x0;
  805.         do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j]], c3 = mask[elt[start]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-1], elt[j], elt[start] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-1], elt[j], elt[start], ormask ); } while (0);
  806.         VB->EdgeFlag[elt[j]] = efj;
  807.      }
  808.       }
  809.  
  810.       /* Draw the last or only triangle
  811.        */
  812.       if (j < count)
  813.      do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j]], c3 = mask[elt[start]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-1], elt[j], elt[start] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-1], elt[j], elt[start], ormask ); } while (0);
  814.  
  815.       /* Restore the first and last edgeflags:
  816.        */
  817.       VB->EdgeFlag[elt[count-1]] = efcount;
  818.       VB->EdgeFlag[elt[start]] = efstart;
  819.  
  820.    }
  821.    else {
  822.       for (j=start+2;j<count;j++) {
  823.      do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j]], c3 = mask[elt[start]]; GLubyte ormask = c1|c2|c3; if (!ormask) TriangleFunc( ctx, elt[j-1], elt[j], elt[start] ); else if (!(c1 & c2 & c3 & 0x3f)) clip_tri_4( ctx, elt[j-1], elt[j], elt[start], ormask ); } while (0);
  824.       }
  825.    }
  826.    ;
  827. }
  828.  
  829. static void clip_render_quads_elts( GLcontext *ctx,
  830.                    GLuint start,
  831.                    GLuint count,
  832.                    GLuint flags )
  833. {
  834.    GLuint j;
  835.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  836.    (void) flags;
  837.  
  838.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0007 );
  839.    if ((ctx->_TriangleCaps & 0x10)) {
  840.       for (j=start+3; j<count; j+=4) {
  841.      /* Use user-specified edgeflags for quads.
  842.       */
  843.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  844.      do { GLubyte c1 = mask[elt[j-3]], c2 = mask[elt[j-2]]; GLubyte c3 = mask[elt[j-1]], c4 = mask[elt[j]]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, elt[j-3], elt[j-2], elt[j-1], elt[j] ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, elt[j-3], elt[j-2], elt[j-1], elt[j], ormask ); } while (0);
  845.       }
  846.    } else {
  847.       for (j=start+3; j<count; j+=4) {
  848.      do { GLubyte c1 = mask[elt[j-3]], c2 = mask[elt[j-2]]; GLubyte c3 = mask[elt[j-1]], c4 = mask[elt[j]]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, elt[j-3], elt[j-2], elt[j-1], elt[j] ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, elt[j-3], elt[j-2], elt[j-1], elt[j], ormask ); } while (0);
  849.       }
  850.    }
  851.    ;
  852. }
  853.  
  854. static void clip_render_quad_strip_elts( GLcontext *ctx,
  855.                     GLuint start,
  856.                     GLuint count,
  857.                     GLuint flags )
  858. {
  859.    GLuint j;
  860.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const GLubyte *mask = VB->ClipMask; const GLuint sz = VB->ClipPtr->size; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) mask; (void) sz; (void) stipple;;
  861.    (void) flags;
  862.  
  863.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0008 );
  864.    if ((ctx->_TriangleCaps & 0x10)) {
  865.       for (j=start+3;j<count;j+=2) {
  866.      /* All edges are boundary.  Set edgeflags to 1, draw the
  867.       * quad, and restore them to the original values.
  868.       */
  869.      GLboolean ef3 = VB->EdgeFlag[elt[j-3]];
  870.      GLboolean ef2 = VB->EdgeFlag[elt[j-2]];
  871.      GLboolean ef1 = VB->EdgeFlag[elt[j-1]];
  872.      GLboolean ef = VB->EdgeFlag[elt[j]];
  873.      if ((flags & 0x100)) {
  874.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  875.      }
  876.      VB->EdgeFlag[elt[j-3]] = 0x1;
  877.      VB->EdgeFlag[elt[j-2]] = 0x1;
  878.      VB->EdgeFlag[elt[j-1]] = 0x1;
  879.      VB->EdgeFlag[elt[j]] = 0x1;
  880.      do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j-3]]; GLubyte c3 = mask[elt[j-2]], c4 = mask[elt[j]]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, elt[j-1], elt[j-3], elt[j-2], elt[j] ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, elt[j-1], elt[j-3], elt[j-2], elt[j], ormask ); } while (0);
  881.      VB->EdgeFlag[elt[j-3]] = ef3;
  882.      VB->EdgeFlag[elt[j-2]] = ef2;
  883.      VB->EdgeFlag[elt[j-1]] = ef1;
  884.      VB->EdgeFlag[elt[j]] = ef;
  885.       }
  886.    } else {
  887.       for (j=start+3;j<count;j+=2) {
  888.      do { GLubyte c1 = mask[elt[j-1]], c2 = mask[elt[j-3]]; GLubyte c3 = mask[elt[j-2]], c4 = mask[elt[j]]; GLubyte ormask = c1|c2|c3|c4; if (!ormask) QuadFunc( ctx, elt[j-1], elt[j-3], elt[j-2], elt[j] ); else if (!(c1 & c2 & c3 & c4 & 0x3f)) clip_quad_4( ctx, elt[j-1], elt[j-3], elt[j-2], elt[j], ormask ); } while (0);
  889.       }
  890.    }
  891.    ;
  892. }
  893.  
  894. static void clip_render_noop_elts( GLcontext *ctx,
  895.                   GLuint start,
  896.                   GLuint count,
  897.                   GLuint flags )
  898. {
  899.    (void)(ctx && start && count && flags);
  900. }
  901.  
  902. static void (*clip_render_tab_elts[0x0009+2])(GLcontext *,
  903.                                GLuint,
  904.                                GLuint,
  905.                                GLuint) =
  906. {
  907.    clip_render_points_elts,
  908.    clip_render_lines_elts,
  909.    clip_render_line_loop_elts,
  910.    clip_render_line_strip_elts,
  911.    clip_render_triangles_elts,
  912.    clip_render_tri_strip_elts,
  913.    clip_render_tri_fan_elts,
  914.    clip_render_quads_elts,
  915.    clip_render_quad_strip_elts,
  916.    clip_render_poly_elts,
  917.    clip_render_noop_elts,
  918. };
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925. /* TODO: do this for all primitives, verts and elts:
  926.  */
  927. static void clip_elt_triangles( GLcontext *ctx,
  928.                 GLuint start,
  929.                 GLuint count,
  930.                 GLuint flags )
  931. {
  932.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  933.    render_func render_tris = tnl->Driver.Render.PrimTabElts[0x0004];
  934.    struct vertex_buffer *VB = &tnl->vb;
  935.    const GLuint * const elt = VB->Elts;
  936.    GLubyte *mask = VB->ClipMask;
  937.    GLuint last = count-2;
  938.    GLuint j;
  939.    (void) flags;
  940.  
  941.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0004 );
  942.  
  943.    for (j=start; j < last; j+=3 ) {
  944.       GLubyte c1 = mask[elt[j]];
  945.       GLubyte c2 = mask[elt[j+1]];
  946.       GLubyte c3 = mask[elt[j+2]];
  947.       GLubyte ormask = c1|c2|c3;
  948.       if (ormask) {
  949.      if (start < j)
  950.         render_tris( ctx, start, j, 0 );
  951.      if (!(c1&c2&c3&0x3f))
  952.         clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask );
  953.      start = j+3;
  954.       }
  955.    }
  956.  
  957.    if (start < j)
  958.       render_tris( ctx, start, j, 0 );
  959. }
  960.  
  961. /**********************************************************************/
  962. /*                  Render whole begin/end objects                    */
  963. /**********************************************************************/
  964.  
  965.  
  966.  
  967. /* Vertices, no clipping.
  968.  */
  969.  
  970.  
  971. /* $Id: t_vb_rendertmp.h,v 1.10 2002/10/29 20:29:04 brianp Exp $ */
  972.  
  973.  
  974. static void _tnl_render_points_verts( GLcontext *ctx,
  975.                 GLuint start,
  976.                 GLuint count,
  977.                 GLuint flags )
  978. {
  979.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  980.    (void) flags;
  981.  
  982.    ctx->OcclusionResult = 0x1;
  983.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0000 );
  984.    tnl->Driver.Render.Points( ctx, start, count );
  985.    ;
  986. }
  987.  
  988. static void _tnl_render_lines_verts( GLcontext *ctx,
  989.                    GLuint start,
  990.                    GLuint count,
  991.                    GLuint flags )
  992. {
  993.    GLuint j;
  994.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  995.    (void) flags;
  996.  
  997.    ctx->OcclusionResult = 0x1;
  998.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0001 );
  999.    for (j=start+1; j<count; j+=2 ) {
  1000.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1001.       LineFunc( ctx, j-1, j );
  1002.    }
  1003.    ;
  1004. }
  1005.  
  1006.  
  1007. static void _tnl_render_line_strip_verts( GLcontext *ctx,
  1008.                     GLuint start,
  1009.                     GLuint count,
  1010.                     GLuint flags )
  1011. {
  1012.    GLuint j;
  1013.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1014.    (void) flags;
  1015.  
  1016.    ctx->OcclusionResult = 0x1;
  1017.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0003 );
  1018.  
  1019.    if ((flags & 0x100)) {
  1020.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1021.    }
  1022.  
  1023.    for (j=start+1; j<count; j++ )
  1024.       LineFunc( ctx, j-1, j );
  1025.  
  1026.    ;
  1027. }
  1028.  
  1029.  
  1030. static void _tnl_render_line_loop_verts( GLcontext *ctx,
  1031.                    GLuint start,
  1032.                    GLuint count,
  1033.                    GLuint flags )
  1034. {
  1035.    GLuint i;
  1036.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1037.  
  1038.    (void) flags;
  1039.  
  1040.    ctx->OcclusionResult = 0x1;
  1041.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0002 );
  1042.  
  1043.    if (start+1 < count) {
  1044.       if ((flags & 0x100)) {
  1045.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1046.      LineFunc( ctx, start, start+1 );
  1047.       }
  1048.  
  1049.       for ( i = start+2 ; i < count ; i++) {
  1050.      LineFunc( ctx, i-1, i );
  1051.       }
  1052.  
  1053.       if ( (flags & 0x200)) {
  1054.      LineFunc( ctx, count-1, start );
  1055.       }
  1056.    }
  1057.  
  1058.    ;
  1059. }
  1060.  
  1061.  
  1062. static void _tnl_render_triangles_verts( GLcontext *ctx,
  1063.                    GLuint start,
  1064.                    GLuint count,
  1065.                    GLuint flags )
  1066. {
  1067.    GLuint j;
  1068.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1069.    (void) flags;
  1070.  
  1071.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0004 );
  1072.    if ((ctx->_TriangleCaps & 0x10)) {
  1073.       for (j=start+2; j<count; j+=3) {
  1074.      /* Leave the edgeflags as supplied by the user.
  1075.       */
  1076.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1077.      TriangleFunc( ctx, j-2, j-1, j );
  1078.       }
  1079.    } else {
  1080.       for (j=start+2; j<count; j+=3) {
  1081.      TriangleFunc( ctx, j-2, j-1, j );
  1082.       }
  1083.    }
  1084.    ;
  1085. }
  1086.  
  1087.  
  1088.  
  1089. static void _tnl_render_tri_strip_verts( GLcontext *ctx,
  1090.                    GLuint start,
  1091.                    GLuint count,
  1092.                    GLuint flags )
  1093. {
  1094.    GLuint j;
  1095.    GLuint parity = 0;
  1096.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1097.  
  1098.    if ((flags & 0x400))
  1099.       parity = 1;
  1100.  
  1101.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0005 );
  1102.    if ((ctx->_TriangleCaps & 0x10)) {
  1103.       for (j=start+2;j<count;j++,parity^=1) {
  1104.      GLuint ej2 = j-2+parity;
  1105.      GLuint ej1 = j-1-parity;
  1106.      GLuint ej = j;
  1107.      GLboolean ef2 = VB->EdgeFlag[ej2];
  1108.      GLboolean ef1 = VB->EdgeFlag[ej1];
  1109.      GLboolean ef = VB->EdgeFlag[ej];
  1110.      if ((flags & 0x100)) {
  1111.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1112.      }
  1113.      VB->EdgeFlag[ej2] = 0x1;
  1114.      VB->EdgeFlag[ej1] = 0x1;
  1115.      VB->EdgeFlag[ej] = 0x1;
  1116.      TriangleFunc( ctx, ej2, ej1, ej );
  1117.      VB->EdgeFlag[ej2] = ef2;
  1118.      VB->EdgeFlag[ej1] = ef1;
  1119.      VB->EdgeFlag[ej] = ef;
  1120.       }
  1121.    } else {
  1122.       for (j=start+2; j<count ; j++, parity^=1) {
  1123.      TriangleFunc( ctx, j-2+parity, j-1-parity, j );
  1124.       }
  1125.    }
  1126.    ;
  1127. }
  1128.  
  1129.  
  1130. static void _tnl_render_tri_fan_verts( GLcontext *ctx,
  1131.                  GLuint start,
  1132.                  GLuint count,
  1133.                  GLuint flags )
  1134. {
  1135.    GLuint j;
  1136.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1137.    (void) flags;
  1138.  
  1139.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0006 );
  1140.    if ((ctx->_TriangleCaps & 0x10)) {
  1141.       for (j=start+2;j<count;j++) {
  1142.      /* For trifans, all edges are boundary.
  1143.       */
  1144.      GLuint ejs = start;
  1145.      GLuint ej1 = j-1;
  1146.      GLuint ej = j;
  1147.      GLboolean efs = VB->EdgeFlag[ejs];
  1148.      GLboolean ef1 = VB->EdgeFlag[ej1];
  1149.      GLboolean ef = VB->EdgeFlag[ej];
  1150.      if ((flags & 0x100)) {
  1151.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1152.      }
  1153.      VB->EdgeFlag[ejs] = 0x1;
  1154.      VB->EdgeFlag[ej1] = 0x1;
  1155.      VB->EdgeFlag[ej] = 0x1;
  1156.      TriangleFunc( ctx, ejs, ej1, ej );
  1157.      VB->EdgeFlag[ejs] = efs;
  1158.      VB->EdgeFlag[ej1] = ef1;
  1159.      VB->EdgeFlag[ej] = ef;
  1160.       }
  1161.    } else {
  1162.       for (j=start+2;j<count;j++) {
  1163.      TriangleFunc( ctx, start, j-1, j );
  1164.       }
  1165.    }
  1166.  
  1167.    ;
  1168. }
  1169.  
  1170.  
  1171. static void _tnl_render_poly_verts( GLcontext *ctx,
  1172.                   GLuint start,
  1173.                   GLuint count,
  1174.                   GLuint flags )
  1175. {
  1176.    GLuint j = start+2;
  1177.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1178.    (void) flags;
  1179.  
  1180.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0009 );
  1181.    if ((ctx->_TriangleCaps & 0x10)) {
  1182.       GLboolean efstart = VB->EdgeFlag[start];
  1183.       GLboolean efcount = VB->EdgeFlag[count-1];
  1184.  
  1185.       /* If the primitive does not begin here, the first edge
  1186.        * is non-boundary.
  1187.        */
  1188.       if (!(flags & 0x100))
  1189.      VB->EdgeFlag[start] = 0x0;
  1190.       else {
  1191.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1192.       }
  1193.  
  1194.       /* If the primitive does not end here, the final edge is
  1195.        * non-boundary.
  1196.        */
  1197.       if (!(flags & 0x200))
  1198.      VB->EdgeFlag[count-1] = 0x0;
  1199.  
  1200.       /* Draw the first triangles (possibly zero)
  1201.        */
  1202.       if (j+1<count) {
  1203.      GLboolean ef = VB->EdgeFlag[j];
  1204.      VB->EdgeFlag[j] = 0x0;
  1205.      TriangleFunc( ctx, j-1, j, start );
  1206.      VB->EdgeFlag[j] = ef;
  1207.      j++;
  1208.  
  1209.      /* Don't render the first edge again:
  1210.       */
  1211.      VB->EdgeFlag[start] = 0x0;
  1212.  
  1213.      for (;j+1<count;j++) {
  1214.         GLboolean efj = VB->EdgeFlag[j];
  1215.         VB->EdgeFlag[j] = 0x0;
  1216.         TriangleFunc( ctx, j-1, j, start );
  1217.         VB->EdgeFlag[j] = efj;
  1218.      }
  1219.       }
  1220.  
  1221.       /* Draw the last or only triangle
  1222.        */
  1223.       if (j < count)
  1224.      TriangleFunc( ctx, j-1, j, start );
  1225.  
  1226.       /* Restore the first and last edgeflags:
  1227.        */
  1228.       VB->EdgeFlag[count-1] = efcount;
  1229.       VB->EdgeFlag[start] = efstart;
  1230.  
  1231.    }
  1232.    else {
  1233.       for (j=start+2;j<count;j++) {
  1234.      TriangleFunc( ctx, j-1, j, start );
  1235.       }
  1236.    }
  1237.    ;
  1238. }
  1239.  
  1240. static void _tnl_render_quads_verts( GLcontext *ctx,
  1241.                    GLuint start,
  1242.                    GLuint count,
  1243.                    GLuint flags )
  1244. {
  1245.    GLuint j;
  1246.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1247.    (void) flags;
  1248.  
  1249.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0007 );
  1250.    if ((ctx->_TriangleCaps & 0x10)) {
  1251.       for (j=start+3; j<count; j+=4) {
  1252.      /* Use user-specified edgeflags for quads.
  1253.       */
  1254.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1255.      QuadFunc( ctx, j-3, j-2, j-1, j );
  1256.       }
  1257.    } else {
  1258.       for (j=start+3; j<count; j+=4) {
  1259.      QuadFunc( ctx, j-3, j-2, j-1, j );
  1260.       }
  1261.    }
  1262.    ;
  1263. }
  1264.  
  1265. static void _tnl_render_quad_strip_verts( GLcontext *ctx,
  1266.                     GLuint start,
  1267.                     GLuint count,
  1268.                     GLuint flags )
  1269. {
  1270.    GLuint j;
  1271.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1272.    (void) flags;
  1273.  
  1274.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0008 );
  1275.    if ((ctx->_TriangleCaps & 0x10)) {
  1276.       for (j=start+3;j<count;j+=2) {
  1277.      /* All edges are boundary.  Set edgeflags to 1, draw the
  1278.       * quad, and restore them to the original values.
  1279.       */
  1280.      GLboolean ef3 = VB->EdgeFlag[j-3];
  1281.      GLboolean ef2 = VB->EdgeFlag[j-2];
  1282.      GLboolean ef1 = VB->EdgeFlag[j-1];
  1283.      GLboolean ef = VB->EdgeFlag[j];
  1284.      if ((flags & 0x100)) {
  1285.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1286.      }
  1287.      VB->EdgeFlag[j-3] = 0x1;
  1288.      VB->EdgeFlag[j-2] = 0x1;
  1289.      VB->EdgeFlag[j-1] = 0x1;
  1290.      VB->EdgeFlag[j] = 0x1;
  1291.      QuadFunc( ctx, j-1, j-3, j-2, j );
  1292.      VB->EdgeFlag[j-3] = ef3;
  1293.      VB->EdgeFlag[j-2] = ef2;
  1294.      VB->EdgeFlag[j-1] = ef1;
  1295.      VB->EdgeFlag[j] = ef;
  1296.       }
  1297.    } else {
  1298.       for (j=start+3;j<count;j+=2) {
  1299.      QuadFunc( ctx, j-1, j-3, j-2, j );
  1300.       }
  1301.    }
  1302.    ;
  1303. }
  1304.  
  1305. static void _tnl_render_noop_verts( GLcontext *ctx,
  1306.                   GLuint start,
  1307.                   GLuint count,
  1308.                   GLuint flags )
  1309. {
  1310.    (void)(ctx && start && count && flags);
  1311. }
  1312.  
  1313.  void (*_tnl_render_tab_verts[0x0009+2])(GLcontext *,
  1314.                                GLuint,
  1315.                                GLuint,
  1316.                                GLuint) =
  1317. {
  1318.    _tnl_render_points_verts,
  1319.    _tnl_render_lines_verts,
  1320.    _tnl_render_line_loop_verts,
  1321.    _tnl_render_line_strip_verts,
  1322.    _tnl_render_triangles_verts,
  1323.    _tnl_render_tri_strip_verts,
  1324.    _tnl_render_tri_fan_verts,
  1325.    _tnl_render_quads_verts,
  1326.    _tnl_render_quad_strip_verts,
  1327.    _tnl_render_poly_verts,
  1328.    _tnl_render_noop_verts,
  1329. };
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337. /* Elts, no clipping.
  1338.  */
  1339. /* $Id: t_vb_rendertmp.h,v 1.10 2002/10/29 20:29:04 brianp Exp $ */
  1340.  
  1341.  
  1342. static void _tnl_render_points_elts( GLcontext *ctx,
  1343.                 GLuint start,
  1344.                 GLuint count,
  1345.                 GLuint flags )
  1346. {
  1347.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1348.    (void) flags;
  1349.  
  1350.    ctx->OcclusionResult = 0x1;
  1351.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0000 );
  1352.    tnl->Driver.Render.Points( ctx, start, count );
  1353.    ;
  1354. }
  1355.  
  1356. static void _tnl_render_lines_elts( GLcontext *ctx,
  1357.                    GLuint start,
  1358.                    GLuint count,
  1359.                    GLuint flags )
  1360. {
  1361.    GLuint j;
  1362.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1363.    (void) flags;
  1364.  
  1365.    ctx->OcclusionResult = 0x1;
  1366.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0001 );
  1367.    for (j=start+1; j<count; j+=2 ) {
  1368.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1369.       LineFunc( ctx, elt[j-1], elt[j] );
  1370.    }
  1371.    ;
  1372. }
  1373.  
  1374.  
  1375. static void _tnl_render_line_strip_elts( GLcontext *ctx,
  1376.                     GLuint start,
  1377.                     GLuint count,
  1378.                     GLuint flags )
  1379. {
  1380.    GLuint j;
  1381.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1382.    (void) flags;
  1383.  
  1384.    ctx->OcclusionResult = 0x1;
  1385.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0003 );
  1386.  
  1387.    if ((flags & 0x100)) {
  1388.       if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1389.    }
  1390.  
  1391.    for (j=start+1; j<count; j++ )
  1392.       LineFunc( ctx, elt[j-1], elt[j] );
  1393.  
  1394.    ;
  1395. }
  1396.  
  1397.  
  1398. static void _tnl_render_line_loop_elts( GLcontext *ctx,
  1399.                    GLuint start,
  1400.                    GLuint count,
  1401.                    GLuint flags )
  1402. {
  1403.    GLuint i;
  1404.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1405.  
  1406.    (void) flags;
  1407.  
  1408.    ctx->OcclusionResult = 0x1;
  1409.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0002 );
  1410.  
  1411.    if (start+1 < count) {
  1412.       if ((flags & 0x100)) {
  1413.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1414.      LineFunc( ctx, elt[start], elt[start+1] );
  1415.       }
  1416.  
  1417.       for ( i = start+2 ; i < count ; i++) {
  1418.      LineFunc( ctx, elt[i-1], elt[i] );
  1419.       }
  1420.  
  1421.       if ( (flags & 0x200)) {
  1422.      LineFunc( ctx, elt[count-1], elt[start] );
  1423.       }
  1424.    }
  1425.  
  1426.    ;
  1427. }
  1428.  
  1429.  
  1430. static void _tnl_render_triangles_elts( GLcontext *ctx,
  1431.                    GLuint start,
  1432.                    GLuint count,
  1433.                    GLuint flags )
  1434. {
  1435.    GLuint j;
  1436.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1437.    (void) flags;
  1438.  
  1439.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0004 );
  1440.    if ((ctx->_TriangleCaps & 0x10)) {
  1441.       for (j=start+2; j<count; j+=3) {
  1442.      /* Leave the edgeflags as supplied by the user.
  1443.       */
  1444.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1445.      TriangleFunc( ctx, elt[j-2], elt[j-1], elt[j] );
  1446.       }
  1447.    } else {
  1448.       for (j=start+2; j<count; j+=3) {
  1449.      TriangleFunc( ctx, elt[j-2], elt[j-1], elt[j] );
  1450.       }
  1451.    }
  1452.    ;
  1453. }
  1454.  
  1455.  
  1456.  
  1457. static void _tnl_render_tri_strip_elts( GLcontext *ctx,
  1458.                    GLuint start,
  1459.                    GLuint count,
  1460.                    GLuint flags )
  1461. {
  1462.    GLuint j;
  1463.    GLuint parity = 0;
  1464.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1465.  
  1466.    if ((flags & 0x400))
  1467.       parity = 1;
  1468.  
  1469.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0005 );
  1470.    if ((ctx->_TriangleCaps & 0x10)) {
  1471.       for (j=start+2;j<count;j++,parity^=1) {
  1472.      GLuint ej2 = elt[j-2+parity];
  1473.      GLuint ej1 = elt[j-1-parity];
  1474.      GLuint ej = elt[j];
  1475.      GLboolean ef2 = VB->EdgeFlag[ej2];
  1476.      GLboolean ef1 = VB->EdgeFlag[ej1];
  1477.      GLboolean ef = VB->EdgeFlag[ej];
  1478.      if ((flags & 0x100)) {
  1479.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1480.      }
  1481.      VB->EdgeFlag[ej2] = 0x1;
  1482.      VB->EdgeFlag[ej1] = 0x1;
  1483.      VB->EdgeFlag[ej] = 0x1;
  1484.      TriangleFunc( ctx, ej2, ej1, ej );
  1485.      VB->EdgeFlag[ej2] = ef2;
  1486.      VB->EdgeFlag[ej1] = ef1;
  1487.      VB->EdgeFlag[ej] = ef;
  1488.       }
  1489.    } else {
  1490.       for (j=start+2; j<count ; j++, parity^=1) {
  1491.      TriangleFunc( ctx, elt[j-2+parity], elt[j-1-parity], elt[j] );
  1492.       }
  1493.    }
  1494.    ;
  1495. }
  1496.  
  1497.  
  1498. static void _tnl_render_tri_fan_elts( GLcontext *ctx,
  1499.                  GLuint start,
  1500.                  GLuint count,
  1501.                  GLuint flags )
  1502. {
  1503.    GLuint j;
  1504.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1505.    (void) flags;
  1506.  
  1507.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0006 );
  1508.    if ((ctx->_TriangleCaps & 0x10)) {
  1509.       for (j=start+2;j<count;j++) {
  1510.      /* For trifans, all edges are boundary.
  1511.       */
  1512.      GLuint ejs = elt[start];
  1513.      GLuint ej1 = elt[j-1];
  1514.      GLuint ej = elt[j];
  1515.      GLboolean efs = VB->EdgeFlag[ejs];
  1516.      GLboolean ef1 = VB->EdgeFlag[ej1];
  1517.      GLboolean ef = VB->EdgeFlag[ej];
  1518.      if ((flags & 0x100)) {
  1519.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1520.      }
  1521.      VB->EdgeFlag[ejs] = 0x1;
  1522.      VB->EdgeFlag[ej1] = 0x1;
  1523.      VB->EdgeFlag[ej] = 0x1;
  1524.      TriangleFunc( ctx, ejs, ej1, ej );
  1525.      VB->EdgeFlag[ejs] = efs;
  1526.      VB->EdgeFlag[ej1] = ef1;
  1527.      VB->EdgeFlag[ej] = ef;
  1528.       }
  1529.    } else {
  1530.       for (j=start+2;j<count;j++) {
  1531.      TriangleFunc( ctx, elt[start], elt[j-1], elt[j] );
  1532.       }
  1533.    }
  1534.  
  1535.    ;
  1536. }
  1537.  
  1538.  
  1539. static void _tnl_render_poly_elts( GLcontext *ctx,
  1540.                   GLuint start,
  1541.                   GLuint count,
  1542.                   GLuint flags )
  1543. {
  1544.    GLuint j = start+2;
  1545.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1546.    (void) flags;
  1547.  
  1548.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0009 );
  1549.    if ((ctx->_TriangleCaps & 0x10)) {
  1550.       GLboolean efstart = VB->EdgeFlag[elt[start]];
  1551.       GLboolean efcount = VB->EdgeFlag[elt[count-1]];
  1552.  
  1553.       /* If the primitive does not begin here, the first edge
  1554.        * is non-boundary.
  1555.        */
  1556.       if (!(flags & 0x100))
  1557.      VB->EdgeFlag[elt[start]] = 0x0;
  1558.       else {
  1559.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1560.       }
  1561.  
  1562.       /* If the primitive does not end here, the final edge is
  1563.        * non-boundary.
  1564.        */
  1565.       if (!(flags & 0x200))
  1566.      VB->EdgeFlag[elt[count-1]] = 0x0;
  1567.  
  1568.       /* Draw the first triangles (possibly zero)
  1569.        */
  1570.       if (j+1<count) {
  1571.      GLboolean ef = VB->EdgeFlag[elt[j]];
  1572.      VB->EdgeFlag[elt[j]] = 0x0;
  1573.      TriangleFunc( ctx, elt[j-1], elt[j], elt[start] );
  1574.      VB->EdgeFlag[elt[j]] = ef;
  1575.      j++;
  1576.  
  1577.      /* Don't render the first edge again:
  1578.       */
  1579.      VB->EdgeFlag[elt[start]] = 0x0;
  1580.  
  1581.      for (;j+1<count;j++) {
  1582.         GLboolean efj = VB->EdgeFlag[elt[j]];
  1583.         VB->EdgeFlag[elt[j]] = 0x0;
  1584.         TriangleFunc( ctx, elt[j-1], elt[j], elt[start] );
  1585.         VB->EdgeFlag[elt[j]] = efj;
  1586.      }
  1587.       }
  1588.  
  1589.       /* Draw the last or only triangle
  1590.        */
  1591.       if (j < count)
  1592.      TriangleFunc( ctx, elt[j-1], elt[j], elt[start] );
  1593.  
  1594.       /* Restore the first and last edgeflags:
  1595.        */
  1596.       VB->EdgeFlag[elt[count-1]] = efcount;
  1597.       VB->EdgeFlag[elt[start]] = efstart;
  1598.  
  1599.    }
  1600.    else {
  1601.       for (j=start+2;j<count;j++) {
  1602.      TriangleFunc( ctx, elt[j-1], elt[j], elt[start] );
  1603.       }
  1604.    }
  1605.    ;
  1606. }
  1607.  
  1608. static void _tnl_render_quads_elts( GLcontext *ctx,
  1609.                    GLuint start,
  1610.                    GLuint count,
  1611.                    GLuint flags )
  1612. {
  1613.    GLuint j;
  1614.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1615.    (void) flags;
  1616.  
  1617.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0007 );
  1618.    if ((ctx->_TriangleCaps & 0x10)) {
  1619.       for (j=start+3; j<count; j+=4) {
  1620.      /* Use user-specified edgeflags for quads.
  1621.       */
  1622.      if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1623.      QuadFunc( ctx, elt[j-3], elt[j-2], elt[j-1], elt[j] );
  1624.       }
  1625.    } else {
  1626.       for (j=start+3; j<count; j+=4) {
  1627.      QuadFunc( ctx, elt[j-3], elt[j-2], elt[j-1], elt[j] );
  1628.       }
  1629.    }
  1630.    ;
  1631. }
  1632.  
  1633. static void _tnl_render_quad_strip_elts( GLcontext *ctx,
  1634.                     GLuint start,
  1635.                     GLuint count,
  1636.                     GLuint flags )
  1637. {
  1638.    GLuint j;
  1639.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context)); struct vertex_buffer *VB = &tnl->vb; const GLuint * const elt = VB->Elts; const line_func LineFunc = tnl->Driver.Render.Line; const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; const quad_func QuadFunc = tnl->Driver.Render.Quad; const GLboolean stipple = ctx->Line.StippleFlag; (void) (LineFunc && TriangleFunc && QuadFunc); (void) elt; (void) stipple;
  1640.    (void) flags;
  1641.  
  1642.    tnl->Driver.Render.PrimitiveNotify( ctx, 0x0008 );
  1643.    if ((ctx->_TriangleCaps & 0x10)) {
  1644.       for (j=start+3;j<count;j+=2) {
  1645.      /* All edges are boundary.  Set edgeflags to 1, draw the
  1646.       * quad, and restore them to the original values.
  1647.       */
  1648.      GLboolean ef3 = VB->EdgeFlag[elt[j-3]];
  1649.      GLboolean ef2 = VB->EdgeFlag[elt[j-2]];
  1650.      GLboolean ef1 = VB->EdgeFlag[elt[j-1]];
  1651.      GLboolean ef = VB->EdgeFlag[elt[j]];
  1652.      if ((flags & 0x100)) {
  1653.         if (stipple) tnl->Driver.Render.ResetLineStipple( ctx );
  1654.      }
  1655.      VB->EdgeFlag[elt[j-3]] = 0x1;
  1656.      VB->EdgeFlag[elt[j-2]] = 0x1;
  1657.      VB->EdgeFlag[elt[j-1]] = 0x1;
  1658.      VB->EdgeFlag[elt[j]] = 0x1;
  1659.      QuadFunc( ctx, elt[j-1], elt[j-3], elt[j-2], elt[j] );
  1660.      VB->EdgeFlag[elt[j-3]] = ef3;
  1661.      VB->EdgeFlag[elt[j-2]] = ef2;
  1662.      VB->EdgeFlag[elt[j-1]] = ef1;
  1663.      VB->EdgeFlag[elt[j]] = ef;
  1664.       }
  1665.    } else {
  1666.       for (j=start+3;j<count;j+=2) {
  1667.      QuadFunc( ctx, elt[j-1], elt[j-3], elt[j-2], elt[j] );
  1668.       }
  1669.    }
  1670.    ;
  1671. }
  1672.  
  1673. static void _tnl_render_noop_elts( GLcontext *ctx,
  1674.                   GLuint start,
  1675.                   GLuint count,
  1676.                   GLuint flags )
  1677. {
  1678.    (void)(ctx && start && count && flags);
  1679. }
  1680.  
  1681.  void (*_tnl_render_tab_elts[0x0009+2])(GLcontext *,
  1682.                                GLuint,
  1683.                                GLuint,
  1684.                                GLuint) =
  1685. {
  1686.    _tnl_render_points_elts,
  1687.    _tnl_render_lines_elts,
  1688.    _tnl_render_line_loop_elts,
  1689.    _tnl_render_line_strip_elts,
  1690.    _tnl_render_triangles_elts,
  1691.    _tnl_render_tri_strip_elts,
  1692.    _tnl_render_tri_fan_elts,
  1693.    _tnl_render_quads_elts,
  1694.    _tnl_render_quad_strip_elts,
  1695.    _tnl_render_poly_elts,
  1696.    _tnl_render_noop_elts,
  1697. };
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705. /**********************************************************************/
  1706. /*              Helper functions for drivers                  */
  1707. /**********************************************************************/
  1708.  
  1709. void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n )
  1710. {
  1711.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  1712.    struct vertex_buffer *VB = &tnl->vb;
  1713.    GLuint *tmp = VB->Elts;
  1714.  
  1715.    VB->Elts = (GLuint *)elts;
  1716.    tnl->Driver.Render.PrimTabElts[0x0009]( ctx, 0, n, 0x100|0x200 );
  1717.    VB->Elts = tmp;
  1718. }
  1719.  
  1720. void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
  1721. {
  1722.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  1723.    tnl->Driver.Render.Line( ctx, ii, jj );
  1724. }
  1725.  
  1726.  
  1727.  
  1728. /**********************************************************************/
  1729. /*              Clip and render whole vertex buffers                  */
  1730. /**********************************************************************/
  1731.  
  1732.  
  1733. static GLboolean run_render( GLcontext *ctx,
  1734.                  struct gl_pipeline_stage *stage )
  1735. {
  1736.    TNLcontext *tnl = ((TNLcontext *)(ctx->swtnl_context));
  1737.    struct vertex_buffer *VB = &tnl->vb;
  1738.    GLuint new_inputs = stage->changed_inputs;
  1739.    render_func *tab;
  1740.    GLint pass = 0;
  1741.  
  1742.    /* Allow the drivers to lock before projected verts are built so
  1743.     * that window coordinates are guarenteed not to change before
  1744.     * rendering.
  1745.     */
  1746.    ;
  1747.  
  1748.    tnl->Driver.Render.Start( ctx );
  1749.  
  1750.  
  1751.    tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs );
  1752.  
  1753.    if (VB->ClipOrMask) {
  1754.       tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
  1755.       clip_render_tab_elts[0x0004] = clip_elt_triangles;
  1756.    }
  1757.    else {
  1758.       tab = (VB->Elts ? 
  1759.          tnl->Driver.Render.PrimTabElts : 
  1760.          tnl->Driver.Render.PrimTabVerts);
  1761.    }
  1762.  
  1763.    do
  1764.    {
  1765.       GLuint i, length, flags = 0;
  1766.       for (i = VB->FirstPrimitive ; !(flags & 0x800) ; i += length)
  1767.       {
  1768.      flags = VB->Primitive[i];
  1769.      length= VB->PrimitiveLength[i];
  1770.      ;
  1771.      ;
  1772.  
  1773.      if (MESA_VERBOSE & VERBOSE_PRIMS)
  1774.         _mesa_debug(0, "MESA prim %s %d..%d\n", 
  1775.             _mesa_lookup_enum_by_nr(flags & 0xff), 
  1776.             i, i+length);
  1777.  
  1778.      if (length)
  1779.         tab[flags & 0xff]( ctx, i, i + length, flags );
  1780.       }
  1781.    } while (tnl->Driver.Render.Multipass &&
  1782.         tnl->Driver.Render.Multipass( ctx, ++pass ));
  1783.  
  1784.  
  1785.    tnl->Driver.Render.Finish( ctx );
  1786. /*     _swrast_flush(ctx); */
  1787. /*     usleep(1000000); */
  1788.    return 0x0;        /* finished the pipe */
  1789. }
  1790.  
  1791.  
  1792. /**********************************************************************/
  1793. /*                          Render pipeline stage                     */
  1794. /**********************************************************************/
  1795.  
  1796.  
  1797.  
  1798. /* Quite a bit of work involved in finding out the inputs for the
  1799.  * render stage.
  1800.  */
  1801. static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
  1802. {
  1803.    GLuint inputs = (1 << 25);
  1804.    GLuint i;
  1805.  
  1806.    if (ctx->Visual.rgbMode) {
  1807.       inputs |= (1 << 3);
  1808.  
  1809.       if (ctx->_TriangleCaps & 0x2)
  1810.      inputs |= (1 << 4);
  1811.  
  1812.       if (ctx->Texture._EnabledUnits) {
  1813.      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
  1814.         if (ctx->Texture.Unit[i]._ReallyEnabled)
  1815.            inputs |= (1 << (8 + (i)));
  1816.      }
  1817.       }
  1818.    }
  1819.    else {
  1820.       inputs |= (1 << 6);
  1821.    }
  1822.  
  1823.    if (ctx->Point._Attenuated)
  1824.       inputs |= (1 << 27);
  1825.  
  1826.    /* How do drivers turn this off?
  1827.     */
  1828.    if (ctx->Fog.Enabled)
  1829.       inputs |= (1 << 5);
  1830.  
  1831.    if (ctx->_TriangleCaps & 0x10)
  1832.       inputs |= (1 << 7);
  1833.  
  1834.    if (ctx->RenderMode==0x1C01)
  1835.       inputs |= ((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15));
  1836.  
  1837.    stage->inputs = inputs;
  1838. }
  1839.  
  1840.  
  1841.  
  1842.  
  1843. static void dtr( struct gl_pipeline_stage *stage )
  1844. {
  1845. }
  1846.  
  1847.  
  1848. const struct gl_pipeline_stage _tnl_render_stage =
  1849. {
  1850.    "render",            /* name */
  1851.    (0x1000000 |
  1852.     (0x400 | 0x100) |
  1853.     0x400 |
  1854.     0x40000|
  1855.     0x400|
  1856.     0x2000|
  1857.     0x100|
  1858.     0x4000 |
  1859.     0x800000),        /* re-check (new inputs, interp function) */
  1860.    0,                /* re-run (always runs) */
  1861.    0x1,            /* active? */
  1862.    0,                /* inputs (set in check_render) */
  1863.    0,                /* outputs */
  1864.    0,                /* changed_inputs */
  1865.    0,            /* private data */
  1866.    dtr,                /* destructor */
  1867.    check_render,        /* check */
  1868.    run_render            /* run */
  1869. };
  1870.