home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tritemp.h < prev    next >
C/C++ Source or Header  |  2000-04-01  |  38KB  |  1,062 lines

  1. /* $Id: tritemp.h,v 1.7 2000/04/01 05:42:06 brianp Exp $ */
  2. /*
  3.  * Triangle Rasterizer Template
  4.  *
  5.  * This file is #include'd to generate custom triangle rasterizers.
  6.  *
  7.  * The following macros may be defined to indicate what auxillary information
  8.  * must be interplated across the triangle:
  9.  *    INTERP_Z      - if defined, interpolate Z values
  10.  *    INTERP_RGB    - if defined, interpolate RGB values
  11.  *    INTERP_SPEC   - if defined, interpolate specular RGB values
  12.  *    INTERP_ALPHA  - if defined, interpolate Alpha values
  13.  *    INTERP_INDEX  - if defined, interpolate color index values
  14.  *    INTERP_INT_ST - if defined, interpolate integer ST texcoords
  15.  *                         (fast, simple 2-D texture mapping)
  16.  *    INTERP_STUV   - if defined, interpolate set 0 float STRQ texcoords
  17.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  18.  *    INTERP_STUV1  - if defined, interpolate set 1 float STRQ texcoords
  19.  *
  20.  * When one can directly address pixels in the color buffer the following
  21.  * macros can be defined and used to compute pixel addresses during
  22.  * rasterization (see pRow):
  23.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  24.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  25.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  26.  *                          Y==0 at bottom of screen and increases upward.
  27.  *
  28.  * Similarly, for direct depth buffer access, this type is used for depth
  29.  * buffer addressing:
  30.  *    DEPTH_TYPE          - either GLushort or GLuint
  31.  *
  32.  * Optionally, one may provide one-time setup code per triangle:
  33.  *    SETUP_CODE    - code which is to be executed once per triangle
  34.  * 
  35.  * The following macro MUST be defined:
  36.  *    INNER_LOOP(LEFT,RIGHT,Y) - code to write a span of pixels.
  37.  *        Something like:
  38.  *
  39.  *                    for (x=LEFT; x<RIGHT;x++) {
  40.  *                       put_pixel(x,Y);
  41.  *                       // increment fixed point interpolants
  42.  *                    }
  43.  *
  44.  * This code was designed for the origin to be in the lower-left corner.
  45.  *
  46.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  47.  */
  48.  
  49.  
  50. /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
  51. {
  52.    typedef struct {
  53.         GLint v0, v1;   /* Y(v0) < Y(v1) */
  54.     GLfloat dx;    /* X(v1) - X(v0) */
  55.     GLfloat dy;    /* Y(v1) - Y(v0) */
  56.     GLfixed fdxdy;    /* dx/dy in fixed-point */
  57.     GLfixed fsx;    /* first sample point x coord */
  58.     GLfixed fsy;
  59.     GLfloat adjy;    /* adjust from v[0]->fy to fsy, scaled */
  60.     GLint lines;    /* number of lines to be sampled on this edge */
  61.     GLfixed fx0;    /* fixed pt X of lower endpoint */
  62.    } EdgeT;
  63.  
  64. #ifdef INTERP_Z
  65.    const GLint depthBits = ctx->Visual->DepthBits;
  66.    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
  67.    const GLfloat maxDepth = ctx->Visual->DepthMaxF;
  68. #define FixedToDepth(F)  ((F) >> fixedToDepthShift)
  69. #endif
  70.    const struct vertex_buffer *VB = ctx->VB;
  71.    EdgeT eMaj, eTop, eBot;
  72.    GLfloat oneOverArea;
  73.    int vMin, vMid, vMax;       /* vertex indexes:  Y(vMin)<=Y(vMid)<=Y(vMax) */
  74.    float bf = ctx->backface_sign;
  75.  
  76.    /* find the order of the 3 vertices along the Y axis */
  77.    {
  78.       GLfloat y0 = VB->Win.data[v0][1];
  79.       GLfloat y1 = VB->Win.data[v1][1];
  80.       GLfloat y2 = VB->Win.data[v2][1];
  81.  
  82.       if (y0<=y1) {
  83.      if (y1<=y2) {
  84.         vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  85.      }
  86.      else if (y2<=y0) {
  87.         vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  88.      }
  89.      else {
  90.         vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  91.      }
  92.       }
  93.       else {
  94.      if (y0<=y2) {
  95.         vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  96.      }
  97.      else if (y2<=y1) {
  98.         vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  99.      }
  100.      else {
  101.         vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  102.      }
  103.       }
  104.    }
  105.  
  106.    /* vertex/edge relationship */
  107.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  108.    eTop.v0 = vMid;   eTop.v1 = vMax;
  109.    eBot.v0 = vMin;   eBot.v1 = vMid;
  110.  
  111.    /* compute deltas for each edge:  vertex[v1] - vertex[v0] */
  112.    eMaj.dx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  113.    eMaj.dy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  114.    eTop.dx = VB->Win.data[vMax][0] - VB->Win.data[vMid][0];
  115.    eTop.dy = VB->Win.data[vMax][1] - VB->Win.data[vMid][1];
  116.    eBot.dx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  117.    eBot.dy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  118.  
  119.    /* compute oneOverArea */
  120.    {
  121.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  122.  
  123.       /* Do backface culling */
  124.       if (area * bf < 0 || area * area < .0025)
  125.      return;
  126.  
  127.       oneOverArea = 1.0F / area;
  128.    }
  129.  
  130. #ifndef DO_OCCLUSION_TEST
  131.    ctx->OcclusionResult = GL_TRUE;
  132. #endif
  133.  
  134.    /* Edge setup.  For a triangle strip these could be reused... */
  135.    {
  136.       /* fixed point Y coordinates */
  137.       GLfixed vMin_fx = FloatToFixed(VB->Win.data[vMin][0] + 0.5F);
  138.       GLfixed vMin_fy = FloatToFixed(VB->Win.data[vMin][1] - 0.5F);
  139.       GLfixed vMid_fx = FloatToFixed(VB->Win.data[vMid][0] + 0.5F);
  140.       GLfixed vMid_fy = FloatToFixed(VB->Win.data[vMid][1] - 0.5F);
  141.       GLfixed vMax_fy = FloatToFixed(VB->Win.data[vMax][1] - 0.5F);
  142.  
  143.       eMaj.fsy = FixedCeil(vMin_fy);
  144.       eMaj.lines = FixedToInt(vMax_fy + FIXED_ONE - FIXED_EPSILON - eMaj.fsy);
  145.       if (eMaj.lines > 0) {
  146.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  147.          eMaj.fdxdy = SignedFloatToFixed(dxdy);
  148.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  149.          eMaj.fx0 = vMin_fx;
  150.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  151.       }
  152.       else {
  153.          return;  /*CULLED*/
  154.       }
  155.  
  156.       eTop.fsy = FixedCeil(vMid_fy);
  157.       eTop.lines = FixedToInt(vMax_fy + FIXED_ONE - FIXED_EPSILON - eTop.fsy);
  158.       if (eTop.lines > 0) {
  159.          GLfloat dxdy = eTop.dx / eTop.dy;
  160.          eTop.fdxdy = SignedFloatToFixed(dxdy);
  161.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  162.          eTop.fx0 = vMid_fx;
  163.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  164.       }
  165.  
  166.       eBot.fsy = FixedCeil(vMin_fy);
  167.       eBot.lines = FixedToInt(vMid_fy + FIXED_ONE - FIXED_EPSILON - eBot.fsy);
  168.       if (eBot.lines > 0) {
  169.          GLfloat dxdy = eBot.dx / eBot.dy;
  170.          eBot.fdxdy = SignedFloatToFixed(dxdy);
  171.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  172.          eBot.fx0 = vMin_fx;
  173.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  174.       }
  175.    }
  176.  
  177.    /*
  178.     * Conceptually, we view a triangle as two subtriangles
  179.     * separated by a perfectly horizontal line.  The edge that is
  180.     * intersected by this line is one with maximal absolute dy; we
  181.     * call it a ``major'' edge.  The other two edges are the
  182.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  183.     * edge (for the lower subtriangle).  If either of these two
  184.     * edges is horizontal or very close to horizontal, the
  185.     * corresponding subtriangle might cover zero sample points;
  186.     * we take care to handle such cases, for performance as well
  187.     * as correctness.
  188.     *
  189.     * By stepping rasterization parameters along the major edge,
  190.     * we can avoid recomputing them at the discontinuity where
  191.     * the top and bottom edges meet.  However, this forces us to
  192.     * be able to scan both left-to-right and right-to-left. 
  193.     * Also, we must determine whether the major edge is at the
  194.     * left or right side of the triangle.  We do this by
  195.     * computing the magnitude of the cross-product of the major
  196.     * and top edges.  Since this magnitude depends on the sine of
  197.     * the angle between the two edges, its sign tells us whether
  198.     * we turn to the left or to the right when travelling along
  199.     * the major edge to the top edge, and from this we infer
  200.     * whether the major edge is on the left or the right.
  201.     *
  202.     * Serendipitously, this cross-product magnitude is also a
  203.     * value we need to compute the iteration parameter
  204.     * derivatives for the triangle, and it can be used to perform
  205.     * backface culling because its sign tells us whether the
  206.     * triangle is clockwise or counterclockwise.  In this code we
  207.     * refer to it as ``area'' because it's also proportional to
  208.     * the pixel area of the triangle.
  209.     */
  210.  
  211.    {
  212.       GLint ltor;        /* true if scanning left-to-right */
  213. #ifdef INTERP_Z
  214.       GLfloat dzdx, dzdy;      GLfixed fdzdx;
  215. #endif
  216. #ifdef INTERP_RGB
  217.       GLfloat drdx, drdy;      GLfixed fdrdx;
  218.       GLfloat dgdx, dgdy;      GLfixed fdgdx;
  219.       GLfloat dbdx, dbdy;      GLfixed fdbdx;
  220. #endif
  221. #ifdef INTERP_SPEC
  222.       GLfloat dsrdx, dsrdy;    GLfixed fdsrdx;
  223.       GLfloat dsgdx, dsgdy;    GLfixed fdsgdx;
  224.       GLfloat dsbdx, dsbdy;    GLfixed fdsbdx;
  225. #endif
  226. #ifdef INTERP_ALPHA
  227.       GLfloat dadx, dady;      GLfixed fdadx;
  228. #endif
  229. #ifdef INTERP_INDEX
  230.       GLfloat didx, didy;      GLfixed fdidx;
  231. #endif
  232. #ifdef INTERP_INT_ST
  233.       GLfloat dsdx, dsdy;      GLfixed fdsdx;
  234.       GLfloat dtdx, dtdy;      GLfixed fdtdx;
  235. #endif
  236. #ifdef INTERP_STUV
  237.       GLfloat dsdx, dsdy;
  238.       GLfloat dtdx, dtdy;
  239.       GLfloat dudx, dudy;
  240.       GLfloat dvdx, dvdy;
  241. #endif
  242. #ifdef INTERP_STUV1
  243.       GLfloat ds1dx, ds1dy;
  244.       GLfloat dt1dx, dt1dy;
  245.       GLfloat du1dx, du1dy;
  246.       GLfloat dv1dx, dv1dy;
  247. #endif
  248.  
  249.       /*
  250.        * Execute user-supplied setup code
  251.        */
  252. #ifdef SETUP_CODE
  253.       SETUP_CODE
  254. #endif
  255.  
  256.       ltor = (oneOverArea < 0.0F);
  257.  
  258.       /* compute d?/dx and d?/dy derivatives */
  259. #ifdef INTERP_Z
  260.       {
  261.          GLfloat eMaj_dz, eBot_dz;
  262.          eMaj_dz = VB->Win.data[vMax][2] - VB->Win.data[vMin][2];
  263.          eBot_dz = VB->Win.data[vMid][2] - VB->Win.data[vMin][2];
  264.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  265.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  266.             /* probably a sliver triangle */
  267.             dzdx = 0.0;
  268.             dzdy = 0.0;
  269.          }
  270.          else {
  271.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  272.          }
  273.          if (depthBits <= 16)
  274.             fdzdx = SignedFloatToFixed(dzdx);
  275.          else
  276.             fdzdx = (GLint) dzdx;
  277.       }
  278. #endif
  279. #ifdef INTERP_RGB
  280.       {
  281.          GLfloat eMaj_dr, eBot_dr;
  282.          eMaj_dr = (GLint) VB->ColorPtr->data[vMax][0] - (GLint) VB->ColorPtr->data[vMin][0];
  283.          eBot_dr = (GLint) VB->ColorPtr->data[vMid][0] - (GLint) VB->ColorPtr->data[vMin][0];
  284.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  285.          fdrdx = SignedFloatToFixed(drdx);
  286.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  287.       }
  288.       {
  289.          GLfloat eMaj_dg, eBot_dg;
  290.          eMaj_dg = (GLint) VB->ColorPtr->data[vMax][1] - (GLint) VB->ColorPtr->data[vMin][1];
  291.      eBot_dg = (GLint) VB->ColorPtr->data[vMid][1] - (GLint) VB->ColorPtr->data[vMin][1];
  292.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  293.          fdgdx = SignedFloatToFixed(dgdx);
  294.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  295.       }
  296.       {
  297.          GLfloat eMaj_db, eBot_db;
  298.          eMaj_db = (GLint) VB->ColorPtr->data[vMax][2] - (GLint) VB->ColorPtr->data[vMin][2];
  299.          eBot_db = (GLint) VB->ColorPtr->data[vMid][2] - (GLint) VB->ColorPtr->data[vMin][2];
  300.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  301.          fdbdx = SignedFloatToFixed(dbdx);
  302.      dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  303.       }
  304. #endif
  305. #ifdef INTERP_SPEC
  306.       {
  307.          GLfloat eMaj_dsr, eBot_dsr;
  308.          eMaj_dsr = (GLint) VB->Specular[vMax][0] - (GLint) VB->Specular[vMin][0];
  309.          eBot_dsr = (GLint) VB->Specular[vMid][0] - (GLint) VB->Specular[vMin][0];
  310.          dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
  311.          fdsrdx = SignedFloatToFixed(dsrdx);
  312.          dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
  313.       }
  314.       {
  315.          GLfloat eMaj_dsg, eBot_dsg;
  316.          eMaj_dsg = (GLint) VB->Specular[vMax][1] - (GLint) VB->Specular[vMin][1];
  317.      eBot_dsg = (GLint) VB->Specular[vMid][1] - (GLint) VB->Specular[vMin][1];
  318.          dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
  319.          fdsgdx = SignedFloatToFixed(dsgdx);
  320.          dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
  321.       }
  322.       {
  323.          GLfloat eMaj_dsb, eBot_dsb;
  324.          eMaj_dsb = (GLint) VB->Specular[vMax][2] - (GLint) VB->Specular[vMin][2];
  325.          eBot_dsb = (GLint) VB->Specular[vMid][2] - (GLint) VB->Specular[vMin][2];
  326.          dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
  327.          fdsbdx = SignedFloatToFixed(dsbdx);
  328.      dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
  329.       }
  330. #endif
  331. #ifdef INTERP_ALPHA
  332.       {
  333.          GLfloat eMaj_da, eBot_da;
  334.          eMaj_da = (GLint) VB->ColorPtr->data[vMax][3] - (GLint) VB->ColorPtr->data[vMin][3];
  335.          eBot_da = (GLint) VB->ColorPtr->data[vMid][3] - (GLint) VB->ColorPtr->data[vMin][3];
  336.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  337.          fdadx = SignedFloatToFixed(dadx);
  338.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  339.       }
  340. #endif
  341. #ifdef INTERP_INDEX
  342.       {
  343.          GLfloat eMaj_di, eBot_di;
  344.          eMaj_di = (GLint) VB->IndexPtr->data[vMax] - (GLint) VB->IndexPtr->data[vMin];
  345.          eBot_di = (GLint) VB->IndexPtr->data[vMid] - (GLint) VB->IndexPtr->data[vMin];
  346.          didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
  347.          fdidx = SignedFloatToFixed(didx);
  348.          didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
  349.       }
  350. #endif
  351. #ifdef INTERP_INT_ST
  352.       {
  353.          GLfloat eMaj_ds, eBot_ds;
  354.          eMaj_ds = (VB->TexCoordPtr[0]->data[vMax][0] - VB->TexCoordPtr[0]->data[vMin][0]) * S_SCALE;
  355.          eBot_ds = (VB->TexCoordPtr[0]->data[vMid][0] - VB->TexCoordPtr[0]->data[vMin][0]) * S_SCALE;
  356.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  357.          fdsdx = SignedFloatToFixed(dsdx);
  358.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  359.       }
  360.       if (VB->TexCoordPtr[0]->size > 1)
  361.       {
  362.          GLfloat eMaj_dt, eBot_dt;
  363.          eMaj_dt = (VB->TexCoordPtr[0]->data[vMax][1] - VB->TexCoordPtr[0]->data[vMin][1]) * T_SCALE;
  364.          eBot_dt = (VB->TexCoordPtr[0]->data[vMid][1] - VB->TexCoordPtr[0]->data[vMin][1]) * T_SCALE;
  365.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  366.          fdtdx = SignedFloatToFixed(dtdx);
  367.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  368.       } else {
  369.          dtdx = 0;
  370.          fdtdx = SignedFloatToFixed(dtdx);
  371.          dtdy = 0;
  372.       }
  373.  
  374. #endif
  375. #ifdef INTERP_STUV
  376.       {
  377.          GLfloat wMax = VB->Win.data[vMax][3];
  378.          GLfloat wMin = VB->Win.data[vMin][3];
  379.          GLfloat wMid = VB->Win.data[vMid][3];
  380.          GLfloat eMaj_ds, eBot_ds;
  381.          GLfloat eMaj_dt, eBot_dt;
  382.          GLfloat eMaj_du, eBot_du;
  383.          GLfloat eMaj_dv, eBot_dv;
  384.  
  385.          eMaj_ds = VB->TexCoordPtr[0]->data[vMax][0]*wMax - VB->TexCoordPtr[0]->data[vMin][0]*wMin;
  386.          eBot_ds = VB->TexCoordPtr[0]->data[vMid][0]*wMid - VB->TexCoordPtr[0]->data[vMin][0]*wMin;
  387.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  388.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  389.  
  390.  
  391.      if (VB->TexCoordPtr[0]->size > 1)
  392.      {
  393.         eMaj_dt = VB->TexCoordPtr[0]->data[vMax][1]*wMax - VB->TexCoordPtr[0]->data[vMin][1]*wMin;
  394.         eBot_dt = VB->TexCoordPtr[0]->data[vMid][1]*wMid - VB->TexCoordPtr[0]->data[vMin][1]*wMin;
  395.         dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  396.         dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  397.      } else {
  398.         dtdx = 0;
  399.         dtdy = 0; 
  400.      }
  401.  
  402.      if (VB->TexCoordPtr[0]->size > 2)
  403.      {
  404.         eMaj_du = VB->TexCoordPtr[0]->data[vMax][2]*wMax - VB->TexCoordPtr[0]->data[vMin][2]*wMin;
  405.         eBot_du = VB->TexCoordPtr[0]->data[vMid][2]*wMid - VB->TexCoordPtr[0]->data[vMin][2]*wMin;
  406.         dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  407.         dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  408.      } else {
  409.         dudx = 0;
  410.         dudy = 0;
  411.      }
  412.  
  413.      if (VB->TexCoordPtr[0]->size > 3)
  414.      {
  415.         eMaj_dv = VB->TexCoordPtr[0]->data[vMax][3]*wMax - VB->TexCoordPtr[0]->data[vMin][3]*wMin;
  416.         eBot_dv = VB->TexCoordPtr[0]->data[vMid][3]*wMid - VB->TexCoordPtr[0]->data[vMin][3]*wMin;
  417.         dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  418.         dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  419.      } else {
  420.         eMaj_dv = wMax - wMin;
  421.         eBot_dv = wMid - wMin;
  422.         dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  423.         dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  424.      }
  425.       }
  426. #endif
  427. #ifdef INTERP_STUV1
  428.       {
  429.          GLfloat wMax = VB->Win.data[vMax][3];
  430.          GLfloat wMin = VB->Win.data[vMin][3];
  431.          GLfloat wMid = VB->Win.data[vMid][3];
  432.          GLfloat eMaj_ds, eBot_ds;
  433.          GLfloat eMaj_dt, eBot_dt;
  434.          GLfloat eMaj_du, eBot_du;
  435.          GLfloat eMaj_dv, eBot_dv;
  436.          eMaj_ds = VB->TexCoordPtr[1]->data[vMax][0]*wMax - VB->TexCoordPtr[1]->data[vMin][0]*wMin;
  437.          eBot_ds = VB->TexCoordPtr[1]->data[vMid][0]*wMid - VB->TexCoordPtr[1]->data[vMin][0]*wMin;
  438.          ds1dx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  439.          ds1dy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  440.  
  441.      if (VB->TexCoordPtr[1]->size > 1)
  442.      {
  443.         eMaj_dt = VB->TexCoordPtr[1]->data[vMax][1]*wMax - VB->TexCoordPtr[1]->data[vMin][1]*wMin;
  444.         eBot_dt = VB->TexCoordPtr[1]->data[vMid][1]*wMid - VB->TexCoordPtr[1]->data[vMin][1]*wMin;
  445.         dt1dx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  446.         dt1dy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  447.      }
  448.      else
  449.      {
  450.         dt1dx = 0;
  451.         dt1dy = 0;
  452.      }
  453.  
  454.      if (VB->TexCoordPtr[1]->size > 2)
  455.      {
  456.         eMaj_du = VB->TexCoordPtr[1]->data[vMax][2]*wMax - VB->TexCoordPtr[1]->data[vMin][2]*wMin;
  457.         eBot_du = VB->TexCoordPtr[1]->data[vMid][2]*wMid - VB->TexCoordPtr[1]->data[vMin][2]*wMin;
  458.         du1dx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  459.         du1dy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  460.      }
  461.      else
  462.      {
  463.         du1dx = 0;
  464.         du1dy = 0;
  465.      }
  466.  
  467.      if (VB->TexCoordPtr[1]->size > 3)
  468.      {
  469.         eMaj_dv = VB->TexCoordPtr[1]->data[vMax][3]*wMax - VB->TexCoordPtr[1]->data[vMin][3]*wMin;
  470.         eBot_dv = VB->TexCoordPtr[1]->data[vMid][3]*wMid - VB->TexCoordPtr[1]->data[vMin][3]*wMin;
  471.         dv1dx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  472.         dv1dy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  473.      }
  474.      else
  475.      {
  476.         eMaj_dv = wMax - wMin;
  477.         eBot_dv = wMid - wMin;
  478.         dv1dx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  479.         dv1dy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  480.      }
  481.       }
  482. #endif
  483.  
  484.       /*
  485.        * We always sample at pixel centers.  However, we avoid
  486.        * explicit half-pixel offsets in this code by incorporating
  487.        * the proper offset in each of x and y during the
  488.        * transformation to window coordinates.
  489.        *
  490.        * We also apply the usual rasterization rules to prevent
  491.        * cracks and overlaps.  A pixel is considered inside a
  492.        * subtriangle if it meets all of four conditions: it is on or
  493.        * to the right of the left edge, strictly to the left of the
  494.        * right edge, on or below the top edge, and strictly above
  495.        * the bottom edge.  (Some edges may be degenerate.)
  496.        *
  497.        * The following discussion assumes left-to-right scanning
  498.        * (that is, the major edge is on the left); the right-to-left
  499.        * case is a straightforward variation.
  500.        *
  501.        * We start by finding the half-integral y coordinate that is
  502.        * at or below the top of the triangle.  This gives us the
  503.        * first scan line that could possibly contain pixels that are
  504.        * inside the triangle.
  505.        *
  506.        * Next we creep down the major edge until we reach that y,
  507.        * and compute the corresponding x coordinate on the edge. 
  508.        * Then we find the half-integral x that lies on or just
  509.        * inside the edge.  This is the first pixel that might lie in
  510.        * the interior of the triangle.  (We won't know for sure
  511.        * until we check the other edges.)
  512.        *
  513.        * As we rasterize the triangle, we'll step down the major
  514.        * edge.  For each step in y, we'll move an integer number
  515.        * of steps in x.  There are two possible x step sizes, which
  516.        * we'll call the ``inner'' step (guaranteed to land on the
  517.        * edge or inside it) and the ``outer'' step (guaranteed to
  518.        * land on the edge or outside it).  The inner and outer steps
  519.        * differ by one.  During rasterization we maintain an error
  520.        * term that indicates our distance from the true edge, and
  521.        * select either the inner step or the outer step, whichever
  522.        * gets us to the first pixel that falls inside the triangle.
  523.        *
  524.        * All parameters (z, red, etc.) as well as the buffer
  525.        * addresses for color and z have inner and outer step values,
  526.        * so that we can increment them appropriately.  This method
  527.        * eliminates the need to adjust parameters by creeping a
  528.        * sub-pixel amount into the triangle at each scanline.
  529.        */
  530.  
  531.       {
  532.          int subTriangle;
  533.          GLfixed fx, fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge;
  534.          GLfixed fdxOuter;
  535.          int idxOuter;
  536.          float dxOuter;
  537.          GLfixed fError, fdError;
  538.          float adjx, adjy;
  539.          GLfixed fy;
  540.          int iy;
  541. #ifdef PIXEL_ADDRESS
  542.          PIXEL_TYPE *pRow;
  543.          int dPRowOuter, dPRowInner;  /* offset in bytes */
  544. #endif
  545. #ifdef INTERP_Z
  546. #  ifdef DEPTH_TYPE
  547.          DEPTH_TYPE *zRow;
  548.          int dZRowOuter, dZRowInner;  /* offset in bytes */
  549. #  endif
  550.          GLfixed fz, fdzOuter, fdzInner;
  551. #endif
  552. #ifdef INTERP_RGB
  553.          GLfixed fr, fdrOuter, fdrInner;
  554.          GLfixed fg, fdgOuter, fdgInner;
  555.          GLfixed fb, fdbOuter, fdbInner;
  556. #endif
  557. #ifdef INTERP_SPEC
  558.          GLfixed fsr, fdsrOuter, fdsrInner;
  559.          GLfixed fsg, fdsgOuter, fdsgInner;
  560.          GLfixed fsb, fdsbOuter, fdsbInner;
  561. #endif
  562. #ifdef INTERP_ALPHA
  563.          GLfixed fa, fdaOuter, fdaInner;
  564. #endif
  565. #ifdef INTERP_INDEX
  566.          GLfixed fi, fdiOuter, fdiInner;
  567. #endif
  568. #ifdef INTERP_INT_ST
  569.          GLfixed fs, fdsOuter, fdsInner;
  570.          GLfixed ft, fdtOuter, fdtInner;
  571. #endif
  572. #ifdef INTERP_STUV
  573.          GLfloat sLeft, dsOuter, dsInner;
  574.          GLfloat tLeft, dtOuter, dtInner;
  575.          GLfloat uLeft, duOuter, duInner;
  576.          GLfloat vLeft, dvOuter, dvInner;
  577. #endif
  578. #ifdef INTERP_STUV1
  579.          GLfloat s1Left, ds1Outer, ds1Inner;
  580.          GLfloat t1Left, dt1Outer, dt1Inner;
  581.          GLfloat u1Left, du1Outer, du1Inner;
  582.          GLfloat v1Left, dv1Outer, dv1Inner;
  583. #endif
  584.  
  585.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  586.             EdgeT *eLeft, *eRight;
  587.             int setupLeft, setupRight;
  588.             int lines;
  589.  
  590.             if (subTriangle==0) {
  591.                /* bottom half */
  592.                if (ltor) {
  593.                   eLeft = &eMaj;
  594.                   eRight = &eBot;
  595.                   lines = eRight->lines;
  596.                   setupLeft = 1;
  597.                   setupRight = 1;
  598.                }
  599.                else {
  600.                   eLeft = &eBot;
  601.                   eRight = &eMaj;
  602.                   lines = eLeft->lines;
  603.                   setupLeft = 1;
  604.                   setupRight = 1;
  605.                }
  606.             }
  607.             else {
  608.                /* top half */
  609.                if (ltor) {
  610.                   eLeft = &eMaj;
  611.                   eRight = &eTop;
  612.                   lines = eRight->lines;
  613.                   setupLeft = 0;
  614.                   setupRight = 1;
  615.                }
  616.                else {
  617.                   eLeft = &eTop;
  618.                   eRight = &eMaj;
  619.                   lines = eLeft->lines;
  620.                   setupLeft = 1;
  621.                   setupRight = 0;
  622.                }
  623.                if (lines==0) return;
  624.             }
  625.  
  626.             if (setupLeft && eLeft->lines>0) {
  627.                GLint vLower;
  628.                GLfixed fsx = eLeft->fsx;
  629.                fx = FixedCeil(fsx);
  630.                fError = fx - fsx - FIXED_ONE;
  631.                fxLeftEdge = fsx - FIXED_EPSILON;
  632.                fdxLeftEdge = eLeft->fdxdy;
  633.                fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
  634.                fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
  635.                idxOuter = FixedToInt(fdxOuter);
  636.                dxOuter = (float) idxOuter;
  637.                (void) dxOuter;
  638.  
  639.                fy = eLeft->fsy;
  640.                iy = FixedToInt(fy);
  641.  
  642.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  643.                adjy = eLeft->adjy;         /* SCALED! */
  644.                (void) adjx;  /* silence compiler warnings */
  645.                (void) adjy;  /* silence compiler warnings */
  646.  
  647.                vLower = eLeft->v0;
  648.                (void) vLower;  /* silence compiler warnings */
  649.  
  650. #ifdef PIXEL_ADDRESS
  651.                {
  652.                   pRow = PIXEL_ADDRESS( FixedToInt(fxLeftEdge), iy );
  653.                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
  654.                   /* negative because Y=0 at bottom and increases upward */
  655.                }
  656. #endif
  657.                /*
  658.                 * Now we need the set of parameter (z, color, etc.) values at
  659.                 * the point (fx, fy).  This gives us properly-sampled parameter
  660.                 * values that we can step from pixel to pixel.  Furthermore,
  661.                 * although we might have intermediate results that overflow
  662.                 * the normal parameter range when we step temporarily outside
  663.                 * the triangle, we shouldn't overflow or underflow for any
  664.                 * pixel that's actually inside the triangle.
  665.                 */
  666.  
  667. #ifdef INTERP_Z
  668.                {
  669.                   GLfloat z0 = VB->Win.data[vLower][2] + ctx->PolygonZoffset;
  670.                   if (depthBits <= 16) {
  671.                      /* interpolate fixed-pt values */
  672.                      GLfloat tmp = (z0 * FIXED_SCALE + dzdx * adjx + dzdy * adjy) + FIXED_HALF;
  673.                      if (tmp < MAX_GLUINT / 2)
  674.                         fz = (GLfixed) tmp;
  675.                      else
  676.                         fz = MAX_GLUINT / 2;
  677.                      fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
  678.                   }
  679.                   else {
  680.                      /* interpolate depth values exactly */
  681.                      fz = (GLint) (z0 + dzdx*FixedToFloat(adjx) + dzdy*FixedToFloat(adjy));
  682.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  683.                   }
  684. #  ifdef DEPTH_TYPE
  685.                   zRow = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), iy);
  686.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
  687. #  endif
  688.                }
  689. #endif
  690. #ifdef INTERP_RGB
  691.                fr = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][0]) + drdx * adjx + drdy * adjy)
  692.                     + FIXED_HALF;
  693.                fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
  694.  
  695.                fg = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][1]) + dgdx * adjx + dgdy * adjy)
  696.                     + FIXED_HALF;
  697.                fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
  698.  
  699.                fb = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][2]) + dbdx * adjx + dbdy * adjy)
  700.                     + FIXED_HALF;
  701.                fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
  702. #endif
  703. #ifdef INTERP_SPEC
  704.                fsr = (GLfixed)(IntToFixed(VB->Specular[vLower][0]) + dsrdx * adjx + dsrdy * adjy)
  705.                     + FIXED_HALF;
  706.                fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx);
  707.  
  708.                fsg = (GLfixed)(IntToFixed(VB->Specular[vLower][1]) + dsgdx * adjx + dsgdy * adjy)
  709.                     + FIXED_HALF;
  710.                fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx);
  711.  
  712.                fsb = (GLfixed)(IntToFixed(VB->Specular[vLower][2]) + dsbdx * adjx + dsbdy * adjy)
  713.                     + FIXED_HALF;
  714.                fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx);
  715. #endif
  716. #ifdef INTERP_ALPHA
  717.                fa = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][3]) + dadx * adjx + dady * adjy)
  718.                     + FIXED_HALF;
  719.                fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
  720. #endif
  721. #ifdef INTERP_INDEX
  722.                fi = (GLfixed)(VB->IndexPtr->data[vLower] * FIXED_SCALE + didx * adjx
  723.                               + didy * adjy) + FIXED_HALF;
  724.                fdiOuter = SignedFloatToFixed(didy + dxOuter * didx);
  725. #endif
  726. #ifdef INTERP_INT_ST
  727.                {
  728.                   GLfloat s0, t0;
  729.                   s0 = VB->TexCoordPtr[0]->data[vLower][0] * S_SCALE;
  730.                   fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + dsdy * adjy) + FIXED_HALF;
  731.                   fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx);
  732.  
  733.           if (VB->TexCoordPtr[0]->size > 1)
  734.           {
  735.              t0 = VB->TexCoordPtr[0]->data[vLower][1] * T_SCALE;
  736.              ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF;
  737.              fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
  738.           } 
  739.           else
  740.           {
  741.              t0 = 0;
  742.              ft = (GLfixed) FIXED_HALF;
  743.              fdtOuter = SignedFloatToFixed(0);
  744.           }
  745.            }
  746. #endif
  747. #ifdef INTERP_STUV
  748.                {
  749.                   GLfloat invW = VB->Win.data[vLower][3];
  750.                   GLfloat s0, t0, u0, v0;
  751.                   s0 = VB->TexCoordPtr[0]->data[vLower][0] * invW;
  752.                   sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE);
  753.                   dsOuter = dsdy + dxOuter * dsdx;
  754.           if (VB->TexCoordPtr[0]->size > 1)
  755.           {          
  756.              t0 = VB->TexCoordPtr[0]->data[vLower][1] * invW;
  757.              tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE);
  758.              dtOuter = dtdy + dxOuter * dtdx;
  759.           } else {
  760.              tLeft = dtOuter = 0;
  761.           }
  762.           if (VB->TexCoordPtr[0]->size > 2)
  763.           {          
  764.              u0 = VB->TexCoordPtr[0]->data[vLower][2] * invW;
  765.              uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE);
  766.              duOuter = dudy + dxOuter * dudx;
  767.           } else {
  768.              uLeft = duOuter = 0;
  769.           }
  770.           if (VB->TexCoordPtr[0]->size > 3)
  771.           {          
  772.              v0 = VB->TexCoordPtr[0]->data[vLower][3] * invW;
  773.           } else {
  774.              v0 = invW;
  775.           }
  776.           vLeft = v0 + (dvdx * adjx + dvdy * adjy) * (1.0F/FIXED_SCALE);
  777.           dvOuter = dvdy + dxOuter * dvdx;
  778.                }
  779. #endif
  780. #ifdef INTERP_STUV1
  781.                {
  782.                   GLfloat invW = VB->Win.data[vLower][3];
  783.                   GLfloat s0, t0, u0, v0;
  784.                   s0 = VB->TexCoordPtr[1]->data[vLower][0] * invW;
  785.                   s1Left = s0 + (ds1dx * adjx + ds1dy * adjy) * (1.0F/FIXED_SCALE);
  786.                   ds1Outer = ds1dy + dxOuter * ds1dx;
  787.           if (VB->TexCoordPtr[0]->size > 1)
  788.           {          
  789.              t0 = VB->TexCoordPtr[1]->data[vLower][1] * invW;
  790.              t1Left = t0 + (dt1dx * adjx + dt1dy * adjy) * (1.0F/FIXED_SCALE);
  791.              dt1Outer = dt1dy + dxOuter * dt1dx;
  792.           } else {
  793.              t1Left = dt1Outer = 0;
  794.           }
  795.           if (VB->TexCoordPtr[0]->size > 2)
  796.           {          
  797.              u0 = VB->TexCoordPtr[1]->data[vLower][2] * invW;
  798.              u1Left = u0 + (du1dx * adjx + du1dy * adjy) * (1.0F/FIXED_SCALE);
  799.              du1Outer = du1dy + dxOuter * du1dx;
  800.           } else {
  801.              u1Left = du1Outer = 0;
  802.           }
  803.           if (VB->TexCoordPtr[0]->size > 3)
  804.           {          
  805.              v0 = VB->TexCoordPtr[1]->data[vLower][3] * invW;
  806.           } else {
  807.              v0 =  invW;
  808.           }
  809.           v1Left = v0 + (dv1dx * adjx + dv1dy * adjy) * (1.0F/FIXED_SCALE);
  810.           dv1Outer = dv1dy + dxOuter * dv1dx;
  811.                }
  812. #endif
  813.  
  814.             } /*if setupLeft*/
  815.  
  816.  
  817.             if (setupRight && eRight->lines>0) {
  818.                fxRightEdge = eRight->fsx - FIXED_EPSILON;
  819.                fdxRightEdge = eRight->fdxdy;
  820.             }
  821.  
  822.             if (lines==0) {
  823.                continue;
  824.             }
  825.  
  826.  
  827.             /* Rasterize setup */
  828. #ifdef PIXEL_ADDRESS
  829.             dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
  830. #endif
  831. #ifdef INTERP_Z
  832. #  ifdef DEPTH_TYPE
  833.             dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
  834. #  endif
  835.             fdzInner = fdzOuter + fdzdx;
  836. #endif
  837. #ifdef INTERP_RGB
  838.             fdrInner = fdrOuter + fdrdx;
  839.             fdgInner = fdgOuter + fdgdx;
  840.             fdbInner = fdbOuter + fdbdx;
  841. #endif
  842. #ifdef INTERP_SPEC
  843.             fdsrInner = fdsrOuter + fdsrdx;
  844.             fdsgInner = fdsgOuter + fdsgdx;
  845.             fdsbInner = fdsbOuter + fdsbdx;
  846. #endif
  847. #ifdef INTERP_ALPHA
  848.             fdaInner = fdaOuter + fdadx;
  849. #endif
  850. #ifdef INTERP_INDEX
  851.             fdiInner = fdiOuter + fdidx;
  852. #endif
  853. #ifdef INTERP_INT_ST
  854.             fdsInner = fdsOuter + fdsdx;
  855.             fdtInner = fdtOuter + fdtdx;
  856. #endif
  857. #ifdef INTERP_STUV
  858.         dsInner = dsOuter + dsdx;
  859.         dtInner = dtOuter + dtdx;
  860.         duInner = duOuter + dudx;
  861.         dvInner = dvOuter + dvdx;
  862. #endif
  863. #ifdef INTERP_STUV1
  864.         ds1Inner = ds1Outer + ds1dx;
  865.         dt1Inner = dt1Outer + dt1dx;
  866.         du1Inner = du1Outer + du1dx;
  867.         dv1Inner = dv1Outer + dv1dx;
  868. #endif
  869.  
  870.             while (lines>0) {
  871.                /* initialize the span interpolants to the leftmost value */
  872.                /* ff = fixed-pt fragment */
  873. #ifdef INTERP_Z
  874.                GLfixed ffz = fz;
  875. #endif
  876. #ifdef INTERP_RGB
  877.                GLfixed ffr = fr,  ffg = fg,  ffb = fb;
  878. #endif
  879. #ifdef INTERP_SPEC
  880.                GLfixed ffsr = fsr,  ffsg = fsg,  ffsb = fsb;
  881. #endif
  882. #ifdef INTERP_ALPHA
  883.                GLfixed ffa = fa;
  884. #endif
  885. #ifdef INTERP_INDEX
  886.                GLfixed ffi = fi;
  887. #endif
  888. #ifdef INTERP_INT_ST
  889.                GLfixed ffs = fs,  fft = ft;
  890. #endif
  891. #ifdef INTERP_STUV
  892.                GLfloat ss = sLeft, tt = tLeft, uu = uLeft, vv = vLeft;
  893. #endif
  894. #ifdef INTERP_STUV1
  895.                GLfloat ss1 = s1Left, tt1 = t1Left, uu1 = u1Left, vv1 = v1Left;
  896. #endif
  897.                GLint left = FixedToInt(fxLeftEdge);
  898.                GLint right = FixedToInt(fxRightEdge);
  899.  
  900. #ifdef INTERP_RGB
  901.                {
  902.                   /* need this to accomodate round-off errors */
  903.                   GLfixed ffrend = ffr+(right-left-1)*fdrdx;
  904.                   GLfixed ffgend = ffg+(right-left-1)*fdgdx;
  905.                   GLfixed ffbend = ffb+(right-left-1)*fdbdx;
  906.                   if (ffrend<0) ffr -= ffrend;
  907.                   if (ffgend<0) ffg -= ffgend;
  908.                   if (ffbend<0) ffb -= ffbend;
  909.                   if (ffr<0) ffr = 0;
  910.                   if (ffg<0) ffg = 0;
  911.                   if (ffb<0) ffb = 0;
  912.                }
  913. #endif
  914. #ifdef INTERP_SPEC
  915.                {
  916.                   /* need this to accomodate round-off errors */
  917.                   GLfixed ffsrend = ffsr+(right-left-1)*fdsrdx;
  918.                   GLfixed ffsgend = ffsg+(right-left-1)*fdsgdx;
  919.                   GLfixed ffsbend = ffsb+(right-left-1)*fdsbdx;
  920.                   if (ffsrend<0) ffsr -= ffsrend;
  921.                   if (ffsgend<0) ffsg -= ffsgend;
  922.                   if (ffsbend<0) ffsb -= ffsbend;
  923.                   if (ffsr<0) ffsr = 0;
  924.                   if (ffsg<0) ffsg = 0;
  925.                   if (ffsb<0) ffsb = 0;
  926.                }
  927. #endif
  928. #ifdef INTERP_ALPHA
  929.                {
  930.                   GLfixed ffaend = ffa+(right-left-1)*fdadx;
  931.                   if (ffaend<0) ffa -= ffaend;
  932.                   if (ffa<0) ffa = 0;
  933.                }
  934. #endif
  935. #ifdef INTERP_INDEX
  936.                if (ffi<0) ffi = 0;
  937. #endif
  938.  
  939.                INNER_LOOP( left, right, iy );
  940.  
  941.                /*
  942.                 * Advance to the next scan line.  Compute the
  943.                 * new edge coordinates, and adjust the
  944.                 * pixel-center x coordinate so that it stays
  945.                 * on or inside the major edge.
  946.                 */
  947.                iy++;
  948.                lines--;
  949.  
  950.                fxLeftEdge += fdxLeftEdge;
  951.                fxRightEdge += fdxRightEdge;
  952.  
  953.  
  954.                fError += fdError;
  955.                if (fError >= 0) {
  956.                   fError -= FIXED_ONE;
  957. #ifdef PIXEL_ADDRESS
  958.                   pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowOuter);
  959. #endif
  960. #ifdef INTERP_Z
  961. #  ifdef DEPTH_TYPE
  962.                   zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter);
  963. #  endif
  964.                   fz += fdzOuter;
  965. #endif
  966. #ifdef INTERP_RGB
  967.                   fr += fdrOuter;   fg += fdgOuter;   fb += fdbOuter;
  968. #endif
  969. #ifdef INTERP_SPEC
  970.                   fsr += fdsrOuter;   fsg += fdsgOuter;   fsb += fdsbOuter;
  971. #endif
  972. #ifdef INTERP_ALPHA
  973.                   fa += fdaOuter;
  974. #endif
  975. #ifdef INTERP_INDEX
  976.                   fi += fdiOuter;
  977. #endif
  978. #ifdef INTERP_INT_ST
  979.                   fs += fdsOuter;   ft += fdtOuter;
  980. #endif
  981. #ifdef INTERP_STUV
  982.           sLeft += dsOuter;
  983.           tLeft += dtOuter;
  984.           uLeft += duOuter;
  985.           vLeft += dvOuter;
  986. #endif
  987. #ifdef INTERP_STUV1
  988.           s1Left += ds1Outer;
  989.           t1Left += dt1Outer;
  990.           u1Left += du1Outer;
  991.           v1Left += dv1Outer;
  992. #endif
  993.                }
  994.                else {
  995. #ifdef PIXEL_ADDRESS
  996.                   pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowInner);
  997. #endif
  998. #ifdef INTERP_Z
  999. #  ifdef DEPTH_TYPE
  1000.                   zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowInner);
  1001. #  endif
  1002.                   fz += fdzInner;
  1003. #endif
  1004. #ifdef INTERP_RGB
  1005.                   fr += fdrInner;   fg += fdgInner;   fb += fdbInner;
  1006. #endif
  1007. #ifdef INTERP_SPEC
  1008.                   fsr += fdsrInner;   fsg += fdsgInner;   fsb += fdsbInner;
  1009. #endif
  1010. #ifdef INTERP_ALPHA
  1011.                   fa += fdaInner;
  1012. #endif
  1013. #ifdef INTERP_INDEX
  1014.                   fi += fdiInner;
  1015. #endif
  1016. #ifdef INTERP_INT_ST
  1017.                   fs += fdsInner;   ft += fdtInner;
  1018. #endif
  1019. #ifdef INTERP_STUV
  1020.           sLeft += dsInner;
  1021.           tLeft += dtInner;
  1022.           uLeft += duInner;
  1023.           vLeft += dvInner;
  1024. #endif
  1025. #ifdef INTERP_STUV1
  1026.           s1Left += ds1Inner;
  1027.           t1Left += dt1Inner;
  1028.           u1Left += du1Inner;
  1029.           v1Left += dv1Inner;
  1030. #endif
  1031.                }
  1032.             } /*while lines>0*/
  1033.  
  1034.          } /* for subTriangle */
  1035.  
  1036.       }
  1037.    }
  1038. }
  1039.  
  1040. #undef SETUP_CODE
  1041. #undef INNER_LOOP
  1042.  
  1043. #undef PIXEL_TYPE
  1044. #undef BYTES_PER_ROW
  1045. #undef PIXEL_ADDRESS
  1046.  
  1047. #undef INTERP_Z
  1048. #undef INTERP_RGB
  1049. #undef INTERP_SPEC
  1050. #undef INTERP_ALPHA
  1051. #undef INTERP_INDEX
  1052. #undef INTERP_INT_ST
  1053. #undef INTERP_STUV
  1054. #undef INTERP_STUV1
  1055.  
  1056. #undef S_SCALE
  1057. #undef T_SCALE
  1058.  
  1059. #undef FixedToDepth
  1060.  
  1061. #undef DO_OCCLUSION_TEST
  1062.