ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

s_tritemp.h
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.0
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 /*
00026  * Triangle Rasterizer Template
00027  *
00028  * This file is #include'd to generate custom triangle rasterizers.
00029  *
00030  * The following macros may be defined to indicate what auxillary information
00031  * must be interpolated across the triangle:
00032  *    INTERP_Z        - if defined, interpolate integer Z values
00033  *    INTERP_RGB      - if defined, interpolate integer RGB values
00034  *    INTERP_ALPHA    - if defined, interpolate integer Alpha values
00035  *    INTERP_INDEX    - if defined, interpolate color index values
00036  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
00037  *                         (fast, simple 2-D texture mapping, without
00038  *                         perspective correction)
00039  *    INTERP_ATTRIBS  - if defined, interpolate arbitrary attribs (texcoords,
00040  *                         varying vars, etc)  This also causes W to be
00041  *                         computed for perspective correction).
00042  *
00043  * When one can directly address pixels in the color buffer the following
00044  * macros can be defined and used to compute pixel addresses during
00045  * rasterization (see pRow):
00046  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
00047  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
00048  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
00049  *                          Y==0 at bottom of screen and increases upward.
00050  *
00051  * Similarly, for direct depth buffer access, this type is used for depth
00052  * buffer addressing (see zRow):
00053  *    DEPTH_TYPE          - either GLushort or GLuint
00054  *
00055  * Optionally, one may provide one-time setup code per triangle:
00056  *    SETUP_CODE    - code which is to be executed once per triangle
00057  *
00058  * The following macro MUST be defined:
00059  *    RENDER_SPAN(span) - code to write a span of pixels.
00060  *
00061  * This code was designed for the origin to be in the lower-left corner.
00062  *
00063  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
00064  *
00065  *
00066  * Some notes on rasterization accuracy:
00067  *
00068  * This code uses fixed point arithmetic (the GLfixed type) to iterate
00069  * over the triangle edges and interpolate ancillary data (such as Z,
00070  * color, secondary color, etc).  The number of fractional bits in
00071  * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the
00072  * accuracy of rasterization.
00073  *
00074  * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest
00075  * 1/16 of a pixel.  If we're walking up a long, nearly vertical edge
00076  * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in
00077  * GLfixed to walk the edge without error.  If the maximum viewport
00078  * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits.
00079  *
00080  * Historically, Mesa has used 11 fractional bits in GLfixed, snaps
00081  * vertices to 1/16 pixel and allowed a maximum viewport height of 2K
00082  * pixels.  11 fractional bits is actually insufficient for accurately
00083  * rasterizing some triangles.  More recently, the maximum viewport
00084  * height was increased to 4K pixels.  Thus, Mesa should be using 16
00085  * fractional bits in GLfixed.  Unfortunately, there may be some issues
00086  * with setting FIXED_FRAC_BITS=16, such as multiplication overflow.
00087  * This will have to be examined in some detail...
00088  *
00089  * For now, if you find rasterization errors, particularly with tall,
00090  * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing
00091  * SUB_PIXEL_BITS.
00092  */
00093 
00094 
00095 /*
00096  * Some code we unfortunately need to prevent negative interpolated colors.
00097  */
00098 #ifndef CLAMP_INTERPOLANT
00099 #define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN)        \
00100 do {                                \
00101    GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP;    \
00102    if (endVal < 0) {                        \
00103       span.CHANNEL -= endVal;                   \
00104    }                                \
00105    if (span.CHANNEL < 0) {                  \
00106       span.CHANNEL = 0;                     \
00107    }                                \
00108 } while (0)
00109 #endif
00110 
00111 
00112 static void NAME(GLcontext *ctx, const SWvertex *v0,
00113                                  const SWvertex *v1,
00114                                  const SWvertex *v2 )
00115 {
00116    typedef struct {
00117       const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
00118       GLfloat dx;   /* X(v1) - X(v0) */
00119       GLfloat dy;   /* Y(v1) - Y(v0) */
00120       GLfloat dxdy; /* dx/dy */
00121       GLfixed fdxdy;    /* dx/dy in fixed-point */
00122       GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */
00123       GLfixed fsx;  /* first sample point x coord */
00124       GLfixed fsy;
00125       GLfixed fx0;  /* fixed pt X of lower endpoint */
00126       GLint lines;  /* number of lines to be sampled on this edge */
00127    } EdgeT;
00128 
00129    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
00130 #ifdef INTERP_Z
00131    const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
00132    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
00133    const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF;
00134 #define FixedToDepth(F)  ((F) >> fixedToDepthShift)
00135 #endif
00136    EdgeT eMaj, eTop, eBot;
00137    GLfloat oneOverArea;
00138    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
00139    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
00140    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
00141    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
00142 
00143    SWspan span;
00144 
00145    (void) swrast;
00146 
00147    INIT_SPAN(span, GL_POLYGON);
00148    span.y = 0; /* silence warnings */
00149 
00150 #ifdef INTERP_Z
00151    (void) fixedToDepthShift;
00152 #endif
00153 
00154    /*
00155    printf("%s()\n", __FUNCTION__);
00156    printf("  %g, %g, %g\n",
00157           v0->attrib[FRAG_ATTRIB_WPOS][0],
00158           v0->attrib[FRAG_ATTRIB_WPOS][1],
00159           v0->attrib[FRAG_ATTRIB_WPOS][2]);
00160    printf("  %g, %g, %g\n",
00161           v1->attrib[FRAG_ATTRIB_WPOS][0],
00162           v1->attrib[FRAG_ATTRIB_WPOS][1],
00163           v1->attrib[FRAG_ATTRIB_WPOS][2]);
00164    printf("  %g, %g, %g\n",
00165           v2->attrib[FRAG_ATTRIB_WPOS][0],
00166           v2->attrib[FRAG_ATTRIB_WPOS][1],
00167           v2->attrib[FRAG_ATTRIB_WPOS][2]);
00168    */
00169 
00170    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
00171     * And find the order of the 3 vertices along the Y axis.
00172     */
00173    {
00174       const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
00175       const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
00176       const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
00177       if (fy0 <= fy1) {
00178          if (fy1 <= fy2) {
00179             /* y0 <= y1 <= y2 */
00180             vMin = v0;   vMid = v1;   vMax = v2;
00181             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
00182          }
00183          else if (fy2 <= fy0) {
00184             /* y2 <= y0 <= y1 */
00185             vMin = v2;   vMid = v0;   vMax = v1;
00186             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
00187          }
00188          else {
00189             /* y0 <= y2 <= y1 */
00190             vMin = v0;   vMid = v2;   vMax = v1;
00191             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
00192             bf = -bf;
00193          }
00194       }
00195       else {
00196          if (fy0 <= fy2) {
00197             /* y1 <= y0 <= y2 */
00198             vMin = v1;   vMid = v0;   vMax = v2;
00199             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
00200             bf = -bf;
00201          }
00202          else if (fy2 <= fy1) {
00203             /* y2 <= y1 <= y0 */
00204             vMin = v2;   vMid = v1;   vMax = v0;
00205             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
00206             bf = -bf;
00207          }
00208          else {
00209             /* y1 <= y2 <= y0 */
00210             vMin = v1;   vMid = v2;   vMax = v0;
00211             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
00212          }
00213       }
00214 
00215       /* fixed point X coords */
00216       vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
00217       vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
00218       vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
00219    }
00220 
00221    /* vertex/edge relationship */
00222    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
00223    eTop.v0 = vMid;   eTop.v1 = vMax;
00224    eBot.v0 = vMin;   eBot.v1 = vMid;
00225 
00226    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
00227    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
00228    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
00229    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
00230    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
00231    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
00232    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
00233 
00234    /* compute area, oneOverArea and perform backface culling */
00235    {
00236       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
00237 
00238       if (IS_INF_OR_NAN(area) || area == 0.0F)
00239          return;
00240 
00241       if (area * bf * swrast->_BackfaceCullSign < 0.0)
00242          return;
00243 
00244       oneOverArea = 1.0F / area;
00245 
00246       /* 0 = front, 1 = back */
00247       span.facing = oneOverArea * bf > 0.0F;
00248    }
00249 
00250    /* Edge setup.  For a triangle strip these could be reused... */
00251    {
00252       eMaj.fsy = FixedCeil(vMin_fy);
00253       eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
00254       if (eMaj.lines > 0) {
00255          eMaj.dxdy = eMaj.dx / eMaj.dy;
00256          eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
00257          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
00258          eMaj.fx0 = vMin_fx;
00259          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
00260       }
00261       else {
00262          return;  /*CULLED*/
00263       }
00264 
00265       eTop.fsy = FixedCeil(vMid_fy);
00266       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
00267       if (eTop.lines > 0) {
00268          eTop.dxdy = eTop.dx / eTop.dy;
00269          eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
00270          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
00271          eTop.fx0 = vMid_fx;
00272          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
00273       }
00274 
00275       eBot.fsy = FixedCeil(vMin_fy);
00276       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
00277       if (eBot.lines > 0) {
00278          eBot.dxdy = eBot.dx / eBot.dy;
00279          eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
00280          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
00281          eBot.fx0 = vMin_fx;
00282          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
00283       }
00284    }
00285 
00286    /*
00287     * Conceptually, we view a triangle as two subtriangles
00288     * separated by a perfectly horizontal line.  The edge that is
00289     * intersected by this line is one with maximal absolute dy; we
00290     * call it a ``major'' edge.  The other two edges are the
00291     * ``top'' edge (for the upper subtriangle) and the ``bottom''
00292     * edge (for the lower subtriangle).  If either of these two
00293     * edges is horizontal or very close to horizontal, the
00294     * corresponding subtriangle might cover zero sample points;
00295     * we take care to handle such cases, for performance as well
00296     * as correctness.
00297     *
00298     * By stepping rasterization parameters along the major edge,
00299     * we can avoid recomputing them at the discontinuity where
00300     * the top and bottom edges meet.  However, this forces us to
00301     * be able to scan both left-to-right and right-to-left.
00302     * Also, we must determine whether the major edge is at the
00303     * left or right side of the triangle.  We do this by
00304     * computing the magnitude of the cross-product of the major
00305     * and top edges.  Since this magnitude depends on the sine of
00306     * the angle between the two edges, its sign tells us whether
00307     * we turn to the left or to the right when travelling along
00308     * the major edge to the top edge, and from this we infer
00309     * whether the major edge is on the left or the right.
00310     *
00311     * Serendipitously, this cross-product magnitude is also a
00312     * value we need to compute the iteration parameter
00313     * derivatives for the triangle, and it can be used to perform
00314     * backface culling because its sign tells us whether the
00315     * triangle is clockwise or counterclockwise.  In this code we
00316     * refer to it as ``area'' because it's also proportional to
00317     * the pixel area of the triangle.
00318     */
00319 
00320    {
00321       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
00322 #ifdef INTERP_INDEX
00323       GLfloat didx, didy;
00324 #endif
00325 
00326       /*
00327        * Execute user-supplied setup code
00328        */
00329 #ifdef SETUP_CODE
00330       SETUP_CODE
00331 #endif
00332 
00333       scan_from_left_to_right = (oneOverArea < 0.0F);
00334 
00335 
00336       /* compute d?/dx and d?/dy derivatives */
00337 #ifdef INTERP_Z
00338       span.interpMask |= SPAN_Z;
00339       {
00340          GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
00341          GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
00342          span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
00343          if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth ||
00344              span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
00345             /* probably a sliver triangle */
00346             span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
00347             span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
00348          }
00349          else {
00350             span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
00351          }
00352          if (depthBits <= 16)
00353             span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]);
00354          else
00355             span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
00356       }
00357 #endif
00358 #ifdef INTERP_RGB
00359       span.interpMask |= SPAN_RGBA;
00360       if (ctx->Light.ShadeModel == GL_SMOOTH) {
00361          GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
00362          GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
00363          GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
00364          GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
00365          GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
00366          GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
00367 #  ifdef INTERP_ALPHA
00368          GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
00369          GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
00370 #  endif
00371          span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
00372          span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
00373          span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
00374          span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
00375          span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
00376          span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
00377          span.redStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
00378          span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
00379          span.blueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
00380 #  ifdef INTERP_ALPHA
00381          span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
00382          span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
00383          span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
00384 #  endif /* INTERP_ALPHA */
00385       }
00386       else {
00387          ASSERT(ctx->Light.ShadeModel == GL_FLAT);
00388          span.interpMask |= SPAN_FLAT;
00389          span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
00390          span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
00391          span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
00392      span.redStep   = 0;
00393      span.greenStep = 0;
00394      span.blueStep  = 0;
00395 #  ifdef INTERP_ALPHA
00396          span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F;
00397      span.alphaStep = 0;
00398 #  endif
00399       }
00400 #endif /* INTERP_RGB */
00401 #ifdef INTERP_INDEX
00402       span.interpMask |= SPAN_INDEX;
00403       if (ctx->Light.ShadeModel == GL_SMOOTH) {
00404          GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
00405          GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
00406          didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
00407          didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
00408          span.indexStep = SignedFloatToFixed(didx);
00409       }
00410       else {
00411          span.interpMask |= SPAN_FLAT;
00412          didx = didy = 0.0F;
00413          span.indexStep = 0;
00414       }
00415 #endif
00416 #ifdef INTERP_INT_TEX
00417       {
00418          GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
00419          GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
00420          GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
00421          GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
00422          span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
00423          span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
00424          span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
00425          span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
00426          span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]);
00427          span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]);
00428       }
00429 #endif
00430 #ifdef INTERP_ATTRIBS
00431       {
00432          /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */
00433          const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3];
00434          const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3];
00435          const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3];
00436          {
00437             const GLfloat eMaj_dw = wMax - wMin;
00438             const GLfloat eBot_dw = wMid - wMin;
00439             span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
00440             span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
00441          }
00442          ATTRIB_LOOP_BEGIN
00443             if (swrast->_InterpMode[attr] == GL_FLAT) {
00444                ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
00445                ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
00446             }
00447             else {
00448                GLuint c;
00449                for (c = 0; c < 4; c++) {
00450                   GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
00451                   GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
00452                   span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
00453                   span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
00454                }
00455             }
00456          ATTRIB_LOOP_END
00457       }
00458 #endif
00459 
00460       /*
00461        * We always sample at pixel centers.  However, we avoid
00462        * explicit half-pixel offsets in this code by incorporating
00463        * the proper offset in each of x and y during the
00464        * transformation to window coordinates.
00465        *
00466        * We also apply the usual rasterization rules to prevent
00467        * cracks and overlaps.  A pixel is considered inside a
00468        * subtriangle if it meets all of four conditions: it is on or
00469        * to the right of the left edge, strictly to the left of the
00470        * right edge, on or below the top edge, and strictly above
00471        * the bottom edge.  (Some edges may be degenerate.)
00472        *
00473        * The following discussion assumes left-to-right scanning
00474        * (that is, the major edge is on the left); the right-to-left
00475        * case is a straightforward variation.
00476        *
00477        * We start by finding the half-integral y coordinate that is
00478        * at or below the top of the triangle.  This gives us the
00479        * first scan line that could possibly contain pixels that are
00480        * inside the triangle.
00481        *
00482        * Next we creep down the major edge until we reach that y,
00483        * and compute the corresponding x coordinate on the edge.
00484        * Then we find the half-integral x that lies on or just
00485        * inside the edge.  This is the first pixel that might lie in
00486        * the interior of the triangle.  (We won't know for sure
00487        * until we check the other edges.)
00488        *
00489        * As we rasterize the triangle, we'll step down the major
00490        * edge.  For each step in y, we'll move an integer number
00491        * of steps in x.  There are two possible x step sizes, which
00492        * we'll call the ``inner'' step (guaranteed to land on the
00493        * edge or inside it) and the ``outer'' step (guaranteed to
00494        * land on the edge or outside it).  The inner and outer steps
00495        * differ by one.  During rasterization we maintain an error
00496        * term that indicates our distance from the true edge, and
00497        * select either the inner step or the outer step, whichever
00498        * gets us to the first pixel that falls inside the triangle.
00499        *
00500        * All parameters (z, red, etc.) as well as the buffer
00501        * addresses for color and z have inner and outer step values,
00502        * so that we can increment them appropriately.  This method
00503        * eliminates the need to adjust parameters by creeping a
00504        * sub-pixel amount into the triangle at each scanline.
00505        */
00506 
00507       {
00508          GLint subTriangle;
00509          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
00510          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
00511          GLfixed fError = 0, fdError = 0;
00512 #ifdef PIXEL_ADDRESS
00513          PIXEL_TYPE *pRow = NULL;
00514          GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
00515 #endif
00516 #ifdef INTERP_Z
00517 #  ifdef DEPTH_TYPE
00518          struct gl_renderbuffer *zrb
00519             = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
00520          DEPTH_TYPE *zRow = NULL;
00521          GLint dZRowOuter = 0, dZRowInner;  /* offset in bytes */
00522 #  endif
00523          GLuint zLeft = 0;
00524          GLfixed fdzOuter = 0, fdzInner;
00525 #endif
00526 #ifdef INTERP_RGB
00527          GLint rLeft = 0, fdrOuter = 0, fdrInner;
00528          GLint gLeft = 0, fdgOuter = 0, fdgInner;
00529          GLint bLeft = 0, fdbOuter = 0, fdbInner;
00530 #endif
00531 #ifdef INTERP_ALPHA
00532          GLint aLeft = 0, fdaOuter = 0, fdaInner;
00533 #endif
00534 #ifdef INTERP_INDEX
00535          GLfixed iLeft=0, diOuter=0, diInner;
00536 #endif
00537 #ifdef INTERP_INT_TEX
00538          GLfixed sLeft=0, dsOuter=0, dsInner;
00539          GLfixed tLeft=0, dtOuter=0, dtInner;
00540 #endif
00541 #ifdef INTERP_ATTRIBS
00542          GLfloat wLeft = 0, dwOuter = 0, dwInner;
00543          GLfloat attrLeft[FRAG_ATTRIB_MAX][4];
00544          GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];
00545 #endif
00546 
00547          for (subTriangle=0; subTriangle<=1; subTriangle++) {
00548             EdgeT *eLeft, *eRight;
00549             int setupLeft, setupRight;
00550             int lines;
00551 
00552             if (subTriangle==0) {
00553                /* bottom half */
00554                if (scan_from_left_to_right) {
00555                   eLeft = &eMaj;
00556                   eRight = &eBot;
00557                   lines = eRight->lines;
00558                   setupLeft = 1;
00559                   setupRight = 1;
00560                }
00561                else {
00562                   eLeft = &eBot;
00563                   eRight = &eMaj;
00564                   lines = eLeft->lines;
00565                   setupLeft = 1;
00566                   setupRight = 1;
00567                }
00568             }
00569             else {
00570                /* top half */
00571                if (scan_from_left_to_right) {
00572                   eLeft = &eMaj;
00573                   eRight = &eTop;
00574                   lines = eRight->lines;
00575                   setupLeft = 0;
00576                   setupRight = 1;
00577                }
00578                else {
00579                   eLeft = &eTop;
00580                   eRight = &eMaj;
00581                   lines = eLeft->lines;
00582                   setupLeft = 1;
00583                   setupRight = 0;
00584                }
00585                if (lines == 0)
00586                   return;
00587             }
00588 
00589             if (setupLeft && eLeft->lines > 0) {
00590                const SWvertex *vLower = eLeft->v0;
00591                const GLfixed fsy = eLeft->fsy;
00592                const GLfixed fsx = eLeft->fsx;  /* no fractional part */
00593                const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
00594                const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
00595                const GLfixed adjy = (GLfixed) eLeft->adjy;      /* SCALED! */
00596                GLint idxOuter;
00597                GLfloat dxOuter;
00598                GLfixed fdxOuter;
00599 
00600                fError = fx - fsx - FIXED_ONE;
00601                fxLeftEdge = fsx - FIXED_EPSILON;
00602                fdxLeftEdge = eLeft->fdxdy;
00603                fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
00604                fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
00605                idxOuter = FixedToInt(fdxOuter);
00606                dxOuter = (GLfloat) idxOuter;
00607                span.y = FixedToInt(fsy);
00608 
00609                /* silence warnings on some compilers */
00610                (void) dxOuter;
00611                (void) adjx;
00612                (void) adjy;
00613                (void) vLower;
00614 
00615 #ifdef PIXEL_ADDRESS
00616                {
00617                   pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
00618                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
00619                   /* negative because Y=0 at bottom and increases upward */
00620                }
00621 #endif
00622                /*
00623                 * Now we need the set of parameter (z, color, etc.) values at
00624                 * the point (fx, fsy).  This gives us properly-sampled parameter
00625                 * values that we can step from pixel to pixel.  Furthermore,
00626                 * although we might have intermediate results that overflow
00627                 * the normal parameter range when we step temporarily outside
00628                 * the triangle, we shouldn't overflow or underflow for any
00629                 * pixel that's actually inside the triangle.
00630                 */
00631 
00632 #ifdef INTERP_Z
00633                {
00634                   GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2];
00635                   if (depthBits <= 16) {
00636                      /* interpolate fixed-pt values */
00637                      GLfloat tmp = (z0 * FIXED_SCALE
00638                                     + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx
00639                                     + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF;
00640                      if (tmp < MAX_GLUINT / 2)
00641                         zLeft = (GLfixed) tmp;
00642                      else
00643                         zLeft = MAX_GLUINT / 2;
00644                      fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] +
00645                                                    dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
00646                   }
00647                   else {
00648                      /* interpolate depth values w/out scaling */
00649                      zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
00650                                           + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
00651                      fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] +
00652                                          dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
00653                   }
00654 #  ifdef DEPTH_TYPE
00655                   zRow = (DEPTH_TYPE *)
00656                     zrb->GetPointer(ctx, zrb, FixedToInt(fxLeftEdge), span.y);
00657                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
00658 #  endif
00659                }
00660 #endif
00661 #ifdef INTERP_RGB
00662                if (ctx->Light.ShadeModel == GL_SMOOTH) {
00663                   rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP])
00664                                   + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx
00665                                   + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
00666                   gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP])
00667                                   + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx
00668                                   + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
00669                   bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP])
00670                                   + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx
00671                                   + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
00672                   fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0]
00673                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
00674                   fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1]
00675                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
00676                   fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2]
00677                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
00678 #  ifdef INTERP_ALPHA
00679                   aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
00680                                   + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx
00681                                   + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
00682                   fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3]
00683                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
00684 #  endif
00685                }
00686                else {
00687                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
00688                   rLeft = ChanToFixed(v2->color[RCOMP]);
00689                   gLeft = ChanToFixed(v2->color[GCOMP]);
00690                   bLeft = ChanToFixed(v2->color[BCOMP]);
00691                   fdrOuter = fdgOuter = fdbOuter = 0;
00692 #  ifdef INTERP_ALPHA
00693                   aLeft = ChanToFixed(v2->color[ACOMP]);
00694                   fdaOuter = 0;
00695 #  endif
00696                }
00697 #endif /* INTERP_RGB */
00698 
00699 
00700 #ifdef INTERP_INDEX
00701                if (ctx->Light.ShadeModel == GL_SMOOTH) {
00702                   iLeft = (GLfixed)(vLower->attrib[FRAG_ATTRIB_CI][0] * FIXED_SCALE
00703                                  + didx * adjx + didy * adjy) + FIXED_HALF;
00704                   diOuter = SignedFloatToFixed(didy + dxOuter * didx);
00705                }
00706                else {
00707                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
00708                   iLeft = FloatToFixed(v2->attrib[FRAG_ATTRIB_CI][0]);
00709                   diOuter = 0;
00710                }
00711 #endif
00712 #ifdef INTERP_INT_TEX
00713                {
00714                   GLfloat s0, t0;
00715                   s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
00716                   sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
00717                                  + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
00718                   dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0]
00719                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
00720 
00721                   t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
00722                   tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
00723                                  + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
00724                   dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1]
00725                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
00726                }
00727 #endif
00728 #ifdef INTERP_ATTRIBS
00729                {
00730                   const GLuint attr = FRAG_ATTRIB_WPOS;
00731                   wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3]
00732                         + (span.attrStepX[attr][3] * adjx
00733                            + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
00734                   dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
00735                }
00736                ATTRIB_LOOP_BEGIN
00737                   const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3];
00738                   if (swrast->_InterpMode[attr] == GL_FLAT) {
00739                      GLuint c;
00740                      for (c = 0; c < 4; c++) {
00741                         attrLeft[attr][c] = v2->attrib[attr][c] * invW;
00742                         daOuter[attr][c] = 0.0;
00743                      }
00744                   }
00745                   else {
00746                      GLuint c;
00747                      for (c = 0; c < 4; c++) {
00748                         const GLfloat a = vLower->attrib[attr][c] * invW;
00749                         attrLeft[attr][c] = a + (  span.attrStepX[attr][c] * adjx
00750                                                  + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
00751                         daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
00752                      }
00753                   }
00754                ATTRIB_LOOP_END
00755 #endif
00756             } /*if setupLeft*/
00757 
00758 
00759             if (setupRight && eRight->lines>0) {
00760                fxRightEdge = eRight->fsx - FIXED_EPSILON;
00761                fdxRightEdge = eRight->fdxdy;
00762             }
00763 
00764             if (lines==0) {
00765                continue;
00766             }
00767 
00768 
00769             /* Rasterize setup */
00770 #ifdef PIXEL_ADDRESS
00771             dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
00772 #endif
00773 #ifdef INTERP_Z
00774 #  ifdef DEPTH_TYPE
00775             dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
00776 #  endif
00777             fdzInner = fdzOuter + span.zStep;
00778 #endif
00779 #ifdef INTERP_RGB
00780             fdrInner = fdrOuter + span.redStep;
00781             fdgInner = fdgOuter + span.greenStep;
00782             fdbInner = fdbOuter + span.blueStep;
00783 #endif
00784 #ifdef INTERP_ALPHA
00785             fdaInner = fdaOuter + span.alphaStep;
00786 #endif
00787 #ifdef INTERP_INDEX
00788             diInner = diOuter + span.indexStep;
00789 #endif
00790 #ifdef INTERP_INT_TEX
00791             dsInner = dsOuter + span.intTexStep[0];
00792             dtInner = dtOuter + span.intTexStep[1];
00793 #endif
00794 #ifdef INTERP_ATTRIBS
00795             dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
00796             ATTRIB_LOOP_BEGIN
00797                GLuint c;
00798                for (c = 0; c < 4; c++) {
00799                   daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
00800                }
00801             ATTRIB_LOOP_END
00802 #endif
00803 
00804             while (lines > 0) {
00805                /* initialize the span interpolants to the leftmost value */
00806                /* ff = fixed-pt fragment */
00807                const GLint right = FixedToInt(fxRightEdge);
00808                span.x = FixedToInt(fxLeftEdge);
00809                if (right <= span.x)
00810                   span.end = 0;
00811                else
00812                   span.end = right - span.x;
00813 
00814 #ifdef INTERP_Z
00815                span.z = zLeft;
00816 #endif
00817 #ifdef INTERP_RGB
00818                span.red = rLeft;
00819                span.green = gLeft;
00820                span.blue = bLeft;
00821 #endif
00822 #ifdef INTERP_ALPHA
00823                span.alpha = aLeft;
00824 #endif
00825 #ifdef INTERP_INDEX
00826                span.index = iLeft;
00827 #endif
00828 #ifdef INTERP_INT_TEX
00829                span.intTex[0] = sLeft;
00830                span.intTex[1] = tLeft;
00831 #endif
00832 
00833 #ifdef INTERP_ATTRIBS
00834                span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
00835                ATTRIB_LOOP_BEGIN
00836                   GLuint c;
00837                   for (c = 0; c < 4; c++) {
00838                      span.attrStart[attr][c] = attrLeft[attr][c];
00839                   }
00840                ATTRIB_LOOP_END
00841 #endif
00842 
00843                /* This is where we actually generate fragments */
00844                /* XXX the test for span.y > 0 _shouldn't_ be needed but
00845                 * it fixes a problem on 64-bit Opterons (bug 4842).
00846                 */
00847                if (span.end > 0 && span.y >= 0) {
00848                   const GLint len = span.end - 1;
00849                   (void) len;
00850 #ifdef INTERP_RGB
00851                   CLAMP_INTERPOLANT(red, redStep, len);
00852                   CLAMP_INTERPOLANT(green, greenStep, len);
00853                   CLAMP_INTERPOLANT(blue, blueStep, len);
00854 #endif
00855 #ifdef INTERP_ALPHA
00856                   CLAMP_INTERPOLANT(alpha, alphaStep, len);
00857 #endif
00858 #ifdef INTERP_INDEX
00859                   CLAMP_INTERPOLANT(index, indexStep, len);
00860 #endif
00861                   {
00862                      RENDER_SPAN( span );
00863                   }
00864                }
00865 
00866                /*
00867                 * Advance to the next scan line.  Compute the
00868                 * new edge coordinates, and adjust the
00869                 * pixel-center x coordinate so that it stays
00870                 * on or inside the major edge.
00871                 */
00872                span.y++;
00873                lines--;
00874 
00875                fxLeftEdge += fdxLeftEdge;
00876                fxRightEdge += fdxRightEdge;
00877 
00878                fError += fdError;
00879                if (fError >= 0) {
00880                   fError -= FIXED_ONE;
00881 
00882 #ifdef PIXEL_ADDRESS
00883                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
00884 #endif
00885 #ifdef INTERP_Z
00886 #  ifdef DEPTH_TYPE
00887                   zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
00888 #  endif
00889                   zLeft += fdzOuter;
00890 #endif
00891 #ifdef INTERP_RGB
00892                   rLeft += fdrOuter;
00893                   gLeft += fdgOuter;
00894                   bLeft += fdbOuter;
00895 #endif
00896 #ifdef INTERP_ALPHA
00897                   aLeft += fdaOuter;
00898 #endif
00899 #ifdef INTERP_INDEX
00900                   iLeft += diOuter;
00901 #endif
00902 #ifdef INTERP_INT_TEX
00903                   sLeft += dsOuter;
00904                   tLeft += dtOuter;
00905 #endif
00906 #ifdef INTERP_ATTRIBS
00907                   wLeft += dwOuter;
00908                   ATTRIB_LOOP_BEGIN
00909                      GLuint c;
00910                      for (c = 0; c < 4; c++) {
00911                         attrLeft[attr][c] += daOuter[attr][c];
00912                      }
00913                   ATTRIB_LOOP_END
00914 #endif
00915                }
00916                else {
00917 #ifdef PIXEL_ADDRESS
00918                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
00919 #endif
00920 #ifdef INTERP_Z
00921 #  ifdef DEPTH_TYPE
00922                   zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
00923 #  endif
00924                   zLeft += fdzInner;
00925 #endif
00926 #ifdef INTERP_RGB
00927                   rLeft += fdrInner;
00928                   gLeft += fdgInner;
00929                   bLeft += fdbInner;
00930 #endif
00931 #ifdef INTERP_ALPHA
00932                   aLeft += fdaInner;
00933 #endif
00934 #ifdef INTERP_INDEX
00935                   iLeft += diInner;
00936 #endif
00937 #ifdef INTERP_INT_TEX
00938                   sLeft += dsInner;
00939                   tLeft += dtInner;
00940 #endif
00941 #ifdef INTERP_ATTRIBS
00942                   wLeft += dwInner;
00943                   ATTRIB_LOOP_BEGIN
00944                      GLuint c;
00945                      for (c = 0; c < 4; c++) {
00946                         attrLeft[attr][c] += daInner[attr][c];
00947                      }
00948                   ATTRIB_LOOP_END
00949 #endif
00950                }
00951             } /*while lines>0*/
00952 
00953          } /* for subTriangle */
00954 
00955       }
00956    }
00957 }
00958 
00959 #undef SETUP_CODE
00960 #undef RENDER_SPAN
00961 
00962 #undef PIXEL_TYPE
00963 #undef BYTES_PER_ROW
00964 #undef PIXEL_ADDRESS
00965 #undef DEPTH_TYPE
00966 
00967 #undef INTERP_Z
00968 #undef INTERP_RGB
00969 #undef INTERP_ALPHA
00970 #undef INTERP_INDEX
00971 #undef INTERP_INT_TEX
00972 #undef INTERP_ATTRIBS
00973 
00974 #undef S_SCALE
00975 #undef T_SCALE
00976 
00977 #undef FixedToDepth
00978 
00979 #undef NAME

Generated on Sat May 26 2012 04:19:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.