home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / tritemp.h < prev    next >
Text File  |  2000-01-07  |  38KB  |  1,067 lines

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