Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  6.3
  4.  *
  5.  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Keith Whitwell <keith@tungstengraphics.com>
  26.  */
  27.  
  28.  
  29. /* Template for building functions to plug into the driver interface
  30.  * of t_vb_render.c:
  31.  *     ctx->Driver.QuadFunc
  32.  *     ctx->Driver.TriangleFunc
  33.  *     ctx->Driver.LineFunc
  34.  *     ctx->Driver.PointsFunc
  35.  *
  36.  * DO_TWOSIDE:   Plug back-color values from the VB into backfacing triangles,
  37.  *               and restore vertices afterwards.
  38.  * DO_OFFSET:    Calculate offset for triangles and adjust vertices.  Restore
  39.  *               vertices after rendering.
  40.  * DO_FLAT:      For hardware without native flatshading, copy provoking colors
  41.  *               into the other vertices.  Restore after rendering.
  42.  * DO_UNFILLED:  Decompose triangles to lines and points where appropriate.
  43.  * DO_TWOSTENCIL:Gross hack for two-sided stencil.
  44.  *
  45.  * HAVE_SPEC: Vertices have secondary rgba values.
  46.  *
  47.  * VERT_X(v): Alias for vertex x value.
  48.  * VERT_Y(v): Alias for vertex y value.
  49.  * VERT_Z(v): Alias for vertex z value.
  50.  * DEPTH_SCALE: Scale for constant offset.
  51.  * REVERSE_DEPTH: Viewport depth range reversed.
  52.  *
  53.  * VERTEX: Hardware vertex type.
  54.  * GET_VERTEX(n): Retreive vertex with index n.
  55.  * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw.
  56.  *
  57.  * VERT_SET_RGBA: Assign vertex rgba from VB color.
  58.  * VERT_COPY_RGBA: Copy vertex rgba another vertex.
  59.  * VERT_SAVE_RGBA: Save vertex rgba to a local variable.
  60.  * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable.
  61.  *   --> Similar for SPEC.
  62.  *
  63.  * LOCAL_VARS(n): (At least) define local vars for save/restore rgba.
  64.  *
  65.  */
  66.  
  67. #if HAVE_BACK_COLORS
  68. #define VERT_SET_RGBA( v, c )
  69. #endif
  70.  
  71. #if !HAVE_SPEC
  72. #define VERT_SET_SPEC( v, c ) (void) c
  73. #define VERT_COPY_SPEC( v0, v1 )
  74. #define VERT_SAVE_SPEC( idx )
  75. #define VERT_RESTORE_SPEC( idx )
  76. #if HAVE_BACK_COLORS
  77. #define VERT_COPY_SPEC1( v )
  78. #endif
  79. #else
  80. #if HAVE_BACK_COLORS
  81. #define VERT_SET_SPEC( v, c )
  82. #endif
  83. #endif
  84.  
  85. #if !HAVE_BACK_COLORS
  86. #define VERT_COPY_SPEC1( v )
  87. #define VERT_COPY_RGBA1( v )
  88. #endif
  89.  
  90. #ifndef INSANE_VERTICES
  91. #define VERT_SET_Z(v,val) VERT_Z(v) = val
  92. #define VERT_Z_ADD(v,val) VERT_Z(v) += val
  93. #endif
  94.  
  95. #ifndef REVERSE_DEPTH
  96. #define REVERSE_DEPTH 0
  97. #endif
  98.  
  99. /* disable twostencil for un-aware drivers */
  100. #ifndef HAVE_STENCIL_TWOSIDE
  101. #define HAVE_STENCIL_TWOSIDE 0
  102. #endif
  103. #ifndef DO_TWOSTENCIL
  104. #define DO_TWOSTENCIL 0
  105. #endif
  106. #ifndef SETUP_STENCIL
  107. #define SETUP_STENCIL(f)
  108. #endif
  109. #ifndef UNSET_STENCIL
  110. #define UNSET_STENCIL(f)
  111. #endif
  112.  
  113. #if DO_TRI
  114. static void TAG(triangle)( struct gl_context *ctx, GLuint e0, GLuint e1, GLuint e2 )
  115. {
  116.    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
  117.    VERTEX *v[3];
  118.    GLfloat offset = 0;
  119.    GLfloat z[3] = { 0 };
  120.    GLenum mode = GL_FILL;
  121.    GLuint facing = 0;
  122.    LOCAL_VARS(3);
  123.  
  124. /*     fprintf(stderr, "%s\n", __FUNCTION__); */
  125.  
  126.    v[0] = (VERTEX *)GET_VERTEX(e0);
  127.    v[1] = (VERTEX *)GET_VERTEX(e1);
  128.    v[2] = (VERTEX *)GET_VERTEX(e2);
  129.  
  130.    if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
  131.    {
  132.       GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
  133.       GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
  134.       GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
  135.       GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
  136.       GLfloat cc = ex*fy - ey*fx;
  137.  
  138.       if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
  139.       {
  140.          facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
  141.  
  142.          if (DO_UNFILLED) {
  143.             if (facing) {
  144.                mode = ctx->Polygon.BackMode;
  145.                if (ctx->Polygon.CullFlag &&
  146.                    ctx->Polygon.CullFaceMode != GL_FRONT) {
  147.                   return;
  148.                }
  149.             } else {
  150.                mode = ctx->Polygon.FrontMode;
  151.                if (ctx->Polygon.CullFlag &&
  152.                    ctx->Polygon.CullFaceMode != GL_BACK) {
  153.                   return;
  154.                }
  155.             }
  156.          }
  157.  
  158.          if (DO_TWOSIDE && facing == 1) {
  159.             if (HAVE_BACK_COLORS) {
  160.                if (!DO_FLAT) {
  161.                   VERT_SAVE_RGBA( 0 );
  162.                   VERT_SAVE_RGBA( 1 );
  163.                   VERT_COPY_RGBA1( v[0] );
  164.                   VERT_COPY_RGBA1( v[1] );
  165.                }
  166.                VERT_SAVE_RGBA( 2 );
  167.                VERT_COPY_RGBA1( v[2] );
  168.                if (HAVE_SPEC) {
  169.                   if (!DO_FLAT) {
  170.                      VERT_SAVE_SPEC( 0 );
  171.                      VERT_SAVE_SPEC( 1 );
  172.                      VERT_COPY_SPEC1( v[0] );
  173.                      VERT_COPY_SPEC1( v[1] );
  174.                   }
  175.                   VERT_SAVE_SPEC( 2 );
  176.                   VERT_COPY_SPEC1( v[2] );
  177.                }
  178.             }
  179.             else {
  180.                GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
  181.                (void) vbcolor;
  182.  
  183.                if (!DO_FLAT) {
  184.                   VERT_SAVE_RGBA( 0 );
  185.                   VERT_SAVE_RGBA( 1 );
  186.                }
  187.                VERT_SAVE_RGBA( 2 );
  188.  
  189.                if (VB->BackfaceColorPtr->stride) {
  190.                   ASSERT(VB->BackfaceColorPtr->stride == 4*sizeof(GLfloat));
  191.  
  192.                   if (!DO_FLAT) {
  193.                      VERT_SET_RGBA( v[0], vbcolor[e0] );
  194.                      VERT_SET_RGBA( v[1], vbcolor[e1] );
  195.                   }
  196.                   VERT_SET_RGBA( v[2], vbcolor[e2] );
  197.                }
  198.                else {
  199.                   if (!DO_FLAT) {
  200.                      VERT_SET_RGBA( v[0], vbcolor[0] );
  201.                      VERT_SET_RGBA( v[1], vbcolor[0] );
  202.                   }
  203.                   VERT_SET_RGBA( v[2], vbcolor[0] );
  204.                }
  205.  
  206.                if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
  207.                   GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
  208.                   ASSERT(VB->BackfaceSecondaryColorPtr->stride == 4*sizeof(GLfloat));
  209.  
  210.                   if (!DO_FLAT) {
  211.                      VERT_SAVE_SPEC( 0 );
  212.                      VERT_SAVE_SPEC( 1 );
  213.                      VERT_SET_SPEC( v[0], vbspec[e0] );
  214.                      VERT_SET_SPEC( v[1], vbspec[e1] );
  215.                   }
  216.                   VERT_SAVE_SPEC( 2 );
  217.                   VERT_SET_SPEC( v[2], vbspec[e2] );
  218.                }
  219.             }
  220.          }
  221.       }
  222.  
  223.  
  224.       if (DO_OFFSET)
  225.       {
  226.          offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
  227.          z[0] = VERT_Z(v[0]);
  228.          z[1] = VERT_Z(v[1]);
  229.          z[2] = VERT_Z(v[2]);
  230.          if (cc * cc > 1e-16) {
  231.             GLfloat ic  = 1.0 / cc;
  232.             GLfloat ez  = z[0] - z[2];
  233.             GLfloat fz  = z[1] - z[2];
  234.             GLfloat a   = ey*fz - ez*fy;
  235.             GLfloat b   = ez*fx - ex*fz;
  236.             GLfloat ac  = a * ic;
  237.             GLfloat bc  = b * ic;
  238.             if ( ac < 0.0f ) ac = -ac;
  239.             if ( bc < 0.0f ) bc = -bc;
  240.             offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
  241.          }
  242.          offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
  243.       }
  244.    }
  245.  
  246.    if (DO_FLAT) {
  247.       VERT_SAVE_RGBA( 0 );
  248.       VERT_SAVE_RGBA( 1 );
  249.       VERT_COPY_RGBA( v[0], v[2] );
  250.       VERT_COPY_RGBA( v[1], v[2] );
  251.       if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
  252.          VERT_SAVE_SPEC( 0 );
  253.          VERT_SAVE_SPEC( 1 );
  254.          VERT_COPY_SPEC( v[0], v[2] );
  255.          VERT_COPY_SPEC( v[1], v[2] );
  256.       }
  257.    }
  258.  
  259.    if (mode == GL_POINT) {
  260.       if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
  261.          VERT_Z_ADD(v[0], offset);
  262.          VERT_Z_ADD(v[1], offset);
  263.          VERT_Z_ADD(v[2], offset);
  264.       }
  265.       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
  266.          SETUP_STENCIL(facing);
  267.          UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
  268.          UNSET_STENCIL(facing);
  269.       } else {
  270.          UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
  271.       }
  272.    } else if (mode == GL_LINE) {
  273.       if (DO_OFFSET && ctx->Polygon.OffsetLine) {
  274.          VERT_Z_ADD(v[0], offset);
  275.          VERT_Z_ADD(v[1], offset);
  276.          VERT_Z_ADD(v[2], offset);
  277.       }
  278.       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
  279.          SETUP_STENCIL(facing);
  280.          UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
  281.          UNSET_STENCIL(facing);
  282.       } else {
  283.          UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
  284.       }
  285.    } else {
  286.       if (DO_OFFSET && ctx->Polygon.OffsetFill) {
  287.          VERT_Z_ADD(v[0], offset);
  288.          VERT_Z_ADD(v[1], offset);
  289.          VERT_Z_ADD(v[2], offset);
  290.       }
  291.       if (DO_UNFILLED)
  292.          RASTERIZE( GL_TRIANGLES );
  293.       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
  294.          SETUP_STENCIL(facing);
  295.          TRI( v[0], v[1], v[2] );
  296.          UNSET_STENCIL(facing);
  297.       } else {
  298.          TRI( v[0], v[1], v[2] );
  299.       }
  300.    }
  301.  
  302.    if (DO_OFFSET)
  303.    {
  304.       VERT_SET_Z(v[0], z[0]);
  305.       VERT_SET_Z(v[1], z[1]);
  306.       VERT_SET_Z(v[2], z[2]);
  307.    }
  308.  
  309.    if (DO_TWOSIDE && facing == 1) {
  310.       if (!DO_FLAT) {
  311.          VERT_RESTORE_RGBA( 0 );
  312.          VERT_RESTORE_RGBA( 1 );
  313.       }
  314.       VERT_RESTORE_RGBA( 2 );
  315.       if (HAVE_SPEC) {
  316.          if (!DO_FLAT) {
  317.             VERT_RESTORE_SPEC( 0 );
  318.             VERT_RESTORE_SPEC( 1 );
  319.          }
  320.          VERT_RESTORE_SPEC( 2 );
  321.       }
  322.    }
  323.  
  324.  
  325.    if (DO_FLAT) {
  326.          VERT_RESTORE_RGBA( 0 );
  327.          VERT_RESTORE_RGBA( 1 );
  328.          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
  329.             VERT_RESTORE_SPEC( 0 );
  330.             VERT_RESTORE_SPEC( 1 );
  331.          }
  332.    }
  333. }
  334. #endif
  335.  
  336. #if DO_QUAD
  337. #if DO_FULL_QUAD
  338. static void TAG(quadr)( struct gl_context *ctx,
  339.                        GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
  340. {
  341.    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
  342.    VERTEX *v[4];
  343.    GLfloat offset = 0;
  344.    GLfloat z[4] = { 0 };
  345.    GLenum mode = GL_FILL;
  346.    GLuint facing = 0;
  347.    LOCAL_VARS(4);
  348.  
  349.    v[0] = (VERTEX *)GET_VERTEX(e0);
  350.    v[1] = (VERTEX *)GET_VERTEX(e1);
  351.    v[2] = (VERTEX *)GET_VERTEX(e2);
  352.    v[3] = (VERTEX *)GET_VERTEX(e3);
  353.  
  354.    if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
  355.    {
  356.       GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
  357.       GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
  358.       GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
  359.       GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
  360.       GLfloat cc = ex*fy - ey*fx;
  361.  
  362.       if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
  363.       {
  364.          facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
  365.  
  366.          if (DO_UNFILLED) {
  367.             if (facing) {
  368.                mode = ctx->Polygon.BackMode;
  369.                if (ctx->Polygon.CullFlag &&
  370.                    ctx->Polygon.CullFaceMode != GL_FRONT) {
  371.                   return;
  372.                }
  373.             } else {
  374.                mode = ctx->Polygon.FrontMode;
  375.                if (ctx->Polygon.CullFlag &&
  376.                    ctx->Polygon.CullFaceMode != GL_BACK) {
  377.                   return;
  378.                }
  379.             }
  380.          }
  381.  
  382.          if (DO_TWOSIDE && facing == 1) {
  383.             GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
  384.             (void)vbcolor;
  385.  
  386.             if (HAVE_BACK_COLORS) {
  387.                if (!DO_FLAT) {
  388.                   VERT_SAVE_RGBA( 0 );
  389.                   VERT_SAVE_RGBA( 1 );
  390.                   VERT_SAVE_RGBA( 2 );
  391.                   VERT_COPY_RGBA1( v[0] );
  392.                   VERT_COPY_RGBA1( v[1] );
  393.                   VERT_COPY_RGBA1( v[2] );
  394.                }
  395.                VERT_SAVE_RGBA( 3 );
  396.                VERT_COPY_RGBA1( v[3] );
  397.                if (HAVE_SPEC) {
  398.                   if (!DO_FLAT) {
  399.                      VERT_SAVE_SPEC( 0 );
  400.                      VERT_SAVE_SPEC( 1 );
  401.                      VERT_SAVE_SPEC( 2 );
  402.                      VERT_COPY_SPEC1( v[0] );
  403.                      VERT_COPY_SPEC1( v[1] );
  404.                      VERT_COPY_SPEC1( v[2] );
  405.                   }
  406.                   VERT_SAVE_SPEC( 3 );
  407.                   VERT_COPY_SPEC1( v[3] );
  408.                }
  409.             }
  410.             else {
  411.                if (!DO_FLAT) {
  412.                   VERT_SAVE_RGBA( 0 );
  413.                   VERT_SAVE_RGBA( 1 );
  414.                   VERT_SAVE_RGBA( 2 );
  415.                }
  416.                VERT_SAVE_RGBA( 3 );
  417.  
  418.                if (VB->BackfaceColorPtr->stride) {
  419.                   if (!DO_FLAT) {
  420.                      VERT_SET_RGBA( v[0], vbcolor[e0] );
  421.                      VERT_SET_RGBA( v[1], vbcolor[e1] );
  422.                      VERT_SET_RGBA( v[2], vbcolor[e2] );
  423.                   }
  424.                   VERT_SET_RGBA( v[3], vbcolor[e3] );
  425.                }
  426.                else {
  427.                   if (!DO_FLAT) {
  428.                      VERT_SET_RGBA( v[0], vbcolor[0] );
  429.                      VERT_SET_RGBA( v[1], vbcolor[0] );
  430.                      VERT_SET_RGBA( v[2], vbcolor[0] );
  431.                   }
  432.                   VERT_SET_RGBA( v[3], vbcolor[0] );
  433.                }
  434.  
  435.                if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
  436.                   GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
  437.                   ASSERT(VB->BackfaceSecondaryColorPtr->stride==4*sizeof(GLfloat));
  438.  
  439.                   if (!DO_FLAT) {
  440.                      VERT_SAVE_SPEC( 0 );
  441.                      VERT_SAVE_SPEC( 1 );
  442.                      VERT_SAVE_SPEC( 2 );
  443.                      VERT_SET_SPEC( v[0], vbspec[e0] );
  444.                      VERT_SET_SPEC( v[1], vbspec[e1] );
  445.                      VERT_SET_SPEC( v[2], vbspec[e2] );
  446.                   }
  447.                   VERT_SAVE_SPEC( 3 );
  448.                   VERT_SET_SPEC( v[3], vbspec[e3] );
  449.                }
  450.             }
  451.          }
  452.       }
  453.  
  454.  
  455.       if (DO_OFFSET)
  456.       {
  457.          offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
  458.          z[0] = VERT_Z(v[0]);
  459.          z[1] = VERT_Z(v[1]);
  460.          z[2] = VERT_Z(v[2]);
  461.          z[3] = VERT_Z(v[3]);
  462.          if (cc * cc > 1e-16) {
  463.             GLfloat ez = z[2] - z[0];
  464.             GLfloat fz = z[3] - z[1];
  465.             GLfloat a   = ey*fz - ez*fy;
  466.             GLfloat b   = ez*fx - ex*fz;
  467.             GLfloat ic  = 1.0 / cc;
  468.             GLfloat ac  = a * ic;
  469.             GLfloat bc  = b * ic;
  470.             if ( ac < 0.0f ) ac = -ac;
  471.             if ( bc < 0.0f ) bc = -bc;
  472.             offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
  473.          }
  474.          offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
  475.       }
  476.    }
  477.  
  478.    if (DO_FLAT) {
  479.          VERT_SAVE_RGBA( 0 );
  480.          VERT_SAVE_RGBA( 1 );
  481.          VERT_SAVE_RGBA( 2 );
  482.          VERT_COPY_RGBA( v[0], v[3] );
  483.          VERT_COPY_RGBA( v[1], v[3] );
  484.          VERT_COPY_RGBA( v[2], v[3] );
  485.          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
  486.             VERT_SAVE_SPEC( 0 );
  487.             VERT_SAVE_SPEC( 1 );
  488.             VERT_SAVE_SPEC( 2 );
  489.             VERT_COPY_SPEC( v[0], v[3] );
  490.             VERT_COPY_SPEC( v[1], v[3] );
  491.             VERT_COPY_SPEC( v[2], v[3] );
  492.          }
  493.    }
  494.  
  495.    if (mode == GL_POINT) {
  496.       if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
  497.          VERT_Z_ADD(v[0], offset);
  498.          VERT_Z_ADD(v[1], offset);
  499.          VERT_Z_ADD(v[2], offset);
  500.          VERT_Z_ADD(v[3], offset);
  501.       }
  502.       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
  503.          SETUP_STENCIL(facing);
  504.          UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
  505.          UNSET_STENCIL(facing);
  506.       } else {
  507.          UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
  508.       }
  509.    } else if (mode == GL_LINE) {
  510.       if (DO_OFFSET && ctx->Polygon.OffsetLine) {
  511.          VERT_Z_ADD(v[0], offset);
  512.          VERT_Z_ADD(v[1], offset);
  513.          VERT_Z_ADD(v[2], offset);
  514.          VERT_Z_ADD(v[3], offset);
  515.       }
  516.       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
  517.          SETUP_STENCIL(facing);
  518.          UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
  519.          UNSET_STENCIL(facing);
  520.       } else {
  521.          UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
  522.       }
  523.    } else {
  524.       if (DO_OFFSET && ctx->Polygon.OffsetFill) {
  525.          VERT_Z_ADD(v[0], offset);
  526.          VERT_Z_ADD(v[1], offset);
  527.          VERT_Z_ADD(v[2], offset);
  528.          VERT_Z_ADD(v[3], offset);
  529.       }
  530.       RASTERIZE( GL_QUADS );
  531.       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
  532.          SETUP_STENCIL(facing);
  533.          QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
  534.          UNSET_STENCIL(facing);
  535.       } else {
  536.          QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
  537.       }
  538.    }
  539.  
  540.    if (DO_OFFSET)
  541.    {
  542.       VERT_SET_Z(v[0], z[0]);
  543.       VERT_SET_Z(v[1], z[1]);
  544.       VERT_SET_Z(v[2], z[2]);
  545.       VERT_SET_Z(v[3], z[3]);
  546.    }
  547.  
  548.    if (DO_TWOSIDE && facing == 1) {
  549.       if (!DO_FLAT) {
  550.          VERT_RESTORE_RGBA( 0 );
  551.          VERT_RESTORE_RGBA( 1 );
  552.          VERT_RESTORE_RGBA( 2 );
  553.       }
  554.       VERT_RESTORE_RGBA( 3 );
  555.       if (HAVE_SPEC) {
  556.          if (!DO_FLAT) {
  557.             VERT_RESTORE_SPEC( 0 );
  558.             VERT_RESTORE_SPEC( 1 );
  559.             VERT_RESTORE_SPEC( 2 );
  560.          }
  561.          VERT_RESTORE_SPEC( 3 );
  562.       }
  563.    }
  564.  
  565.  
  566.    if (DO_FLAT) {
  567.          VERT_RESTORE_RGBA( 0 );
  568.          VERT_RESTORE_RGBA( 1 );
  569.          VERT_RESTORE_RGBA( 2 );
  570.          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
  571.             VERT_RESTORE_SPEC( 0 );
  572.             VERT_RESTORE_SPEC( 1 );
  573.             VERT_RESTORE_SPEC( 2 );
  574.          }
  575.    }
  576. }
  577. #else
  578. static void TAG(quadr)( struct gl_context *ctx, GLuint e0,
  579.                        GLuint e1, GLuint e2, GLuint e3 )
  580. {
  581.    if (DO_UNFILLED) {
  582.       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  583.       GLubyte ef1 = VB->EdgeFlag[e1];
  584.       GLubyte ef3 = VB->EdgeFlag[e3];
  585.       VB->EdgeFlag[e1] = 0;
  586.       TAG(triangle)( ctx, e0, e1, e3 );
  587.       VB->EdgeFlag[e1] = ef1;
  588.       VB->EdgeFlag[e3] = 0;
  589.       TAG(triangle)( ctx, e1, e2, e3 );
  590.       VB->EdgeFlag[e3] = ef3;
  591.    } else {
  592.       TAG(triangle)( ctx, e0, e1, e3 );
  593.       TAG(triangle)( ctx, e1, e2, e3 );
  594.    }
  595. }
  596. #endif
  597. #endif
  598.  
  599. #if DO_LINE
  600. static void TAG(line)( struct gl_context *ctx, GLuint e0, GLuint e1 )
  601. {
  602.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  603.    VERTEX *v[2];
  604.    LOCAL_VARS(2);
  605.  
  606.    v[0] = (VERTEX *)GET_VERTEX(e0);
  607.    v[1] = (VERTEX *)GET_VERTEX(e1);
  608.  
  609.    if (DO_FLAT) {
  610.          VERT_SAVE_RGBA( 0 );
  611.          VERT_COPY_RGBA( v[0], v[1] );
  612.          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
  613.             VERT_SAVE_SPEC( 0 );
  614.             VERT_COPY_SPEC( v[0], v[1] );
  615.          }
  616.    }
  617.  
  618.    LINE( v[0], v[1] );
  619.  
  620.    if (DO_FLAT) {
  621.          VERT_RESTORE_RGBA( 0 );
  622.  
  623.          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
  624.             VERT_RESTORE_SPEC( 0 );
  625.          }
  626.    }
  627. }
  628. #endif
  629.  
  630. #if DO_POINTS
  631. static void TAG(points)( struct gl_context *ctx, GLuint first, GLuint last )
  632. {
  633.    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
  634.    GLuint i;
  635.    LOCAL_VARS(1);
  636.  
  637.    if (VB->Elts == 0) {
  638.       for ( i = first ; i < last ; i++ ) {
  639.          if ( VB->ClipMask[i] == 0 ) {
  640.             VERTEX *v = (VERTEX *)GET_VERTEX(i);
  641.             POINT( v );
  642.          }
  643.       }
  644.    } else {
  645.       for ( i = first ; i < last ; i++ ) {
  646.          GLuint e = VB->Elts[i];
  647.          if ( VB->ClipMask[e] == 0 ) {
  648.             VERTEX *v = (VERTEX *)GET_VERTEX(e);
  649.             POINT( v );
  650.          }
  651.       }
  652.    }
  653. }
  654. #endif
  655.  
  656. static void TAG(init)( void )
  657. {
  658. #if DO_QUAD
  659.    TAB[IND].quad = TAG(quadr);
  660. #endif
  661. #if DO_TRI
  662.    TAB[IND].triangle = TAG(triangle);
  663. #endif
  664. #if DO_LINE
  665.    TAB[IND].line = TAG(line);
  666. #endif
  667. #if DO_POINTS
  668.    TAB[IND].points = TAG(points);
  669. #endif
  670. }
  671.  
  672. #undef IND
  673. #undef TAG
  674.  
  675. #if HAVE_BACK_COLORS
  676. #undef VERT_SET_RGBA
  677. #endif
  678.  
  679. #if !HAVE_SPEC
  680. #undef VERT_SET_SPEC
  681. #undef VERT_COPY_SPEC
  682. #undef VERT_SAVE_SPEC
  683. #undef VERT_RESTORE_SPEC
  684. #if HAVE_BACK_COLORS
  685. #undef VERT_COPY_SPEC1
  686. #endif
  687. #else
  688. #if HAVE_BACK_COLORS
  689. #undef VERT_SET_SPEC
  690. #endif
  691. #endif
  692.  
  693. #if !HAVE_BACK_COLORS
  694. #undef VERT_COPY_SPEC1
  695. #undef VERT_COPY_RGBA1
  696. #endif
  697.  
  698. #ifndef INSANE_VERTICES
  699. #undef VERT_SET_Z
  700. #undef VERT_Z_ADD
  701. #endif
  702.