home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_tritemp.h < prev    next >
C/C++ Source or Header  |  2002-12-29  |  56KB  |  1,413 lines

  1. /* $Id: s_tritemp.h,v 1.41 2002/11/13 16:51:02 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26. /* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.2 2002/02/27 21:07:54 tsi Exp $ */
  27.  
  28. /*
  29.  * Triangle Rasterizer Template
  30.  *
  31.  * This file is #include'd to generate custom triangle rasterizers.
  32.  *
  33.  * The following macros may be defined to indicate what auxillary information
  34.  * must be interplated across the triangle:
  35.  *    INTERP_Z        - if defined, interpolate Z values
  36.  *    INTERP_FOG      - if defined, interpolate fog values
  37.  *    INTERP_RGB      - if defined, interpolate RGB values
  38.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  39.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  40.  *    INTERP_INDEX    - if defined, interpolate color index values
  41.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  42.  *                         (fast, simple 2-D texture mapping)
  43.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  44.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  45.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  46.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  47.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  48.  *
  49.  * When one can directly address pixels in the color buffer the following
  50.  * macros can be defined and used to compute pixel addresses during
  51.  * rasterization (see pRow):
  52.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  53.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  54.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  55.  *                          Y==0 at bottom of screen and increases upward.
  56.  *
  57.  * Similarly, for direct depth buffer access, this type is used for depth
  58.  * buffer addressing:
  59.  *    DEPTH_TYPE          - either GLushort or GLuint
  60.  *
  61.  * Optionally, one may provide one-time setup code per triangle:
  62.  *    SETUP_CODE    - code which is to be executed once per triangle
  63.  *    CLEANUP_CODE    - code to execute at end of triangle
  64.  *
  65.  * The following macro MUST be defined:
  66.  *    RENDER_SPAN(span) - code to write a span of pixels.
  67.  *
  68.  * This code was designed for the origin to be in the lower-left corner.
  69.  *
  70.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  71.  */
  72.  
  73.  
  74. /*
  75.  * This is a bit of a hack, but it's a centralized place to enable floating-
  76.  * point color interpolation when GLchan is actually floating point.
  77.  */
  78. #if CHAN_TYPE == GL_FLOAT
  79.  
  80. #if defined(INTERP_RGB)
  81. #undef INTERP_RGB
  82. #undef INTERP_ALPHA
  83. #define INTERP_FLOAT_RGBA
  84. #endif
  85.  
  86. #if defined(INTERP_SPEC)
  87. #undef INTERP_SPEC
  88. #define INTERP_FLOAT_SPEC
  89. #endif
  90.  
  91. #endif /* CHAN_TYPE == GL_FLOAT */
  92.  
  93.  
  94.  
  95. static void NAME(GLcontext *ctx, const SWvertex *v0,
  96.                                  const SWvertex *v1,
  97.                                  const SWvertex *v2 )
  98. {
  99.    typedef struct {
  100.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  101.         GLfloat dx;    /* X(v1) - X(v0) */
  102.         GLfloat dy;    /* Y(v1) - Y(v0) */
  103.         GLfixed fdxdy;    /* dx/dy in fixed-point */
  104.         GLfixed fsx;    /* first sample point x coord */
  105.         GLfixed fsy;
  106.         GLfloat adjy;    /* adjust from v[0]->fy to fsy, scaled */
  107.         GLint lines;    /* number of lines to be sampled on this edge */
  108.         GLfixed fx0;    /* fixed pt X of lower endpoint */
  109.    } EdgeT;
  110.  
  111. #ifdef INTERP_Z
  112.    const GLint depthBits = ctx->Visual.depthBits;
  113.    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
  114.    const GLfloat maxDepth = ctx->DepthMaxF;
  115. #define FixedToDepth(F)  ((F) >> fixedToDepthShift)
  116. #endif
  117.    EdgeT eMaj, eTop, eBot;
  118.    GLfloat oneOverArea;
  119.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  120.    float bf = SWRAST_CONTEXT(ctx)->_backface_sign;
  121.    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
  122.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  123.  
  124.    struct sw_span span;
  125.  
  126.    INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
  127.  
  128. #ifdef INTERP_Z
  129.    (void) fixedToDepthShift;
  130. #endif
  131.  
  132.    /* 
  133.    printf("%s()\n", __FUNCTION__);
  134.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  135.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  136.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  137.     */
  138.  
  139.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  140.     * And find the order of the 3 vertices along the Y axis.
  141.     */
  142.    {
  143.       const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
  144.       const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
  145.       const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
  146.  
  147.       if (fy0 <= fy1) {
  148.          if (fy1 <= fy2) {
  149.             /* y0 <= y1 <= y2 */
  150.             vMin = v0;   vMid = v1;   vMax = v2;
  151.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  152.          }
  153.          else if (fy2 <= fy0) {
  154.             /* y2 <= y0 <= y1 */
  155.             vMin = v2;   vMid = v0;   vMax = v1;
  156.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  157.          }
  158.          else {
  159.             /* y0 <= y2 <= y1 */
  160.             vMin = v0;   vMid = v2;   vMax = v1;
  161.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  162.             bf = -bf;
  163.          }
  164.       }
  165.       else {
  166.          if (fy0 <= fy2) {
  167.             /* y1 <= y0 <= y2 */
  168.             vMin = v1;   vMid = v0;   vMax = v2;
  169.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  170.             bf = -bf;
  171.          }
  172.          else if (fy2 <= fy1) {
  173.             /* y2 <= y1 <= y0 */
  174.             vMin = v2;   vMid = v1;   vMax = v0;
  175.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  176.             bf = -bf;
  177.          }
  178.          else {
  179.             /* y1 <= y2 <= y0 */
  180.             vMin = v1;   vMid = v2;   vMax = v0;
  181.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  182.          }
  183.       }
  184.  
  185.       /* fixed point X coords */
  186.       vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
  187.       vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
  188.       vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
  189.    }
  190.  
  191.    /* vertex/edge relationship */
  192.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  193.    eTop.v0 = vMid;   eTop.v1 = vMax;
  194.    eBot.v0 = vMin;   eBot.v1 = vMid;
  195.  
  196.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  197.    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
  198.    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
  199.    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
  200.    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
  201.    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
  202.    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
  203.  
  204.    /* compute area, oneOverArea and perform backface culling */
  205.    {
  206.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  207.  
  208.       /* Do backface culling */
  209.       if (area * bf < 0.0)
  210.          return;
  211.  
  212.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  213.          return;
  214.  
  215.       oneOverArea = 1.0F / area;
  216.    }
  217.  
  218. #ifndef DO_OCCLUSION_TEST
  219.    ctx->OcclusionResult = GL_TRUE;
  220. #endif
  221.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  222.  
  223.    /* Edge setup.  For a triangle strip these could be reused... */
  224.    {
  225.       eMaj.fsy = FixedCeil(vMin_fy);
  226.       eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
  227.       if (eMaj.lines > 0) {
  228.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  229.          eMaj.fdxdy = SignedFloatToFixed(dxdy);
  230.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  231.          eMaj.fx0 = vMin_fx;
  232.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  233.       }
  234.       else {
  235.          return;  /*CULLED*/
  236.       }
  237.  
  238.       eTop.fsy = FixedCeil(vMid_fy);
  239.       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
  240.       if (eTop.lines > 0) {
  241.          GLfloat dxdy = eTop.dx / eTop.dy;
  242.          eTop.fdxdy = SignedFloatToFixed(dxdy);
  243.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  244.          eTop.fx0 = vMid_fx;
  245.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  246.       }
  247.  
  248.       eBot.fsy = FixedCeil(vMin_fy);
  249.       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
  250.       if (eBot.lines > 0) {
  251.          GLfloat dxdy = eBot.dx / eBot.dy;
  252.          eBot.fdxdy = SignedFloatToFixed(dxdy);
  253.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  254.          eBot.fx0 = vMin_fx;
  255.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  256.       }
  257.    }
  258.  
  259.    /*
  260.     * Conceptually, we view a triangle as two subtriangles
  261.     * separated by a perfectly horizontal line.  The edge that is
  262.     * intersected by this line is one with maximal absolute dy; we
  263.     * call it a ``major'' edge.  The other two edges are the
  264.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  265.     * edge (for the lower subtriangle).  If either of these two
  266.     * edges is horizontal or very close to horizontal, the
  267.     * corresponding subtriangle might cover zero sample points;
  268.     * we take care to handle such cases, for performance as well
  269.     * as correctness.
  270.     *
  271.     * By stepping rasterization parameters along the major edge,
  272.     * we can avoid recomputing them at the discontinuity where
  273.     * the top and bottom edges meet.  However, this forces us to
  274.     * be able to scan both left-to-right and right-to-left.
  275.     * Also, we must determine whether the major edge is at the
  276.     * left or right side of the triangle.  We do this by
  277.     * computing the magnitude of the cross-product of the major
  278.     * and top edges.  Since this magnitude depends on the sine of
  279.     * the angle between the two edges, its sign tells us whether
  280.     * we turn to the left or to the right when travelling along
  281.     * the major edge to the top edge, and from this we infer
  282.     * whether the major edge is on the left or the right.
  283.     *
  284.     * Serendipitously, this cross-product magnitude is also a
  285.     * value we need to compute the iteration parameter
  286.     * derivatives for the triangle, and it can be used to perform
  287.     * backface culling because its sign tells us whether the
  288.     * triangle is clockwise or counterclockwise.  In this code we
  289.     * refer to it as ``area'' because it's also proportional to
  290.     * the pixel area of the triangle.
  291.     */
  292.  
  293.    {
  294.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  295. #ifdef INTERP_Z
  296.       GLfloat dzdx, dzdy;
  297. #endif
  298. #ifdef INTERP_FOG
  299.       GLfloat dfogdy;
  300. #endif
  301. #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
  302.       GLfloat drdx, drdy;
  303.       GLfloat dgdx, dgdy;
  304.       GLfloat dbdx, dbdy;
  305. #endif
  306. #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
  307.       GLfloat dadx, dady;
  308. #endif
  309. #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
  310.       GLfloat dsrdx, dsrdy;
  311.       GLfloat dsgdx, dsgdy;
  312.       GLfloat dsbdx, dsbdy;
  313. #endif
  314. #ifdef INTERP_INDEX
  315.       GLfloat didx, didy;
  316. #endif
  317. #ifdef INTERP_INT_TEX
  318.       GLfloat dsdx, dsdy;
  319.       GLfloat dtdx, dtdy;
  320. #endif
  321. #ifdef INTERP_TEX
  322.       GLfloat dsdx, dsdy;
  323.       GLfloat dtdx, dtdy;
  324.       GLfloat dudx, dudy;
  325.       GLfloat dvdx, dvdy;
  326. #endif
  327. #ifdef INTERP_MULTITEX
  328.       GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS];
  329.       GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS];
  330.       GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS];
  331.       GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];
  332. #endif
  333.  
  334.       /*
  335.        * Execute user-supplied setup code
  336.        */
  337. #ifdef SETUP_CODE
  338.       SETUP_CODE
  339. #endif
  340.  
  341.       scan_from_left_to_right = (oneOverArea < 0.0F);
  342.  
  343.  
  344.       /* compute d?/dx and d?/dy derivatives */
  345. #ifdef INTERP_Z
  346.       span.interpMask |= SPAN_Z;
  347.       {
  348.          GLfloat eMaj_dz, eBot_dz;
  349.          eMaj_dz = vMax->win[2] - vMin->win[2];
  350.          eBot_dz = vMid->win[2] - vMin->win[2];
  351.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  352.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  353.             /* probably a sliver triangle */
  354.             dzdx = 0.0;
  355.             dzdy = 0.0;
  356.          }
  357.          else {
  358.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  359.          }
  360.          if (depthBits <= 16)
  361.             span.zStep = SignedFloatToFixed(dzdx);
  362.          else
  363.             span.zStep = (GLint) dzdx;
  364.       }
  365. #endif
  366. #ifdef INTERP_FOG
  367.       span.interpMask |= SPAN_FOG;
  368.       {
  369.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  370.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  371.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  372.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  373.       }
  374. #endif
  375. #ifdef INTERP_RGB
  376.       span.interpMask |= SPAN_RGBA;
  377.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  378.          GLfloat eMaj_dr, eBot_dr;
  379.          GLfloat eMaj_dg, eBot_dg;
  380.          GLfloat eMaj_db, eBot_db;
  381. #  ifdef INTERP_ALPHA
  382.          GLfloat eMaj_da, eBot_da;
  383. #  endif
  384.          eMaj_dr = (GLfloat) ((GLint) vMax->color[RCOMP] - 
  385.                   (GLint) vMin->color[RCOMP]);
  386.          eBot_dr = (GLfloat) ((GLint) vMid->color[RCOMP] - 
  387.                   (GLint) vMin->color[RCOMP]);
  388.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  389.          span.redStep = SignedFloatToFixed(drdx);
  390.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  391.          eMaj_dg = (GLfloat) ((GLint) vMax->color[GCOMP] - 
  392.                   (GLint) vMin->color[GCOMP]);
  393.          eBot_dg = (GLfloat) ((GLint) vMid->color[GCOMP] - 
  394.                   (GLint) vMin->color[GCOMP]);
  395.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  396.          span.greenStep = SignedFloatToFixed(dgdx);
  397.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  398.          eMaj_db = (GLfloat) ((GLint) vMax->color[BCOMP] - 
  399.                   (GLint) vMin->color[BCOMP]);
  400.          eBot_db = (GLfloat) ((GLint) vMid->color[BCOMP] - 
  401.                   (GLint) vMin->color[BCOMP]);
  402.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  403.          span.blueStep = SignedFloatToFixed(dbdx);
  404.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  405. #  ifdef INTERP_ALPHA
  406.          eMaj_da = (GLfloat) ((GLint) vMax->color[ACOMP] - 
  407.                   (GLint) vMin->color[ACOMP]);
  408.          eBot_da = (GLfloat) ((GLint) vMid->color[ACOMP] - 
  409.                   (GLint) vMin->color[ACOMP]);
  410.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  411.          span.alphaStep = SignedFloatToFixed(dadx);
  412.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  413. #  endif
  414.       }
  415.       else {
  416.          ASSERT (ctx->Light.ShadeModel == GL_FLAT);
  417.          span.interpMask |= SPAN_FLAT;
  418.          drdx = drdy = 0.0F;
  419.          dgdx = dgdy = 0.0F;
  420.          dbdx = dbdy = 0.0F;
  421.          span.redStep = 0;
  422.          span.greenStep = 0;
  423.          span.blueStep = 0;
  424. #  ifdef INTERP_ALPHA
  425.          dadx = dady = 0.0F;
  426.          span.alphaStep = 0;
  427. #  endif
  428.       }
  429. #endif
  430. #ifdef INTERP_FLOAT_RGBA
  431.       span.interpMask |= SPAN_RGBA;
  432.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  433.          GLfloat eMaj_dr, eBot_dr;
  434.          GLfloat eMaj_dg, eBot_dg;
  435.          GLfloat eMaj_db, eBot_db;
  436.          GLfloat eMaj_da, eBot_da;
  437.          eMaj_dr = vMax->color[RCOMP] - vMin->color[RCOMP];
  438.          eBot_dr = vMid->color[RCOMP] - vMin->color[RCOMP];
  439.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  440.          span.redStep = drdx;
  441.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  442.          eMaj_dg = vMax->color[GCOMP] - vMin->color[GCOMP];
  443.          eBot_dg = vMid->color[GCOMP] - vMin->color[GCOMP];
  444.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  445.          span.greenStep = dgdx;
  446.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  447.          eMaj_db = vMax->color[BCOMP] - vMin->color[BCOMP];
  448.          eBot_db = vMid->color[BCOMP] - vMin->color[BCOMP];
  449.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  450.          span.blueStep = dbdx;
  451.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  452.          eMaj_da = vMax->color[ACOMP] - vMin->color[ACOMP];
  453.          eBot_da = vMid->color[ACOMP] - vMin->color[ACOMP];
  454.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  455.          span.alphaStep = dadx;
  456.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  457.       }
  458.       else {
  459.          drdx = drdy = span.redStep = 0.0F;
  460.          dgdx = dgdy = span.greenStep = 0.0F;
  461.          dbdx = dbdy = span.blueStep = 0.0F;
  462.          dadx = dady = span.alphaStep = 0.0F;
  463.       }
  464. #endif
  465. #ifdef INTERP_SPEC
  466.       span.interpMask |= SPAN_SPEC;
  467.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  468.          GLfloat eMaj_dsr, eBot_dsr;
  469.          GLfloat eMaj_dsg, eBot_dsg;
  470.          GLfloat eMaj_dsb, eBot_dsb;
  471.          eMaj_dsr = (GLfloat) ((GLint) vMax->specular[RCOMP] - 
  472.                    (GLint) vMin->specular[RCOMP]);
  473.          eBot_dsr = (GLfloat) ((GLint) vMid->specular[RCOMP] - 
  474.                    (GLint) vMin->specular[RCOMP]);
  475.          dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
  476.          span.specRedStep = SignedFloatToFixed(dsrdx);
  477.          dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
  478.          eMaj_dsg = (GLfloat) ((GLint) vMax->specular[GCOMP] - 
  479.                    (GLint) vMin->specular[GCOMP]);
  480.          eBot_dsg = (GLfloat) ((GLint) vMid->specular[GCOMP] - 
  481.                    (GLint) vMin->specular[GCOMP]);
  482.          dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
  483.          span.specGreenStep = SignedFloatToFixed(dsgdx);
  484.          dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
  485.          eMaj_dsb = (GLfloat) ((GLint) vMax->specular[BCOMP] - 
  486.                    (GLint) vMin->specular[BCOMP]);
  487.          eBot_dsb = (GLfloat) ((GLint) vMid->specular[BCOMP] - 
  488.                    (GLint) vMin->specular[BCOMP]);
  489.          dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
  490.          span.specBlueStep = SignedFloatToFixed(dsbdx);
  491.          dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
  492.       }
  493.       else {
  494.          dsrdx = dsrdy = 0.0F;
  495.          dsgdx = dsgdy = 0.0F;
  496.          dsbdx = dsbdy = 0.0F;
  497.          span.specRedStep = 0;
  498.          span.specGreenStep = 0;
  499.          span.specBlueStep = 0;
  500.       }
  501. #endif
  502. #ifdef INTERP_FLOAT_SPEC
  503.       span.interpMask |= SPAN_SPEC;
  504.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  505.          GLfloat eMaj_dsr, eBot_dsr;
  506.          GLfloat eMaj_dsg, eBot_dsg;
  507.          GLfloat eMaj_dsb, eBot_dsb;
  508.          eMaj_dsr = vMax->specular[RCOMP] - vMin->specular[RCOMP];
  509.          eBot_dsr = vMid->specular[RCOMP] - vMin->specular[RCOMP];
  510.          dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
  511.          span.specRedStep = dsrdx;
  512.          dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
  513.          eMaj_dsg = vMax->specular[GCOMP] - vMin->specular[GCOMP];
  514.          eBot_dsg = vMid->specular[GCOMP] - vMin->specular[GCOMP];
  515.          dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
  516.          span.specGreenStep = dsgdx;
  517.          dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
  518.          eMaj_dsb = vMax->specular[BCOMP] - vMin->specular[BCOMP];
  519.          eBot_dsb = vMid->specular[BCOMP] - vMin->specular[BCOMP];
  520.          dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
  521.          span.specBlueStep = dsbdx;
  522.          dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
  523.       }
  524.       else {
  525.          dsrdx = dsrdy = span.specRedStep = 0;
  526.          dsgdx = dsgdy = span.specGreenStep = 0;
  527.          dsbdx = dsbdy = span.specBlueStep = 0;
  528.       }
  529. #endif
  530. #ifdef INTERP_INDEX
  531.       span.interpMask |= SPAN_INDEX;
  532.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  533.          GLfloat eMaj_di, eBot_di;
  534.          eMaj_di = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index);
  535.          eBot_di = (GLfloat) ((GLint) vMid->index - (GLint) vMin->index);
  536.          didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
  537.          span.indexStep = SignedFloatToFixed(didx);
  538.          didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
  539.       }
  540.       else {
  541.          span.interpMask |= SPAN_FLAT;
  542.          didx = didy = 0.0F;
  543.          span.indexStep = 0;
  544.       }
  545. #endif
  546. #ifdef INTERP_INT_TEX
  547.       span.interpMask |= SPAN_INT_TEXTURE;
  548.       {
  549.          GLfloat eMaj_ds, eBot_ds;
  550.          eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
  551.          eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
  552.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  553.          span.intTexStep[0] = SignedFloatToFixed(dsdx);
  554.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  555.       }
  556.       {
  557.          GLfloat eMaj_dt, eBot_dt;
  558.          eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
  559.          eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
  560.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  561.          span.intTexStep[1] = SignedFloatToFixed(dtdx);
  562.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  563.       }
  564.  
  565. #endif
  566. #ifdef INTERP_TEX
  567.       span.interpMask |= SPAN_TEXTURE;
  568.       {
  569.          GLfloat wMax = vMax->win[3];
  570.          GLfloat wMin = vMin->win[3];
  571.          GLfloat wMid = vMid->win[3];
  572.          GLfloat eMaj_ds, eBot_ds;
  573.          GLfloat eMaj_dt, eBot_dt;
  574.          GLfloat eMaj_du, eBot_du;
  575.          GLfloat eMaj_dv, eBot_dv;
  576.  
  577.          eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
  578.          eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
  579.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  580.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  581.          span.texStepX[0][0] = dsdx;
  582.          span.texStepY[0][0] = dsdy;
  583.  
  584.          eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
  585.          eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
  586.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  587.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  588.          span.texStepX[0][1] = dtdx;
  589.          span.texStepY[0][1] = dtdy;
  590.  
  591.          eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
  592.          eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
  593.          dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  594.          dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  595.          span.texStepX[0][2] = dudx;
  596.          span.texStepY[0][2] = dudy;
  597.  
  598.          eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
  599.          eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
  600.          dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  601.          dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  602.          span.texStepX[0][3] = dvdx;
  603.          span.texStepY[0][3] = dvdy;
  604.       }
  605. #endif
  606. #ifdef INTERP_MULTITEX
  607.       span.interpMask |= SPAN_TEXTURE;
  608.       {
  609.          GLfloat wMax = vMax->win[3];
  610.          GLfloat wMin = vMin->win[3];
  611.          GLfloat wMid = vMid->win[3];
  612.          GLuint u;
  613.          for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  614.             if (ctx->Texture.Unit[u]._ReallyEnabled) {
  615.                GLfloat eMaj_ds, eBot_ds;
  616.                GLfloat eMaj_dt, eBot_dt;
  617.                GLfloat eMaj_du, eBot_du;
  618.                GLfloat eMaj_dv, eBot_dv;
  619.                eMaj_ds = vMax->texcoord[u][0] * wMax
  620.                        - vMin->texcoord[u][0] * wMin;
  621.                eBot_ds = vMid->texcoord[u][0] * wMid
  622.                        - vMin->texcoord[u][0] * wMin;
  623.                dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  624.                dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  625.                span.texStepX[u][0] = dsdx[u];
  626.                span.texStepY[u][0] = dsdy[u];
  627.  
  628.                eMaj_dt = vMax->texcoord[u][1] * wMax
  629.                        - vMin->texcoord[u][1] * wMin;
  630.                eBot_dt = vMid->texcoord[u][1] * wMid
  631.                        - vMin->texcoord[u][1] * wMin;
  632.                dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  633.                dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  634.                span.texStepX[u][1] = dtdx[u];
  635.                span.texStepY[u][1] = dtdy[u];
  636.  
  637.                eMaj_du = vMax->texcoord[u][2] * wMax
  638.                        - vMin->texcoord[u][2] * wMin;
  639.                eBot_du = vMid->texcoord[u][2] * wMid
  640.                        - vMin->texcoord[u][2] * wMin;
  641.                dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  642.                dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  643.                span.texStepX[u][2] = dudx[u];
  644.                span.texStepY[u][2] = dudy[u];
  645.  
  646.                eMaj_dv = vMax->texcoord[u][3] * wMax
  647.                        - vMin->texcoord[u][3] * wMin;
  648.                eBot_dv = vMid->texcoord[u][3] * wMid
  649.                        - vMin->texcoord[u][3] * wMin;
  650.                dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  651.                dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  652.                span.texStepX[u][3] = dvdx[u];
  653.                span.texStepY[u][3] = dvdy[u];
  654.             }
  655.          }
  656.       }
  657. #endif
  658.  
  659.       /*
  660.        * We always sample at pixel centers.  However, we avoid
  661.        * explicit half-pixel offsets in this code by incorporating
  662.        * the proper offset in each of x and y during the
  663.        * transformation to window coordinates.
  664.        *
  665.        * We also apply the usual rasterization rules to prevent
  666.        * cracks and overlaps.  A pixel is considered inside a
  667.        * subtriangle if it meets all of four conditions: it is on or
  668.        * to the right of the left edge, strictly to the left of the
  669.        * right edge, on or below the top edge, and strictly above
  670.        * the bottom edge.  (Some edges may be degenerate.)
  671.        *
  672.        * The following discussion assumes left-to-right scanning
  673.        * (that is, the major edge is on the left); the right-to-left
  674.        * case is a straightforward variation.
  675.        *
  676.        * We start by finding the half-integral y coordinate that is
  677.        * at or below the top of the triangle.  This gives us the
  678.        * first scan line that could possibly contain pixels that are
  679.        * inside the triangle.
  680.        *
  681.        * Next we creep down the major edge until we reach that y,
  682.        * and compute the corresponding x coordinate on the edge.
  683.        * Then we find the half-integral x that lies on or just
  684.        * inside the edge.  This is the first pixel that might lie in
  685.        * the interior of the triangle.  (We won't know for sure
  686.        * until we check the other edges.)
  687.        *
  688.        * As we rasterize the triangle, we'll step down the major
  689.        * edge.  For each step in y, we'll move an integer number
  690.        * of steps in x.  There are two possible x step sizes, which
  691.        * we'll call the ``inner'' step (guaranteed to land on the
  692.        * edge or inside it) and the ``outer'' step (guaranteed to
  693.        * land on the edge or outside it).  The inner and outer steps
  694.        * differ by one.  During rasterization we maintain an error
  695.        * term that indicates our distance from the true edge, and
  696.        * select either the inner step or the outer step, whichever
  697.        * gets us to the first pixel that falls inside the triangle.
  698.        *
  699.        * All parameters (z, red, etc.) as well as the buffer
  700.        * addresses for color and z have inner and outer step values,
  701.        * so that we can increment them appropriately.  This method
  702.        * eliminates the need to adjust parameters by creeping a
  703.        * sub-pixel amount into the triangle at each scanline.
  704.        */
  705.  
  706.       {
  707.          int subTriangle;
  708.          GLfixed fx;
  709.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  710.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  711.          GLfixed fdxOuter;
  712.          int idxOuter;
  713.          float dxOuter;
  714.          GLfixed fError = 0, fdError = 0;
  715.          float adjx, adjy;
  716.          GLfixed fy;
  717. #ifdef PIXEL_ADDRESS
  718.          PIXEL_TYPE *pRow = NULL;
  719.          int dPRowOuter = 0, dPRowInner;  /* offset in bytes */
  720. #endif
  721. #ifdef INTERP_Z
  722. #  ifdef DEPTH_TYPE
  723.          DEPTH_TYPE *zRow = NULL;
  724.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  725. #  endif
  726.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  727. #endif
  728. #ifdef INTERP_FOG
  729.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  730. #endif
  731. #ifdef INTERP_RGB
  732.          GLfixed fr = 0, fdrOuter = 0, fdrInner;
  733.          GLfixed fg = 0, fdgOuter = 0, fdgInner;
  734.          GLfixed fb = 0, fdbOuter = 0, fdbInner;
  735. #endif
  736. #ifdef INTERP_ALPHA
  737.          GLfixed fa = 0, fdaOuter = 0, fdaInner;
  738. #endif
  739. #ifdef INTERP_FLOAT_RGBA
  740.          GLfloat fr, fdrOuter, fdrInner;
  741.          GLfloat fg, fdgOuter, fdgInner;
  742.          GLfloat fb, fdbOuter, fdbInner;
  743.          GLfloat fa, fdaOuter, fdaInner;
  744. #endif
  745. #ifdef INTERP_SPEC
  746.          GLfixed fsr=0, fdsrOuter=0, fdsrInner;
  747.          GLfixed fsg=0, fdsgOuter=0, fdsgInner;
  748.          GLfixed fsb=0, fdsbOuter=0, fdsbInner;
  749. #endif
  750. #ifdef INTERP_FLOAT_SPEC
  751.          GLfloat fsr=0, fdsrOuter=0, fdsrInner;
  752.          GLfloat fsg=0, fdsgOuter=0, fdsgInner;
  753.          GLfloat fsb=0, fdsbOuter=0, fdsbInner;
  754. #endif
  755. #ifdef INTERP_INDEX
  756.          GLfixed fi=0, fdiOuter=0, fdiInner;
  757. #endif
  758. #ifdef INTERP_INT_TEX
  759.          GLfixed fs=0, fdsOuter=0, fdsInner;
  760.          GLfixed ft=0, fdtOuter=0, fdtInner;
  761. #endif
  762. #ifdef INTERP_TEX
  763.          GLfloat sLeft=0, dsOuter=0, dsInner;
  764.          GLfloat tLeft=0, dtOuter=0, dtInner;
  765.          GLfloat uLeft=0, duOuter=0, duInner;
  766.          GLfloat vLeft=0, dvOuter=0, dvInner;
  767. #endif
  768. #ifdef INTERP_MULTITEX
  769.          GLfloat sLeft[MAX_TEXTURE_UNITS];
  770.          GLfloat tLeft[MAX_TEXTURE_UNITS];
  771.          GLfloat uLeft[MAX_TEXTURE_UNITS];
  772.          GLfloat vLeft[MAX_TEXTURE_UNITS];
  773.          GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS];
  774.          GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS];
  775.          GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS];
  776.          GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS];
  777. #endif
  778.  
  779.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  780.             EdgeT *eLeft, *eRight;
  781.             int setupLeft, setupRight;
  782.             int lines;
  783.  
  784.             if (subTriangle==0) {
  785.                /* bottom half */
  786.                if (scan_from_left_to_right) {
  787.                   eLeft = &eMaj;
  788.                   eRight = &eBot;
  789.                   lines = eRight->lines;
  790.                   setupLeft = 1;
  791.                   setupRight = 1;
  792.                }
  793.                else {
  794.                   eLeft = &eBot;
  795.                   eRight = &eMaj;
  796.                   lines = eLeft->lines;
  797.                   setupLeft = 1;
  798.                   setupRight = 1;
  799.                }
  800.             }
  801.             else {
  802.                /* top half */
  803.                if (scan_from_left_to_right) {
  804.                   eLeft = &eMaj;
  805.                   eRight = &eTop;
  806.                   lines = eRight->lines;
  807.                   setupLeft = 0;
  808.                   setupRight = 1;
  809.                }
  810.                else {
  811.                   eLeft = &eTop;
  812.                   eRight = &eMaj;
  813.                   lines = eLeft->lines;
  814.                   setupLeft = 1;
  815.                   setupRight = 0;
  816.                }
  817.                if (lines == 0)
  818.                   return;
  819.             }
  820.  
  821.             if (setupLeft && eLeft->lines > 0) {
  822.                const SWvertex *vLower;
  823.                GLfixed fsx = eLeft->fsx;
  824.                fx = FixedCeil(fsx);
  825.                fError = fx - fsx - FIXED_ONE;
  826.                fxLeftEdge = fsx - FIXED_EPSILON;
  827.                fdxLeftEdge = eLeft->fdxdy;
  828.                fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
  829.                fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
  830.                idxOuter = FixedToInt(fdxOuter);
  831.                dxOuter = (float) idxOuter;
  832.                (void) dxOuter;
  833.  
  834.                fy = eLeft->fsy;
  835.                span.y = FixedToInt(fy);
  836.  
  837.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  838.                adjy = eLeft->adjy;         /* SCALED! */
  839. #ifndef(__OS2__)
  840.                (void) adjx;  /* silence compiler warnings */
  841.                (void) adjy;  /* silence compiler warnings */
  842. #endif
  843.                vLower = eLeft->v0;
  844. #ifndef(__OS2__)
  845.                (void) vLower;  /* silence compiler warnings */
  846. #endif
  847. #ifdef PIXEL_ADDRESS
  848.                {
  849.                   pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
  850.                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
  851.                   /* negative because Y=0 at bottom and increases upward */
  852.                }
  853. #endif
  854.                /*
  855.                 * Now we need the set of parameter (z, color, etc.) values at
  856.                 * the point (fx, fy).  This gives us properly-sampled parameter
  857.                 * values that we can step from pixel to pixel.  Furthermore,
  858.                 * although we might have intermediate results that overflow
  859.                 * the normal parameter range when we step temporarily outside
  860.                 * the triangle, we shouldn't overflow or underflow for any
  861.                 * pixel that's actually inside the triangle.
  862.                 */
  863.  
  864. #ifdef INTERP_Z
  865.                {
  866.                   GLfloat z0 = vLower->win[2];
  867.                   if (depthBits <= 16) {
  868.                      /* interpolate fixed-pt values */
  869.                      GLfloat tmp = (z0 * FIXED_SCALE +
  870.                                     dzdx * adjx + dzdy * adjy) + FIXED_HALF;
  871.                      if (tmp < MAX_GLUINT / 2)
  872.                         fz = (GLfixed) tmp;
  873.                      else
  874.                         fz = MAX_GLUINT / 2;
  875.                      fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
  876.                   }
  877.                   else {
  878.                      /* interpolate depth values exactly */
  879.                      fz = (GLint) (z0 + dzdx * FixedToFloat(adjx)
  880.                                    + dzdy * FixedToFloat(adjy));
  881.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  882.                   }
  883. #  ifdef DEPTH_TYPE
  884.                   zRow = (DEPTH_TYPE *)
  885.                     _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y);
  886.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
  887. #  endif
  888.                }
  889. #endif
  890. #ifdef INTERP_FOG
  891.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  892.                                        * (1.0F/FIXED_SCALE);
  893.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  894. #endif
  895. #ifdef INTERP_RGB
  896.                if (ctx->Light.ShadeModel == GL_SMOOTH) {
  897.                   fr = (GLfixed) (ChanToFixed(vLower->color[RCOMP])
  898.                                    + drdx * adjx + drdy * adjy) + FIXED_HALF;
  899.                   fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
  900.                   fg = (GLfixed) (ChanToFixed(vLower->color[GCOMP])
  901.                                    + dgdx * adjx + dgdy * adjy) + FIXED_HALF;
  902.                   fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
  903.                   fb = (GLfixed) (ChanToFixed(vLower->color[BCOMP])
  904.                                     + dbdx * adjx + dbdy * adjy) + FIXED_HALF;
  905.                   fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
  906. #  ifdef INTERP_ALPHA
  907.                   fa = (GLfixed) (ChanToFixed(vLower->color[ACOMP])
  908.                                    + dadx * adjx + dady * adjy) + FIXED_HALF;
  909.                   fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
  910. #  endif
  911.                }
  912.                else {
  913.                   ASSERT (ctx->Light.ShadeModel == GL_FLAT);
  914.                   fr = ChanToFixed(v2->color[RCOMP]);
  915.                   fg = ChanToFixed(v2->color[GCOMP]);
  916.                   fb = ChanToFixed(v2->color[BCOMP]);
  917.                   fdrOuter = fdgOuter = fdbOuter = 0;
  918. #  ifdef INTERP_ALPHA
  919.                   fa =  ChanToFixed(v2->color[ACOMP]);
  920.                   fdaOuter = 0;
  921. #  endif
  922.                }
  923. #endif
  924. #ifdef INTERP_FLOAT_RGBA
  925.                if (ctx->Light.ShadeModel == GL_SMOOTH) {
  926.                   fr = vLower->color[RCOMP]
  927.                      + (drdx * adjx + drdy * adjy) * (1.0F / FIXED_SCALE);
  928.                   fdrOuter = drdy + dxOuter * drdx;
  929.                   fg = vLower->color[GCOMP]
  930.                      + (dgdx * adjx + dgdy * adjy) * (1.0F / FIXED_SCALE);
  931.                   fdgOuter = dgdy + dxOuter * dgdx;
  932.                   fb = vLower->color[BCOMP]
  933.                      + (dbdx * adjx + dbdy * adjy) * (1.0F / FIXED_SCALE);
  934.                   fdbOuter = dbdy + dxOuter * dbdx;
  935.                   fa = vLower->color[ACOMP]
  936.                      + (dadx * adjx + dady * adjy) * (1.0F / FIXED_SCALE);
  937.                   fdaOuter = dady + dxOuter * dadx;
  938.                }
  939.                else {
  940.                   fr = v2->color[RCOMP];
  941.                   fg = v2->color[GCOMP];
  942.                   fb = v2->color[BCOMP];
  943.                   fa = v2->color[ACOMP];
  944.                   fdrOuter = fdgOuter = fdbOuter = fdaOuter = 0.0F;
  945.                }
  946. #endif
  947. #ifdef INTERP_SPEC
  948.                if (ctx->Light.ShadeModel == GL_SMOOTH) {
  949.                   fsr = (GLfixed) (ChanToFixed(vLower->specular[RCOMP])
  950.                                    + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF;
  951.                   fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx);
  952.                   fsg = (GLfixed) (ChanToFixed(vLower->specular[GCOMP])
  953.                                    + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF;
  954.                   fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx);
  955.                   fsb = (GLfixed) (ChanToFixed(vLower->specular[BCOMP])
  956.                                    + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF;
  957.                   fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx);
  958.                }
  959.                else {
  960.                   fsr = ChanToFixed(v2->specular[RCOMP]);
  961.                   fsg = ChanToFixed(v2->specular[GCOMP]);
  962.                   fsb = ChanToFixed(v2->specular[BCOMP]);
  963.                   fdsrOuter = fdsgOuter = fdsbOuter = 0;
  964.                }
  965. #endif
  966. #ifdef INTERP_FLOAT_SPEC
  967.                if (ctx->Light.ShadeModel == GL_SMOOTH) {
  968.                   fsr = vLower->specular[RCOMP]
  969.                      + (dsrdx * adjx + dsrdy * adjy) * (1.0F / FIXED_SCALE);
  970.                   fdsrOuter = dsrdy + dxOuter * dsrdx;
  971.                   fsg = vLower->specular[GCOMP]
  972.                      + (dsgdx * adjx + dsgdy * adjy) * (1.0F / FIXED_SCALE);
  973.                   fdsgOuter = dsgdy + dxOuter * dsgdx;
  974.                   fsb = vLower->specular[BCOMP]
  975.                      + (dsbdx * adjx + dsbdy * adjy) * (1.0F / FIXED_SCALE);
  976.                   fdsbOuter = dsbdy + dxOuter * dsbdx;
  977.                }
  978.                else {
  979.                   fsr = v2->specular[RCOMP];
  980.                   fsg = v2->specular[GCOMP];
  981.                   fsb = v2->specular[BCOMP];
  982.                   fdsrOuter = fdsgOuter = fdsbOuter = 0.0F;
  983.                }
  984. #endif
  985. #ifdef INTERP_INDEX
  986.                if (ctx->Light.ShadeModel == GL_SMOOTH) {
  987.                   fi = (GLfixed)(vLower->index * FIXED_SCALE
  988.                                  + didx * adjx + didy * adjy) + FIXED_HALF;
  989.                   fdiOuter = SignedFloatToFixed(didy + dxOuter * didx);
  990.                }
  991.                else {
  992.                   fi = (GLfixed) (v2->index * FIXED_SCALE);
  993.                   fdiOuter = 0;
  994.                }
  995. #endif
  996. #ifdef INTERP_INT_TEX
  997.                {
  998.                   GLfloat s0, t0;
  999.                   s0 = vLower->texcoord[0][0] * S_SCALE;
  1000.                   fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx
  1001.                                  + dsdy * adjy) + FIXED_HALF;
  1002.                   fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx);
  1003.  
  1004.                   t0 = vLower->texcoord[0][1] * T_SCALE;
  1005.                   ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx
  1006.                                  + dtdy * adjy) + FIXED_HALF;
  1007.                   fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
  1008.                }
  1009. #endif
  1010. #ifdef INTERP_TEX
  1011.                {
  1012.                   GLfloat invW = vLower->win[3];
  1013.                   GLfloat s0, t0, u0, v0;
  1014.                   s0 = vLower->texcoord[0][0] * invW;
  1015.                   sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)
  1016.                      * (1.0F/FIXED_SCALE);
  1017.                   dsOuter = dsdy + dxOuter * span.texStepX[0][0];
  1018.                   t0 = vLower->texcoord[0][1] * invW;
  1019.                   tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)
  1020.                      * (1.0F/FIXED_SCALE);
  1021.                   dtOuter = dtdy + dxOuter * span.texStepX[0][1];
  1022.                   u0 = vLower->texcoord[0][2] * invW;
  1023.                   uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)
  1024.                      * (1.0F/FIXED_SCALE);
  1025.                   duOuter = dudy + dxOuter * span.texStepX[0][2];
  1026.                   v0 = vLower->texcoord[0][3] * invW;
  1027.                   vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)
  1028.                      * (1.0F/FIXED_SCALE);
  1029.                   dvOuter = dvdy + dxOuter * span.texStepX[0][3];
  1030.                }
  1031. #endif
  1032. #ifdef INTERP_MULTITEX
  1033.                {
  1034.                   GLuint u;
  1035.                   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1036.                      if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1037.                         GLfloat invW = vLower->win[3];
  1038.                         GLfloat s0, t0, u0, v0;
  1039.                         s0 = vLower->texcoord[u][0] * invW;
  1040.                         sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u]
  1041.                                          * adjy) * (1.0F/FIXED_SCALE);
  1042.                         dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0];
  1043.                         t0 = vLower->texcoord[u][1] * invW;
  1044.                         tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u]
  1045.                                          * adjy) * (1.0F/FIXED_SCALE);
  1046.                         dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1];
  1047.                         u0 = vLower->texcoord[u][2] * invW;
  1048.                         uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u]
  1049.                                          * adjy) * (1.0F/FIXED_SCALE);
  1050.                         duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2];
  1051.                         v0 = vLower->texcoord[u][3] * invW;
  1052.                         vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u]
  1053.                                          * adjy) * (1.0F/FIXED_SCALE);
  1054.                         dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3];
  1055.                      }
  1056.                   }
  1057.                }
  1058. #endif
  1059.  
  1060.             } /*if setupLeft*/
  1061.  
  1062.  
  1063.             if (setupRight && eRight->lines>0) {
  1064.                fxRightEdge = eRight->fsx - FIXED_EPSILON;
  1065.                fdxRightEdge = eRight->fdxdy;
  1066.             }
  1067.  
  1068.             if (lines==0) {
  1069.                continue;
  1070.             }
  1071.  
  1072.  
  1073.             /* Rasterize setup */
  1074. #ifdef PIXEL_ADDRESS
  1075.             dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
  1076. #endif
  1077. #ifdef INTERP_Z
  1078. #  ifdef DEPTH_TYPE
  1079.             dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
  1080. #  endif
  1081.             fdzInner = fdzOuter + span.zStep;
  1082. #endif
  1083. #ifdef INTERP_FOG
  1084.             dfogInner = dfogOuter + span.fogStep;
  1085. #endif
  1086. #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
  1087.             fdrInner = fdrOuter + span.redStep;
  1088.             fdgInner = fdgOuter + span.greenStep;
  1089.             fdbInner = fdbOuter + span.blueStep;
  1090. #endif
  1091. #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
  1092.             fdaInner = fdaOuter + span.alphaStep;
  1093. #endif
  1094. #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
  1095.             fdsrInner = fdsrOuter + span.specRedStep;
  1096.             fdsgInner = fdsgOuter + span.specGreenStep;
  1097.             fdsbInner = fdsbOuter + span.specBlueStep;
  1098. #endif
  1099. #ifdef INTERP_INDEX
  1100.             fdiInner = fdiOuter + span.indexStep;
  1101. #endif
  1102. #ifdef INTERP_INT_TEX
  1103.             fdsInner = fdsOuter + span.intTexStep[0];
  1104.             fdtInner = fdtOuter + span.intTexStep[1];
  1105. #endif
  1106. #ifdef INTERP_TEX
  1107.             dsInner = dsOuter + span.texStepX[0][0];
  1108.             dtInner = dtOuter + span.texStepX[0][1];
  1109.             duInner = duOuter + span.texStepX[0][2];
  1110.             dvInner = dvOuter + span.texStepX[0][3];
  1111. #endif
  1112. #ifdef INTERP_MULTITEX
  1113.             {
  1114.                GLuint u;
  1115.                for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1116.                   if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1117.                      dsInner[u] = dsOuter[u] + span.texStepX[u][0];
  1118.                      dtInner[u] = dtOuter[u] + span.texStepX[u][1];
  1119.                      duInner[u] = duOuter[u] + span.texStepX[u][2];
  1120.                      dvInner[u] = dvOuter[u] + span.texStepX[u][3];
  1121.                   }
  1122.                }
  1123.             }
  1124. #endif
  1125.  
  1126.             while (lines > 0) {
  1127.                /* initialize the span interpolants to the leftmost value */
  1128.                /* ff = fixed-pt fragment */
  1129.                const GLint right = FixedToInt(fxRightEdge);
  1130.  
  1131.                span.x = FixedToInt(fxLeftEdge);
  1132.  
  1133.                if (right <= span.x)
  1134.                   span.end = 0;
  1135.                else
  1136.                   span.end = right - span.x;
  1137.  
  1138. #ifdef INTERP_Z
  1139.                span.z = fz;
  1140. #endif
  1141. #ifdef INTERP_FOG
  1142.                span.fog = fogLeft;
  1143. #endif
  1144. #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
  1145.                span.red = fr;
  1146.                span.green = fg;
  1147.                span.blue = fb;
  1148. #endif
  1149. #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
  1150.                span.alpha = fa;
  1151. #endif
  1152. #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
  1153.                span.specRed = fsr;
  1154.                span.specGreen = fsg;
  1155.                span.specBlue = fsb;
  1156. #endif
  1157. #ifdef INTERP_INDEX
  1158.                span.index = fi;
  1159. #endif
  1160. #ifdef INTERP_INT_TEX
  1161.                span.intTex[0] = fs;
  1162.                span.intTex[1] = ft;
  1163. #endif
  1164.  
  1165. #ifdef INTERP_TEX
  1166.                span.tex[0][0] = sLeft;
  1167.                span.tex[0][1] = tLeft;
  1168.                span.tex[0][2] = uLeft;
  1169.                span.tex[0][3] = vLeft;
  1170. #endif
  1171.  
  1172. #ifdef INTERP_MULTITEX
  1173.                {
  1174.                   GLuint u;
  1175.                   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1176.                      if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1177.                         span.tex[u][0] = sLeft[u];
  1178.                         span.tex[u][1] = tLeft[u];
  1179.                         span.tex[u][2] = uLeft[u];
  1180.                         span.tex[u][3] = vLeft[u];
  1181.                      }
  1182.                   }
  1183.                }
  1184. #endif
  1185.  
  1186. #ifdef INTERP_RGB
  1187.                {
  1188.                   /* need this to accomodate round-off errors */
  1189.                   const GLint len = right - span.x - 1;
  1190.                   GLfixed ffrend = span.red + len * span.redStep;
  1191.                   GLfixed ffgend = span.green + len * span.greenStep;
  1192.                   GLfixed ffbend = span.blue + len * span.blueStep;
  1193.                   if (ffrend < 0) {
  1194.                      span.red -= ffrend;
  1195.                      if (span.red < 0)
  1196.                         span.red = 0;
  1197.                   }
  1198.                   if (ffgend < 0) {
  1199.                      span.green -= ffgend;
  1200.                      if (span.green < 0)
  1201.                         span.green = 0;
  1202.                   }
  1203.                   if (ffbend < 0) {
  1204.                      span.blue -= ffbend;
  1205.                      if (span.blue < 0)
  1206.                         span.blue = 0;
  1207.                   }
  1208.                }
  1209. #endif
  1210. #ifdef INTERP_ALPHA
  1211.                {
  1212.                   const GLint len = right - span.x - 1;
  1213.                   GLfixed ffaend = span.alpha + len * span.alphaStep;
  1214.                   if (ffaend < 0) {
  1215.                      span.alpha -= ffaend;
  1216.                      if (span.alpha < 0)
  1217.                         span.alpha = 0;
  1218.                   }
  1219.                }
  1220. #endif
  1221. #ifdef INTERP_SPEC
  1222.                {
  1223.                   /* need this to accomodate round-off errors */
  1224.                   const GLint len = right - span.x - 1;
  1225.                   GLfixed ffsrend = span.specRed + len * span.specRedStep;
  1226.                   GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
  1227.                   GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
  1228.                   if (ffsrend < 0) {
  1229.                      span.specRed -= ffsrend;
  1230.                      if (span.specRed < 0)
  1231.                         span.specRed = 0;
  1232.                   }
  1233.                   if (ffsgend < 0) {
  1234.                      span.specGreen -= ffsgend;
  1235.                      if (span.specGreen < 0)
  1236.                         span.specGreen = 0;
  1237.                   }
  1238.                   if (ffsbend < 0) {
  1239.                      span.specBlue -= ffsbend;
  1240.                      if (span.specBlue < 0)
  1241.                         span.specBlue = 0;
  1242.                   }
  1243.                }
  1244. #endif
  1245. #ifdef INTERP_INDEX
  1246.                if (span.index < 0)  span.index = 0;
  1247. #endif
  1248.  
  1249.                /* This is where we actually generate fragments */
  1250.                if (span.end > 0) {
  1251.                   RENDER_SPAN( span );
  1252.                }
  1253.  
  1254.                /*
  1255.                 * Advance to the next scan line.  Compute the
  1256.                 * new edge coordinates, and adjust the
  1257.                 * pixel-center x coordinate so that it stays
  1258.                 * on or inside the major edge.
  1259.                 */
  1260.                (span.y)++;
  1261.                lines--;
  1262.  
  1263.                fxLeftEdge += fdxLeftEdge;
  1264.                fxRightEdge += fdxRightEdge;
  1265.  
  1266.  
  1267.                fError += fdError;
  1268.                if (fError >= 0) {
  1269.                   fError -= FIXED_ONE;
  1270. #ifdef PIXEL_ADDRESS
  1271.                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
  1272. #endif
  1273. #ifdef INTERP_Z
  1274. #  ifdef DEPTH_TYPE
  1275.                   zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
  1276. #  endif
  1277.                   fz += fdzOuter;
  1278. #endif
  1279. #ifdef INTERP_FOG
  1280.                   fogLeft += dfogOuter;
  1281. #endif
  1282. #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
  1283.                   fr += fdrOuter;
  1284.                   fg += fdgOuter;
  1285.                   fb += fdbOuter;
  1286. #endif
  1287. #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
  1288.                   fa += fdaOuter;
  1289. #endif
  1290. #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
  1291.                   fsr += fdsrOuter;
  1292.                   fsg += fdsgOuter;
  1293.                   fsb += fdsbOuter;
  1294. #endif
  1295. #ifdef INTERP_INDEX
  1296.                   fi += fdiOuter;
  1297. #endif
  1298. #ifdef INTERP_INT_TEX
  1299.                   fs += fdsOuter;
  1300.                   ft += fdtOuter;
  1301. #endif
  1302. #ifdef INTERP_TEX
  1303.                   sLeft += dsOuter;
  1304.                   tLeft += dtOuter;
  1305.                   uLeft += duOuter;
  1306.                   vLeft += dvOuter;
  1307. #endif
  1308. #ifdef INTERP_MULTITEX
  1309.                   {
  1310.                      GLuint u;
  1311.                      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1312.                         if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1313.                            sLeft[u] += dsOuter[u];
  1314.                            tLeft[u] += dtOuter[u];
  1315.                            uLeft[u] += duOuter[u];
  1316.                            vLeft[u] += dvOuter[u];
  1317.                         }
  1318.                      }
  1319.                   }
  1320. #endif
  1321.                }
  1322.                else {
  1323. #ifdef PIXEL_ADDRESS
  1324.                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
  1325. #endif
  1326. #ifdef INTERP_Z
  1327. #  ifdef DEPTH_TYPE
  1328.                   zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
  1329. #  endif
  1330.                   fz += fdzInner;
  1331. #endif
  1332. #ifdef INTERP_FOG
  1333.                   fogLeft += dfogInner;
  1334. #endif
  1335. #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
  1336.                   fr += fdrInner;
  1337.                   fg += fdgInner;
  1338.                   fb += fdbInner;
  1339. #endif
  1340. #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
  1341.                   fa += fdaInner;
  1342. #endif
  1343. #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
  1344.                   fsr += fdsrInner;
  1345.                   fsg += fdsgInner;
  1346.                   fsb += fdsbInner;
  1347. #endif
  1348. #ifdef INTERP_INDEX
  1349.                   fi += fdiInner;
  1350. #endif
  1351. #ifdef INTERP_INT_TEX
  1352.                   fs += fdsInner;
  1353.                   ft += fdtInner;
  1354. #endif
  1355. #ifdef INTERP_TEX
  1356.                   sLeft += dsInner;
  1357.                   tLeft += dtInner;
  1358.                   uLeft += duInner;
  1359.                   vLeft += dvInner;
  1360. #endif
  1361. #ifdef INTERP_MULTITEX
  1362.                   {
  1363.                      GLuint u;
  1364.                      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1365.                         if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1366.                            sLeft[u] += dsInner[u];
  1367.                            tLeft[u] += dtInner[u];
  1368.                            uLeft[u] += duInner[u];
  1369.                            vLeft[u] += dvInner[u];
  1370.                         }
  1371.                      }
  1372.                   }
  1373. #endif
  1374.                }
  1375.             } /*while lines>0*/
  1376.  
  1377.          } /* for subTriangle */
  1378.  
  1379.       }
  1380. #ifdef CLEANUP_CODE
  1381.       CLEANUP_CODE
  1382. #endif
  1383.    }
  1384. }
  1385.  
  1386. #undef SETUP_CODE
  1387. #undef CLEANUP_CODE
  1388. #undef RENDER_SPAN
  1389.  
  1390. #undef PIXEL_TYPE
  1391. #undef BYTES_PER_ROW
  1392. #undef PIXEL_ADDRESS
  1393.  
  1394. #undef INTERP_Z
  1395. #undef INTERP_FOG
  1396. #undef INTERP_RGB
  1397. #undef INTERP_ALPHA
  1398. #undef INTERP_SPEC
  1399. #undef INTERP_INDEX
  1400. #undef INTERP_INT_TEX
  1401. #undef INTERP_TEX
  1402. #undef INTERP_MULTITEX
  1403. #undef INTERP_FLOAT_RGBA
  1404. #undef INTERP_FLOAT_SPEC
  1405.  
  1406. #undef S_SCALE
  1407. #undef T_SCALE
  1408.  
  1409. #undef FixedToDepth
  1410.  
  1411. #undef DO_OCCLUSION_TEST
  1412. #undef NAME
  1413.