home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / AATRIANGLE / aatriangle.c next >
C/C++ Source or Header  |  2000-04-21  |  74KB  |  1,943 lines

  1. /* aatriangle.c  */
  2. /* originally made from aatriangle.c and aatritemp.h via 'icc -Pc+ -Pe+ aatriangle.c' + edit - EK */
  3. /* with great optimization made for rgba_aa_tri */
  4. /* $Id: aatriangle.c,v 1.5 2000/04/05 14:41:08 brianp Exp $ */
  5. /* $Id: aatritemp.h,v 1.9 2000/04/01 05:42:06 brianp Exp $ */
  6. /*
  7.  * Mesa 3-D graphics library
  8.  * Version:  3.3
  9.  *
  10.  * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
  11.  * partial (C) 2000 Evgeny Kotsuba
  12.  *
  13.  * Permission is hereby granted, free of charge, to any person obtaining a
  14.  * copy of this software and associated documentation files (the "Software"),
  15.  * to deal in the Software without restriction, including without limitation
  16.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  17.  * and/or sell copies of the Software, and to permit persons to whom the
  18.  * Software is furnished to do so, subject to the following conditions:
  19.  *
  20.  * The above copyright notice and this permission notice shall be included
  21.  * in all copies or substantial portions of the Software.
  22.  *
  23.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  24.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  26.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  27.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  28.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29.  */
  30.  
  31.  
  32. /*
  33.  * Antialiased Triangle rasterizers
  34.  */
  35.  
  36. #ifdef PC_HEADER
  37. #include "all.h"
  38. #else
  39. #include "glheader.h"
  40. #include "aatriangle.h"
  41. #include "span.h"
  42. #include "types.h"
  43. #include "vb.h"
  44. #endif
  45.  
  46.  
  47. /* EK */
  48. #include "malloc.h"
  49. #include "debug_mem.h"
  50. #define FIST_MAGIC ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))
  51. #define INLINE _Inline
  52. /*
  53.  * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
  54.  * vertices and the given Z values.
  55.  */
  56. /* static */
  57. static void  INLINE
  58. compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
  59.               GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4])
  60. {
  61.    const GLfloat px = v1[0] - v0[0];
  62.    const GLfloat py = v1[1] - v0[1];
  63.    const GLfloat pz = z1 - z0;
  64.  
  65.    const GLfloat qx = v2[0] - v0[0];
  66.    const GLfloat qy = v2[1] - v0[1];
  67.    const GLfloat qz = z2 - z0;
  68.  
  69.    const GLfloat a = py * qz - pz * qy;
  70.    const GLfloat b = pz * qx - px * qz;
  71.    const GLfloat c = px * qy - py * qx;
  72.    const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
  73.  
  74.    plane[0] = a;
  75.    plane[1] = b;
  76.    plane[2] = c;
  77.    plane[3] = d;
  78. }
  79.  
  80.  
  81. /*
  82.  * Compute coefficients of a plane with a constant Z value.
  83.  */
  84. /* static */
  85. static void  INLINE
  86. constant_plane(GLfloat value, GLfloat plane[4])
  87. {
  88.    plane[0] = 0.0;
  89.    plane[1] = 0.0;
  90.    plane[2] = -1.0;
  91.    plane[3] = value;
  92. }
  93.  
  94.  
  95.  
  96.  
  97. /*
  98.  * Solve plane equation for Z at (X,Y).
  99.  */
  100. /* static */
  101. static  INLINE GLfloat
  102. solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
  103. {
  104.    GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
  105.    return z;
  106. }
  107.  
  108.  
  109.  
  110.  
  111. /*
  112.  * Return 1 / solve_plane().
  113.  */
  114. /* static */
  115. static  INLINE GLfloat
  116. solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
  117. {
  118.    GLfloat z = -plane[2] / (plane[3] + plane[0] * x + plane[1] * y);
  119.    return z;
  120. }
  121.  
  122.  
  123. /*
  124.  * Solve plane and return clamped GLubyte value.
  125.  */
  126. /* static */
  127. static  INLINE GLubyte
  128. solve_plane_0_255(GLfloat x, GLfloat y, const GLfloat plane[4])
  129. {
  130.    GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F;
  131.    if (z < 0.0F)
  132.       return 0;
  133.    else if (z > 255.0F)
  134.       return 255;
  135.    return (GLubyte) (GLint) z;
  136. }
  137.  
  138.  
  139. /*
  140.  * Compute how much (area) of the given pixel is inside the triangle.
  141.  * Vertices MUST be specified in counter-clockwise order.
  142.  * Return:  coverage in [0, 1].
  143.  */
  144. /* static */
  145. static  GLfloat
  146. compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
  147.                   const GLfloat v2[3], GLint winx, GLint winy)
  148. {
  149.    static const GLfloat samples[16][2] = {
  150.       /* start with the four corners */
  151.       { 0.00, 0.00 },
  152.       { 0.75, 0.00 },
  153.       { 0.00, 0.75 },
  154.       { 0.75, 0.75 },
  155.       /* continue with interior samples */
  156.       { 0.25, 0.00 },
  157.       { 0.50, 0.00 },
  158.       { 0.00, 0.25 },
  159.       { 0.25, 0.25 },
  160.       { 0.50, 0.25 },
  161.       { 0.75, 0.25 },
  162.       { 0.00, 0.50 },
  163.       { 0.25, 0.50 },
  164.       { 0.50, 0.50 },
  165.       { 0.75, 0.50 },
  166.       { 0.25, 0.75 },
  167.       { 0.50, 0.75 }
  168.    };
  169.    const GLfloat x = (GLfloat) winx;
  170.    const GLfloat y = (GLfloat) winy;
  171.    const GLfloat dx0 = v1[0] - v0[0];
  172.    const GLfloat dy0 = v1[1] - v0[1];
  173.    const GLfloat dx1 = v2[0] - v1[0];
  174.    const GLfloat dy1 = v2[1] - v1[1];
  175.    const GLfloat dx2 = v0[0] - v2[0];
  176.    const GLfloat dy2 = v0[1] - v2[1];
  177.    GLfloat cross0,cross1,cross2;
  178.    GLint stop = 4, i;
  179.    GLfloat insideCount = 16.0F;
  180.  
  181.  
  182.    for (i = 0; i < stop; i++) {
  183.       const GLfloat sx = x + samples[i][0];
  184.       const GLfloat sy = y + samples[i][1];
  185. //      const GLfloat fx0 = sx - v0[0];
  186. //      const GLfloat fy0 = sy - v0[1];
  187. //      const GLfloat fx1 = sx - v1[0];
  188. //      const GLfloat fy1 = sy - v1[1];
  189. //      const GLfloat fx2 = sx - v2[0];
  190. //      const GLfloat fy2 = sy - v2[1];
  191.  
  192. //      fx0 = sx - v0[0];
  193. //      fy0 = sy - v0[1];
  194.       /* cross product determines if sample is inside or outside each edge */
  195.       cross0 = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0]));
  196.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  197.        * positive or negative value depending on the direction of the edge.
  198.        */
  199.       if (cross0 == 0.0F)
  200.          cross0 = dx0 + dy0;
  201.       if (cross0 < 0.0F) {
  202.          /* point is outside triangle */
  203.          insideCount--;
  204.          stop = 16;
  205.          continue;
  206.       }
  207. //      fx1 = sx - v1[0];
  208. //      fy1 = sy - v1[1];
  209.  
  210. //      cross1 = (dx1 * fy1 - dy1 * fx1);
  211.       cross1 = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0]));
  212.  
  213.       if (cross1 == 0.0F)
  214.          cross1 = dx1 + dy1;
  215.       if (cross1 < 0.0F) {
  216.          /* point is outside triangle */
  217.          insideCount--;
  218.          stop = 16;
  219.          continue;
  220.       }
  221. //      fx2 = sx - v2[0];
  222. //      fy2 = sy - v2[1];
  223. //    cross2 = (dx2 * fy2 - dy2 * fx2);
  224.       cross2 = (dx2 * (sy - v2[1]) - dy2 * (sx - v2[0]));
  225.       if (cross2 == 0.0F)
  226.          cross2 = dx2 + dy2;
  227.       if (cross2 < 0.0F) {
  228.          /* point is outside triangle */
  229.          insideCount--;
  230.          stop = 16;
  231.       }
  232.    }
  233.  
  234.    if (stop == 4)
  235.       return 1.0F;
  236.    else
  237.       return insideCount * (1.0F / 16.0F);
  238.  
  239. }
  240.  
  241.  
  242. /*
  243.  * Compute how much (area) of the given pixel is inside the triangle.
  244.  * Vertices MUST be specified in counter-clockwise order.
  245.  * Return:  coverage in [0, 15].
  246.  */
  247.  
  248. static  GLint
  249. compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
  250.                   const GLfloat v2[3], GLint winx, GLint winy)
  251. {
  252.    /* NOTE: 15 samples instead of 16.
  253.     * A better sample distribution could be used.
  254.     */
  255.    static const GLfloat samples[15][2] = {
  256.       /* start with the four corners */
  257.       { 0.00, 0.00 },
  258.       { 0.75, 0.00 },
  259.       { 0.00, 0.75 },
  260.       { 0.75, 0.75 },
  261.       /* continue with interior samples */
  262.       { 0.25, 0.00 },
  263.       { 0.50, 0.00 },
  264.       { 0.00, 0.25 },
  265.       { 0.25, 0.25 },
  266.       { 0.50, 0.25 },
  267.       { 0.75, 0.25 },
  268.       { 0.00, 0.50 },
  269.       { 0.25, 0.50 },
  270.       /*{ 0.50, 0.50 },*/
  271.       { 0.75, 0.50 },
  272.       { 0.25, 0.75 },
  273.       { 0.50, 0.75 }
  274.    };
  275.    const GLfloat x = (GLfloat) winx;
  276.    const GLfloat y = (GLfloat) winy;
  277.    const GLfloat dx0 = v1[0] - v0[0];
  278.    const GLfloat dy0 = v1[1] - v0[1];
  279.    const GLfloat dx1 = v2[0] - v1[0];
  280.    const GLfloat dy1 = v2[1] - v1[1];
  281.    const GLfloat dx2 = v0[0] - v2[0];
  282.    const GLfloat dy2 = v0[1] - v2[1];
  283.    GLint stop = 4, i;
  284.    GLint insideCount = 15;
  285.  
  286.  
  287.    for (i = 0; i < stop; i++) {
  288.       const GLfloat sx = x + samples[i][0];
  289.       const GLfloat sy = y + samples[i][1];
  290.       const GLfloat fx0 = sx - v0[0];
  291.       const GLfloat fy0 = sy - v0[1];
  292.       const GLfloat fx1 = sx - v1[0];
  293.       const GLfloat fy1 = sy - v1[1];
  294.       const GLfloat fx2 = sx - v2[0];
  295.       const GLfloat fy2 = sy - v2[1];
  296.       /* cross product determines if sample is inside or outside each edge */
  297.       GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
  298.       GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
  299.       GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
  300.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  301.        * positive or negative value depending on the direction of the edge.
  302.        */
  303.       if (cross0 == 0.0F)
  304.          cross0 = dx0 + dy0;
  305.       if (cross1 == 0.0F)
  306.          cross1 = dx1 + dy1;
  307.       if (cross2 == 0.0F)
  308.          cross2 = dx2 + dy2;
  309.       if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
  310.          /* point is outside triangle */
  311.          insideCount--;
  312.          stop = 15;
  313.       }
  314.    }
  315.    if (stop == 4)
  316.       return 15;
  317.    else
  318.       return insideCount;
  319. }
  320.  
  321. /* $Id: aatritemp.h,v 1.6 2000/03/14 15:05:47 brianp Exp $ */
  322. /*
  323.  * Antialiased Triangle Rasterizer Template
  324.  *
  325.  * This file is #include'd to generate custom AA triangle rasterizers.
  326.  * NOTE: this code hasn't been optimized yet.  That'll come after it
  327.  * works correctly.
  328.  *
  329.  * The following macros may be defined to indicate what auxillary information
  330.  * must be copmuted across the triangle:
  331.  *    DO_Z      - if defined, compute Z values
  332.  *    DO_RGBA   - if defined, compute RGBA values
  333.  *    DO_INDEX  - if defined, compute color index values
  334.  *    DO_SPEC   - if defined, compute specular RGB values
  335.  *    DO_STUV0  - if defined, compute unit 0 STRQ texcoords
  336.  *    DO_STUV1  - if defined, compute unit 1 STRQ texcoords
  337.  */
  338.  
  339. /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
  340.  
  341. //#define DO_Z
  342. //#define DO_RGBA
  343.  
  344. static void
  345. rgba_aa_tri(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
  346. {
  347.    const struct vertex_buffer *VB = ctx->VB;
  348.    const GLfloat *p0 = VB->Win.data[v0];
  349.    const GLfloat *p1 = VB->Win.data[v1];
  350.    const GLfloat *p2 = VB->Win.data[v2];
  351.    GLint vMin, vMid, vMax;
  352.    GLint iyMin, iyMax,ixMin,ixMax;
  353.    GLfloat yMin, yMax,xMax,xMin;
  354.    GLboolean ltor;
  355.    GLfloat majDx, majDy;
  356.    GLfloat zPlane[4],zPlaneDelta;                           /* Z (depth) */
  357.    GLdepth z[MAX_WIDTH];
  358.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];      /* color */
  359.    GLfloat rPlaneDelta,gPlaneDelta,bPlaneDelta,aPlaneDelta;
  360.    GLubyte rgba[MAX_WIDTH][4];
  361.    GLfloat bf = ctx->backface_sign;
  362.  
  363.    float ival;  /* EK */
  364.    double dtemp;
  365.    float  rPlane_c0, gPlane_c0,bPlane_c0,aPlane_c0, zPlane_c0,tmpz;
  366.    GLuint itmpz;
  367.  
  368.    /* determine bottom to top order of vertices */
  369.  
  370.    GLfloat y0 = VB->Win.data[v0][1];
  371.    GLfloat y1 = VB->Win.data[v1][1];
  372.    GLfloat y2 = VB->Win.data[v2][1];
  373.  
  374.       if (y0 <= y1) {
  375.         if (y1 <= y2) {
  376.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  377.         }
  378.         else if (y2 <= y0) {
  379.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  380.         }
  381.         else {
  382.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  383.         }
  384.       }
  385.       else {
  386.         if (y0 <= y2) {
  387.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  388.         }
  389.         else if (y2 <= y1) {
  390.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  391.         }
  392.         else {
  393.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  394.         }
  395.       }
  396.  
  397.    majDx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  398.    majDy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  399.  
  400.    {
  401.       const GLfloat botDx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  402.       const GLfloat botDy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  403.       const GLfloat area = majDx * botDy - botDx * majDy;
  404.       ltor = (GLboolean) (area < 0.0F);
  405.       /* Do backface culling */
  406.       if (area * bf < 0 || area * area < .0025)
  407.         return;
  408.    }
  409.  
  410. #ifndef DO_OCCLUSION_TEST
  411.    ctx->OcclusionResult = GL_TRUE;
  412. #endif
  413.  
  414.    /* plane setup */
  415.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  416.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  417.       GLubyte (*rgba)[4] = VB->ColorPtr->data;
  418.       compute_plane(p0, p1, p2, rgba[v0][0], rgba[v1][0], rgba[v2][0], rPlane);
  419.       compute_plane(p0, p1, p2, rgba[v0][1], rgba[v1][1], rgba[v2][1], gPlane);
  420.       compute_plane(p0, p1, p2, rgba[v0][2], rgba[v1][2], rgba[v2][2], bPlane);
  421.       compute_plane(p0, p1, p2, rgba[v0][3], rgba[v1][3], rgba[v2][3], aPlane);
  422.    }
  423.    else {
  424.       constant_plane(VB->ColorPtr->data[pv][0], rPlane);
  425.       constant_plane(VB->ColorPtr->data[pv][1], gPlane);
  426.       constant_plane(VB->ColorPtr->data[pv][2], bPlane);
  427.       constant_plane(VB->ColorPtr->data[pv][3], aPlane);
  428.    }
  429.  
  430.    yMin = VB->Win.data[vMin][1];
  431.    yMax = VB->Win.data[vMax][1];
  432.    iyMin = (int) yMin;
  433.    iyMax = (int) yMax + 1;
  434. /* EK */
  435.    xMax = xMin = VB->Win.data[vMax][0];
  436.    if(VB->Win.data[vMin][0] > xMax) xMax = VB->Win.data[vMin][0];
  437.    if(VB->Win.data[vMin][0] < xMin) xMin = VB->Win.data[vMin][0];
  438.    if(VB->Win.data[vMid][0] > xMax) xMax = VB->Win.data[vMid][0];
  439.    if(VB->Win.data[vMid][0] < xMin) xMin = VB->Win.data[vMid][0];
  440.    ixMin = (int) xMin;
  441.    ixMax = (int) xMax + 1;
  442. //   if(ixMin < 0) ixMin = 0;
  443.    if(ixMax >= ctx->DrawBuffer->Width) ixMax = ctx->DrawBuffer->Width - 1;
  444.    if(iyMax >= ctx->DrawBuffer->Height) iyMax = ctx->DrawBuffer->Height - 1;
  445.  
  446.    if (ltor) {
  447.       /* scan left to right */
  448.       const float *pMin = VB->Win.data[vMin];
  449.       const float *pMid = VB->Win.data[vMid];
  450.       const float *pMax = VB->Win.data[vMax];
  451.       const float dxdy = majDx / majDy;
  452.       const float xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  453.       float x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  454.       int iy;
  455.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  456.          GLint ix, startX = (GLint) (x - xAdj);
  457.          GLuint count, n;
  458.          GLfloat coverage=0.f;
  459.          /* skip over fragments with zero coverage */
  460.          while (startX < ixMax  /* MAX_WIDTH EK */ ) {
  461.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  462.             if (coverage > 0.0F)
  463.                break;
  464.             startX++;
  465.          }
  466.  
  467.          /* enter interior of triangle */
  468.          ix = startX;
  469.          if (coverage > 0.0F)
  470.          {
  471.          count = 0;
  472. //   rPlane_c0 = rPlane[3]+rPlane[1]*iy;
  473.    rPlane_c0 = ( rPlane[3]+rPlane[1]*iy + rPlane[0]*ix)/ -rPlane[2];
  474.    rPlaneDelta = rPlane[0]/ -rPlane[2];
  475.    gPlane_c0 = ( gPlane[3]+gPlane[1]*iy + gPlane[0]*ix)/ -gPlane[2];
  476.    gPlaneDelta = gPlane[0]/ -gPlane[2];
  477.    bPlane_c0 = ( bPlane[3]+bPlane[1]*iy + bPlane[0]*ix)/ -bPlane[2];
  478.    bPlaneDelta = bPlane[0]/ -bPlane[2];
  479.    aPlane_c0 = ( aPlane[3]+aPlane[1]*iy + aPlane[0]*ix)/ -aPlane[2];
  480.    aPlaneDelta = aPlane[0]/ -aPlane[2];
  481.  
  482. //   zPlane_c0 = zPlane[3]+zPlane[1]*iy;
  483.    zPlane_c0 = ( zPlane[3] + zPlane[1]*iy + zPlane[0]*ix) / -zPlane[2];
  484.    zPlaneDelta = zPlane[0] / -zPlane[2];
  485.              for(;ix <ixMax ;)
  486.              {
  487. ////         while (coverage > 0.0F) {
  488. //            z[count] = (GLdepth) solve_plane(ix, iy, zPlane);
  489. //GLdepth = int or short int
  490.               dtemp = FIST_MAGIC + zPlane_c0;
  491.               z[count] = (GLdepth) ((*(int *)&dtemp) - 0x80000000);
  492. //          rgba[count][RCOMP] = solve_plane_0_255(ix, iy, rPlane);
  493.               if (rPlane_c0 < 0.0F)        itmpz = 0;
  494.               else if (rPlane_c0 > 255.0F)      itmpz = 255;
  495.               else
  496.               {  //itmpz = tmpz;
  497.                   dtemp = FIST_MAGIC + rPlane_c0;
  498.                   itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  499.               }
  500.               rgba[count][RCOMP] = (GLubyte)itmpz;
  501. //          rgba[count][GCOMP] = solve_plane_0_255(ix, iy, gPlane);
  502.               if (gPlane_c0 < 0.0F)             itmpz = 0;
  503.               else if (gPlane_c0 > 255.0F)      itmpz = 255;
  504.               else
  505.               {  //itmpz = tmpz;
  506.                  dtemp = FIST_MAGIC + gPlane_c0;
  507.                  itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  508.               }
  509.               rgba[count][GCOMP] = (GLubyte)itmpz;
  510.  
  511. //            rgba[count][BCOMP] = solve_plane_0_255(ix, iy, bPlane);
  512.               if (bPlane_c0 < 0.0F)             itmpz = 0;
  513.               else if (bPlane_c0 > 255.0F)      itmpz = 255;
  514.               else
  515.               {  //itmpz = tmpz;
  516.                  dtemp = FIST_MAGIC + bPlane_c0;
  517.                  itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  518.               }
  519.               rgba[count][BCOMP] = (GLubyte)itmpz;
  520.  
  521. //          rgba[count][ACOMP] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  522. //          tmpz = (aPlane_c0 + aPlane[0]*ix)/ -aPlane[2] * coverage; /* + 0.5F; */
  523.               tmpz = aPlane_c0 * coverage;
  524.               if (tmpz < 0.0F)             itmpz = 0;
  525.               else if (tmpz > 255.0F)      itmpz = 255;
  526.               else
  527.               {  //itmpz = tmpz;
  528.                  dtemp = FIST_MAGIC + tmpz;
  529.                  itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  530.               }
  531.               rgba[count][ACOMP] = (GLubyte)itmpz;
  532.  
  533.               ix++;
  534.               coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  535.               if(!(coverage > 0.0F))
  536.                       break;
  537.               count++;
  538.               zPlane_c0 += zPlaneDelta;
  539.               rPlane_c0 += rPlaneDelta;
  540.               gPlane_c0 += gPlaneDelta;
  541.               bPlane_c0 += bPlaneDelta;
  542.               aPlane_c0 += aPlaneDelta;
  543.             }
  544.          } // endif (coverage > 0.0F)
  545.  
  546.          n = (GLuint) ix - (GLuint) startX;
  547. //  if(n == 2 && startX == 199 && iy == 199)
  548. //         printf("n=%i,startX=%i,iy=%i\n",n,startX,iy);
  549.          gl_write_rgba_span(ctx, n, startX, iy, z, rgba, GL_POLYGON);
  550. //CHECK_MEM;
  551.       }
  552.    }
  553.    else {
  554.       /* scan right to left */
  555.       const GLfloat *pMin = VB->Win.data[vMin];
  556.       const GLfloat *pMid = VB->Win.data[vMid];
  557.       const GLfloat *pMax = VB->Win.data[vMax];
  558.       const GLfloat dxdy = majDx / majDy;
  559.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  560.       GLfloat x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  561.       GLint iy;
  562.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  563.          GLint ix, left, startX = (GLint) (x + xAdj);
  564.          GLuint count, n;
  565.          GLfloat coverage =0.f;
  566.          /* skip fragments with zero coverage */
  567.          while (startX >= ixMin /* 0 EK */) {
  568.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  569.             if (coverage > 0.0F)
  570.                break;
  571.             startX--;
  572.          }
  573.  
  574.          /* enter interior of triangle */
  575.          ix = startX;
  576.          if (coverage > 0.0F)
  577.          {
  578.            rPlane_c0 = ( rPlane[3]+rPlane[1]*iy + rPlane[0]*ix)/ -rPlane[2];
  579.            rPlaneDelta = rPlane[0]/ rPlane[2];
  580.            gPlane_c0 = ( gPlane[3]+gPlane[1]*iy + gPlane[0]*ix)/ -gPlane[2];
  581.            gPlaneDelta = gPlane[0]/ gPlane[2];
  582.            bPlane_c0 = ( bPlane[3]+bPlane[1]*iy + bPlane[0]*ix)/ -bPlane[2];
  583.            bPlaneDelta = bPlane[0]/ bPlane[2];
  584.            aPlane_c0 = ( aPlane[3]+aPlane[1]*iy + aPlane[0]*ix)/ -aPlane[2];
  585.            aPlaneDelta = aPlane[0]/ aPlane[2];
  586.            zPlane_c0 = ( zPlane[3] + zPlane[1]*iy+zPlane[0]*ix) / -zPlane[2];
  587.            zPlaneDelta = zPlane[0] / zPlane[2];
  588.  
  589.            for(;ix>0;)
  590. //while (coverage > 0.0F)
  591.            {
  592. //            z[ix] = (GLdepth) solve_plane(ix, iy, zPlane);
  593.              dtemp = FIST_MAGIC + zPlane_c0;
  594.              z[ix] = (GLdepth) ((*(int *)&dtemp) - 0x80000000);
  595.  
  596. //          rgba[ix][RCOMP] = solve_plane_0_255(ix, iy, rPlane);
  597.              if (rPlane_c0 < 0.0F)             itmpz = 0;
  598.              else if (rPlane_c0 > 255.0F)      itmpz = 255;
  599.              else
  600.              {  //itmpz = tmpz;
  601.                 dtemp = FIST_MAGIC + rPlane_c0;
  602.                 itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  603.              }
  604.  
  605.              rgba[ix][RCOMP] = (GLubyte)itmpz;
  606.  
  607. //          rgba[ix][GCOMP] = solve_plane_0_255(ix, iy, gPlane);
  608.              if (gPlane_c0 < 0.0F)             itmpz = 0;
  609.              else if (gPlane_c0 > 255.0F)      itmpz = 255;
  610.              else
  611.              {  //itmpz = tmpz;
  612.                 dtemp = FIST_MAGIC + gPlane_c0;
  613.                 itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  614.              }
  615.              rgba[ix][GCOMP] = (GLubyte)itmpz;
  616.  
  617. //            rgba[ix][BCOMP] = solve_plane_0_255(ix, iy, bPlane);
  618.              if (bPlane_c0 < 0.0F)             itmpz = 0;
  619.              else if (bPlane_c0 > 255.0F)      itmpz = 255;
  620.              else
  621.              {  //itmpz = tmpz;
  622.                 dtemp = FIST_MAGIC + bPlane_c0;
  623.                 itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  624.              }
  625.              rgba[ix][BCOMP] = (GLubyte)itmpz;
  626.  
  627. //          rgba[ix][ACOMP] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  628.              tmpz = aPlane_c0 * coverage;
  629.              if (tmpz < 0.0F)             itmpz = 0;
  630.              else if (tmpz > 255.0F)      itmpz = 255;
  631.              else
  632.              {  //itmpz = tmpz;
  633.                 dtemp = FIST_MAGIC + tmpz;
  634.                 itmpz = (GLubyte) ((*(int *)&dtemp) - 0x80000000);
  635.              }
  636.              rgba[ix][ACOMP] = (GLubyte)itmpz;
  637.  
  638.              ix--;
  639.              coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  640.              if(!(coverage > 0.0F))
  641.                       break;
  642.              zPlane_c0 += zPlaneDelta;
  643.              rPlane_c0 += rPlaneDelta;
  644.              gPlane_c0 += gPlaneDelta;
  645.              bPlane_c0 += bPlaneDelta;
  646.              aPlane_c0 += aPlaneDelta;
  647.            }
  648.          } //endif (coverage > 0.0F)
  649.  
  650.          n = (GLuint) startX - (GLuint) ix;
  651.          left = ix + 1;
  652. //  printf("n=%i,startX=%i,iy=%i\n",n,startX,iy);
  653.          gl_write_rgba_span(ctx, n, left, iy, z + left,
  654.                             rgba + left, GL_POLYGON);
  655. //CHECK_MEM;
  656.       }
  657.    }
  658. }
  659.  
  660.  
  661. //#define DO_Z
  662. //#define DO_INDEX
  663.  
  664. static void
  665. index_aa_tri(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
  666. {
  667.    const struct vertex_buffer *VB = ctx->VB;
  668.    const GLfloat *p0 = VB->Win.data[v0];
  669.    const GLfloat *p1 = VB->Win.data[v1];
  670.    const GLfloat *p2 = VB->Win.data[v2];
  671.    GLint vMin, vMid, vMax;
  672.    GLint iyMin, iyMax;
  673.    GLfloat yMin, yMax;
  674.    GLboolean ltor;
  675.    GLfloat majDx, majDy;
  676.    GLfloat zPlane[4];                                       /* Z (depth) */
  677.    GLdepth z[MAX_WIDTH];
  678.    GLfloat iPlane[4];                                       /* color index */
  679.    GLuint index[MAX_WIDTH];
  680.    GLfloat bf = ctx->backface_sign;
  681.  
  682.    /* determine bottom to top order of vertices */
  683.    {
  684.       GLfloat y0 = VB->Win.data[v0][1];
  685.       GLfloat y1 = VB->Win.data[v1][1];
  686.       GLfloat y2 = VB->Win.data[v2][1];
  687.       if (y0 <= y1) {
  688.         if (y1 <= y2) {
  689.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  690.         }
  691.         else if (y2 <= y0) {
  692.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  693.         }
  694.         else {
  695.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  696.         }
  697.       }
  698.       else {
  699.         if (y0 <= y2) {
  700.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  701.         }
  702.         else if (y2 <= y1) {
  703.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  704.         }
  705.         else {
  706.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  707.         }
  708.       }
  709.    }
  710.  
  711.    majDx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  712.    majDy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  713.  
  714.    {
  715.       const GLfloat botDx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  716.       const GLfloat botDy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  717.       const GLfloat area = majDx * botDy - botDx * majDy;
  718.       ltor = (GLboolean) (area < 0.0F);
  719.       /* Do backface culling */
  720.       if (area * bf < 0 || area * area < .0025)
  721.         return;
  722.    }
  723.  
  724. #ifndef DO_OCCLUSION_TEST
  725.    ctx->OcclusionResult = GL_TRUE;
  726. #endif
  727.  
  728.    /* plane setup */
  729.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  730.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  731.       compute_plane(p0, p1, p2, VB->IndexPtr->data[v0],
  732.                     VB->IndexPtr->data[v1], VB->IndexPtr->data[v2], iPlane);
  733.    }
  734.    else {
  735.       constant_plane(VB->IndexPtr->data[pv], iPlane);
  736.    }
  737.  
  738.    yMin = VB->Win.data[vMin][1];
  739.    yMax = VB->Win.data[vMax][1];
  740.    iyMin = (int) yMin;
  741.    iyMax = (int) yMax + 1;
  742.  
  743.    if (ltor) {
  744.       /* scan left to right */
  745.       const float *pMin = VB->Win.data[vMin];
  746.       const float *pMid = VB->Win.data[vMid];
  747.       const float *pMax = VB->Win.data[vMax];
  748.       const float dxdy = majDx / majDy;
  749.       const float xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  750.       float x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  751.       int iy;
  752.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  753.          GLint ix, startX = (GLint) (x - xAdj);
  754.          GLuint count, n;
  755.          GLfloat coverage=0.f;
  756.          /* skip over fragments with zero coverage */
  757.          while (startX < MAX_WIDTH) {
  758.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  759.             if (coverage > 0.0F)
  760.                break;
  761.             startX++;
  762.          }
  763.  
  764.          /* enter interior of triangle */
  765.          ix = startX;
  766.          count = 0;
  767.          while (coverage > 0.0F) {
  768.             z[count] = (GLdepth) solve_plane(ix, iy, zPlane);
  769.             {
  770.                GLint frac = compute_coveragei(pMin, pMid, pMax, ix, iy);
  771.                GLint indx = (GLint) solve_plane(ix, iy, iPlane);
  772.                index[count] = (indx & ~0xf) | frac;
  773.             }
  774.             ix++;
  775.             count++;
  776.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  777.          }
  778.  
  779.          n = (GLuint) ix - (GLuint) startX;
  780.          gl_write_index_span(ctx, n, startX, iy, z, index, GL_POLYGON);
  781.       }
  782.    }
  783.    else {
  784.       /* scan right to left */
  785.       const GLfloat *pMin = VB->Win.data[vMin];
  786.       const GLfloat *pMid = VB->Win.data[vMid];
  787.       const GLfloat *pMax = VB->Win.data[vMax];
  788.       const GLfloat dxdy = majDx / majDy;
  789.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  790.       GLfloat x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  791.       GLint iy;
  792.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  793.          GLint ix, left, startX = (GLint) (x + xAdj);
  794.          GLuint count, n;
  795.          GLfloat coverage=0.f;
  796.          /* skip fragments with zero coverage */
  797.          while (startX >= 0) {
  798.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  799.             if (coverage > 0.0F)
  800.                break;
  801.             startX--;
  802.          }
  803.  
  804.          /* enter interior of triangle */
  805.          ix = startX;
  806.          count = 0;
  807.          while (coverage > 0.0F) {
  808.             z[ix] = (GLdepth) solve_plane(ix, iy, zPlane);
  809.             {
  810.                GLint frac = compute_coveragei(pMin, pMax, pMid, ix, iy);
  811.                GLint indx = (GLint) solve_plane(ix, iy, iPlane);
  812.                index[ix] = (indx & ~0xf) | frac;
  813.             }
  814.             ix--;
  815.             count++;
  816.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  817.          }
  818.  
  819.          n = (GLuint) startX - (GLuint) ix;
  820.          left = ix + 1;
  821.          gl_write_index_span(ctx, n, left, iy, z + left,
  822.                              index + left, GL_POLYGON);
  823.       }
  824.    }
  825. }
  826.  
  827.  
  828. /*
  829.  * Compute mipmap level of detail.
  830.  */
  831. static INLINE GLfloat
  832. compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
  833.                GLfloat invQ, GLfloat width, GLfloat height)
  834. {
  835.    GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width;
  836.    GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width;
  837.    GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height;
  838.    GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height;
  839.    GLfloat r1 = dudx * dudx + dudy * dudy;
  840.    GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
  841.    GLfloat rho2 = r1 + r2;
  842.    /* return log base 2 of rho */
  843.    return log(rho2) * 1.442695 * 0.5;       /* 1.442695 = 1/log(2) */
  844. }
  845.  
  846. //#define DO_Z
  847. //#define DO_RGBA
  848. //#define DO_STUV0
  849.  
  850. static void
  851. tex_aa_tri(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
  852. {
  853.    const struct vertex_buffer *VB = ctx->VB;
  854.    const GLfloat *p0 = VB->Win.data[v0];
  855.    const GLfloat *p1 = VB->Win.data[v1];
  856.    const GLfloat *p2 = VB->Win.data[v2];
  857.    GLint vMin, vMid, vMax;
  858.    GLint iyMin, iyMax;
  859.    GLfloat yMin, yMax;
  860.    GLboolean ltor;
  861.    GLfloat majDx, majDy;
  862.    GLfloat zPlane[4];                                       /* Z (depth) */
  863.    GLdepth z[MAX_WIDTH];
  864.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];      /* color */
  865.    GLubyte rgba[MAX_WIDTH][4];
  866.    GLfloat s0Plane[4], t0Plane[4], u0Plane[4], v0Plane[4];  /* texture 0 */
  867.    GLfloat width0, height0;
  868.    GLfloat s[2][MAX_WIDTH];
  869.    GLfloat t[2][MAX_WIDTH];
  870.    GLfloat u[2][MAX_WIDTH];
  871.    GLfloat lambda[2][MAX_WIDTH];
  872.    GLfloat bf = ctx->backface_sign;
  873.  
  874.    /* determine bottom to top order of vertices */
  875.    {
  876.       GLfloat y0 = VB->Win.data[v0][1];
  877.       GLfloat y1 = VB->Win.data[v1][1];
  878.       GLfloat y2 = VB->Win.data[v2][1];
  879.       if (y0 <= y1) {
  880.         if (y1 <= y2) {
  881.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  882.         }
  883.         else if (y2 <= y0) {
  884.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  885.         }
  886.         else {
  887.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  888.         }
  889.       }
  890.       else {
  891.         if (y0 <= y2) {
  892.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  893.         }
  894.         else if (y2 <= y1) {
  895.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  896.         }
  897.         else {
  898.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  899.         }
  900.       }
  901.    }
  902.  
  903.    majDx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  904.    majDy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  905.  
  906.    {
  907.       const GLfloat botDx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  908.       const GLfloat botDy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  909.       const GLfloat area = majDx * botDy - botDx * majDy;
  910.       ltor = (GLboolean) (area < 0.0F);
  911.       /* Do backface culling */
  912.       if (area * bf < 0 || area * area < .0025)
  913.         return;
  914.    }
  915.  
  916. #ifndef DO_OCCLUSION_TEST
  917.    ctx->OcclusionResult = GL_TRUE;
  918. #endif
  919.  
  920.    /* plane setup */
  921.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  922.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  923.       GLubyte (*rgba)[4] = VB->ColorPtr->data;
  924.       compute_plane(p0, p1, p2, rgba[v0][0], rgba[v1][0], rgba[v2][0], rPlane);
  925.       compute_plane(p0, p1, p2, rgba[v0][1], rgba[v1][1], rgba[v2][1], gPlane);
  926.       compute_plane(p0, p1, p2, rgba[v0][2], rgba[v1][2], rgba[v2][2], bPlane);
  927.       compute_plane(p0, p1, p2, rgba[v0][3], rgba[v1][3], rgba[v2][3], aPlane);
  928.    }
  929.    else {
  930.       constant_plane(VB->ColorPtr->data[pv][0], rPlane);
  931.       constant_plane(VB->ColorPtr->data[pv][1], gPlane);
  932.       constant_plane(VB->ColorPtr->data[pv][2], bPlane);
  933.       constant_plane(VB->ColorPtr->data[pv][3], aPlane);
  934.    }
  935.    {
  936.       const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;
  937.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  938.       const GLint tSize = 3;
  939.       const GLfloat invW0 = VB->Win.data[v0][3];
  940.       const GLfloat invW1 = VB->Win.data[v1][3];
  941.       const GLfloat invW2 = VB->Win.data[v2][3];
  942.       GLfloat (*texCoord)[4] = VB->TexCoordPtr[0]->data;
  943.       const GLfloat s0 = texCoord[v0][0] * invW0;
  944.       const GLfloat s1 = texCoord[v1][0] * invW1;
  945.       const GLfloat s2 = texCoord[v2][0] * invW2;
  946.       const GLfloat t0 = (tSize > 1) ? texCoord[v0][1] * invW0 : 0.0F;
  947.       const GLfloat t1 = (tSize > 1) ? texCoord[v1][1] * invW1 : 0.0F;
  948.       const GLfloat t2 = (tSize > 1) ? texCoord[v2][1] * invW2 : 0.0F;
  949.       const GLfloat r0 = (tSize > 2) ? texCoord[v0][2] * invW0 : 0.0F;
  950.       const GLfloat r1 = (tSize > 2) ? texCoord[v1][2] * invW1 : 0.0F;
  951.       const GLfloat r2 = (tSize > 2) ? texCoord[v2][2] * invW2 : 0.0F;
  952.       const GLfloat q0 = (tSize > 3) ? texCoord[v0][3] * invW0 : invW0;
  953.       const GLfloat q1 = (tSize > 3) ? texCoord[v1][3] * invW1 : invW1;
  954.       const GLfloat q2 = (tSize > 3) ? texCoord[v2][3] * invW2 : invW2;
  955.       compute_plane(p0, p1, p2, s0, s1, s2, s0Plane);
  956.       compute_plane(p0, p1, p2, t0, t1, t2, t0Plane);
  957.       compute_plane(p0, p1, p2, r0, r1, r2, u0Plane);
  958.       compute_plane(p0, p1, p2, q0, q1, q2, v0Plane);
  959.       width0 = (GLfloat) texImage->Width;
  960.       height0 = (GLfloat) texImage->Height;
  961.    }
  962.  
  963.    yMin = VB->Win.data[vMin][1];
  964.    yMax = VB->Win.data[vMax][1];
  965.    iyMin = (int) yMin;
  966.    iyMax = (int) yMax + 1;
  967.  
  968.    if (ltor) {
  969.       /* scan left to right */
  970.       const float *pMin = VB->Win.data[vMin];
  971.       const float *pMid = VB->Win.data[vMid];
  972.       const float *pMax = VB->Win.data[vMax];
  973.       const float dxdy = majDx / majDy;
  974.       const float xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  975.       float x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  976.       int iy;
  977.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  978.          GLint ix, startX = (GLint) (x - xAdj);
  979.          GLuint count, n;
  980.          GLfloat coverage=0.f;
  981.          /* skip over fragments with zero coverage */
  982.          while (startX < MAX_WIDTH) {
  983.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  984.             if (coverage > 0.0F)
  985.                break;
  986.             startX++;
  987.          }
  988.  
  989.          /* enter interior of triangle */
  990.          ix = startX;
  991.          count = 0;
  992.          while (coverage > 0.0F) {
  993.             z[count] =(GLdepth) solve_plane(ix, iy, zPlane);
  994.             rgba[count][RCOMP] = solve_plane_0_255(ix, iy, rPlane);
  995.             rgba[count][GCOMP] = solve_plane_0_255(ix, iy, gPlane);
  996.             rgba[count][BCOMP] = solve_plane_0_255(ix, iy, bPlane);
  997.             rgba[count][ACOMP] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  998.             {
  999.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1000.                s[0][count] = solve_plane(ix, iy, s0Plane) * invQ;
  1001.                t[0][count] = solve_plane(ix, iy, t0Plane) * invQ;
  1002.                u[0][count] = solve_plane(ix, iy, u0Plane) * invQ;
  1003.                lambda[0][count] = compute_lambda(s0Plane, t0Plane, invQ,
  1004.                                                  width0, height0);
  1005.             }
  1006.             ix++;
  1007.             count++;
  1008.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1009.          }
  1010.  
  1011.          n = (GLuint) ix - (GLuint) startX;
  1012.          gl_write_texture_span(ctx, n, startX, iy, z,
  1013.                                s[0], t[0], u[0], lambda[0],
  1014.                                rgba, 0, GL_POLYGON);
  1015.       }
  1016.    }
  1017.    else {
  1018.       /* scan right to left */
  1019.       const GLfloat *pMin = VB->Win.data[vMin];
  1020.       const GLfloat *pMid = VB->Win.data[vMid];
  1021.       const GLfloat *pMax = VB->Win.data[vMax];
  1022.       const GLfloat dxdy = majDx / majDy;
  1023.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1024.       GLfloat x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1025.       GLint iy;
  1026.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1027.          GLint ix, left, startX = (GLint) (x + xAdj);
  1028.          GLuint count, n;
  1029.          GLfloat coverage=0.f;
  1030.          /* skip fragments with zero coverage */
  1031.          while (startX >= 0) {
  1032.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1033.             if (coverage > 0.0F)
  1034.                break;
  1035.             startX--;
  1036.          }
  1037.  
  1038.          /* enter interior of triangle */
  1039.          ix = startX;
  1040.          count = 0;
  1041.          while (coverage > 0.0F) {
  1042.             z[ix] = (GLdepth) solve_plane(ix, iy, zPlane);
  1043.             rgba[ix][0] = solve_plane_0_255(ix, iy, rPlane);
  1044.             rgba[ix][1] = solve_plane_0_255(ix, iy, gPlane);
  1045.             rgba[ix][2] = solve_plane_0_255(ix, iy, bPlane);
  1046.             rgba[ix][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1047.             {
  1048.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1049.                s[0][ix] = solve_plane(ix, iy, s0Plane) * invQ;
  1050.                t[0][ix] = solve_plane(ix, iy, t0Plane) * invQ;
  1051.                u[0][ix] = solve_plane(ix, iy, u0Plane) * invQ;
  1052.                lambda[0][ix] = compute_lambda(s0Plane, t0Plane, invQ,
  1053.                                               width0, height0);
  1054.             }
  1055.             ix--;
  1056.             count++;
  1057.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1058.          }
  1059.  
  1060.          n = (GLuint) startX - (GLuint) ix;
  1061.          left = ix + 1;
  1062.          gl_write_texture_span(ctx, n, left, iy, z + left,
  1063.                                s[0] + left, t[0] + left,
  1064.                                u[0] + left, lambda[0] + left,
  1065.                                rgba + left, 0, GL_POLYGON);
  1066.       }
  1067.    }
  1068. }
  1069.  
  1070. //#define DO_Z
  1071. //#define DO_RGBA
  1072. //#define DO_STUV0
  1073. //#define DO_SPEC
  1074.  
  1075. static void
  1076. spec_tex_aa_tri(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
  1077. {  const struct vertex_buffer *VB = ctx->VB;
  1078.    const GLfloat *p0 = VB->Win.data[v0];
  1079.    const GLfloat *p1 = VB->Win.data[v1];
  1080.    const GLfloat *p2 = VB->Win.data[v2];
  1081.    GLint vMin, vMid, vMax;
  1082.    GLint iyMin, iyMax;
  1083.    GLfloat yMin, yMax;
  1084.    GLboolean ltor;
  1085.    GLfloat majDx, majDy;
  1086.    GLfloat zPlane[4];                                       /* Z (depth) */
  1087.    GLdepth z[MAX_WIDTH];
  1088.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];      /* color */
  1089.    GLubyte rgba[MAX_WIDTH][4];
  1090.    GLfloat srPlane[4], sgPlane[4], sbPlane[4];              /* spec color */
  1091.    GLubyte spec[MAX_WIDTH][4];
  1092.    GLfloat s0Plane[4], t0Plane[4], u0Plane[4], v0Plane[4];  /* texture 0 */
  1093.    GLfloat width0, height0;
  1094.    GLfloat s[2][MAX_WIDTH];
  1095.    GLfloat t[2][MAX_WIDTH];
  1096.    GLfloat u[2][MAX_WIDTH];
  1097.    GLfloat lambda[2][MAX_WIDTH];
  1098.    GLfloat bf = ctx->backface_sign;
  1099.  
  1100.    /* determine bottom to top order of vertices */
  1101.    {
  1102.       GLfloat y0 = VB->Win.data[v0][1];
  1103.       GLfloat y1 = VB->Win.data[v1][1];
  1104.       GLfloat y2 = VB->Win.data[v2][1];
  1105.       if (y0 <= y1) {
  1106.         if (y1 <= y2) {
  1107.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  1108.         }
  1109.         else if (y2 <= y0) {
  1110.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  1111.         }
  1112.         else {
  1113.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  1114.         }
  1115.       }
  1116.       else {
  1117.         if (y0 <= y2) {
  1118.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  1119.         }
  1120.         else if (y2 <= y1) {
  1121.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  1122.         }
  1123.         else {
  1124.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  1125.         }
  1126.       }
  1127.    }
  1128.  
  1129.    majDx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  1130.    majDy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  1131.  
  1132.    {
  1133.       const GLfloat botDx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  1134.       const GLfloat botDy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  1135.       const GLfloat area = majDx * botDy - botDx * majDy;
  1136.       ltor = (GLboolean) (area < 0.0F);
  1137.       /* Do backface culling */
  1138.       if (area * bf < 0 || area * area < .0025)
  1139.         return;
  1140.    }
  1141.  
  1142. #ifndef DO_OCCLUSION_TEST
  1143.    ctx->OcclusionResult = GL_TRUE;
  1144. #endif
  1145.  
  1146.    /* plane setup */
  1147.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1148.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  1149.       GLubyte (*rgba)[4] = VB->ColorPtr->data;
  1150.       compute_plane(p0, p1, p2, rgba[v0][0], rgba[v1][0], rgba[v2][0], rPlane);
  1151.       compute_plane(p0, p1, p2, rgba[v0][1], rgba[v1][1], rgba[v2][1], gPlane);
  1152.       compute_plane(p0, p1, p2, rgba[v0][2], rgba[v1][2], rgba[v2][2], bPlane);
  1153.       compute_plane(p0, p1, p2, rgba[v0][3], rgba[v1][3], rgba[v2][3], aPlane);
  1154.    }
  1155.    else {
  1156.       constant_plane(VB->ColorPtr->data[pv][0], rPlane);
  1157.       constant_plane(VB->ColorPtr->data[pv][1], gPlane);
  1158.       constant_plane(VB->ColorPtr->data[pv][2], bPlane);
  1159.       constant_plane(VB->ColorPtr->data[pv][3], aPlane);
  1160.    }
  1161.    {
  1162.       GLubyte (*spec)[4] = VB->Specular;
  1163.       compute_plane(p0, p1, p2, spec[v0][0], spec[v1][0], spec[v2][0],srPlane);
  1164.       compute_plane(p0, p1, p2, spec[v0][1], spec[v1][1], spec[v2][1],sgPlane);
  1165.       compute_plane(p0, p1, p2, spec[v0][2], spec[v1][2], spec[v2][2],sbPlane);
  1166.    }
  1167.    {
  1168.       const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;
  1169.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1170.       const GLint tSize = 3;
  1171.       const GLfloat invW0 = VB->Win.data[v0][3];
  1172.       const GLfloat invW1 = VB->Win.data[v1][3];
  1173.       const GLfloat invW2 = VB->Win.data[v2][3];
  1174.       GLfloat (*texCoord)[4] = VB->TexCoordPtr[0]->data;
  1175.       const GLfloat s0 = texCoord[v0][0] * invW0;
  1176.       const GLfloat s1 = texCoord[v1][0] * invW1;
  1177.       const GLfloat s2 = texCoord[v2][0] * invW2;
  1178.       const GLfloat t0 = (tSize > 1) ? texCoord[v0][1] * invW0 : 0.0F;
  1179.       const GLfloat t1 = (tSize > 1) ? texCoord[v1][1] * invW1 : 0.0F;
  1180.       const GLfloat t2 = (tSize > 1) ? texCoord[v2][1] * invW2 : 0.0F;
  1181.       const GLfloat r0 = (tSize > 2) ? texCoord[v0][2] * invW0 : 0.0F;
  1182.       const GLfloat r1 = (tSize > 2) ? texCoord[v1][2] * invW1 : 0.0F;
  1183.       const GLfloat r2 = (tSize > 2) ? texCoord[v2][2] * invW2 : 0.0F;
  1184.       const GLfloat q0 = (tSize > 3) ? texCoord[v0][3] * invW0 : invW0;
  1185.       const GLfloat q1 = (tSize > 3) ? texCoord[v1][3] * invW1 : invW1;
  1186.       const GLfloat q2 = (tSize > 3) ? texCoord[v2][3] * invW2 : invW2;
  1187.       compute_plane(p0, p1, p2, s0, s1, s2, s0Plane);
  1188.       compute_plane(p0, p1, p2, t0, t1, t2, t0Plane);
  1189.       compute_plane(p0, p1, p2, r0, r1, r2, u0Plane);
  1190.       compute_plane(p0, p1, p2, q0, q1, q2, v0Plane);
  1191.       width0 = (GLfloat) texImage->Width;
  1192.       height0 = (GLfloat) texImage->Height;
  1193.    }
  1194.  
  1195.    yMin = VB->Win.data[vMin][1];
  1196.    yMax = VB->Win.data[vMax][1];
  1197.    iyMin = (int) yMin;
  1198.    iyMax = (int) yMax + 1;
  1199.  
  1200.    if (ltor) {
  1201.       /* scan left to right */
  1202.       const float *pMin = VB->Win.data[vMin];
  1203.       const float *pMid = VB->Win.data[vMid];
  1204.       const float *pMax = VB->Win.data[vMax];
  1205.       const float dxdy = majDx / majDy;
  1206.       const float xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1207.       float x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1208.       int iy;
  1209.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1210.          GLint ix, startX = (GLint) (x - xAdj);
  1211.          GLuint count, n;
  1212.          GLfloat coverage=0.f;
  1213.          /* skip over fragments with zero coverage */
  1214.          while (startX < MAX_WIDTH) {
  1215.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1216.             if (coverage > 0.0F)
  1217.                break;
  1218.             startX++;
  1219.          }
  1220.  
  1221.          /* enter interior of triangle */
  1222.          ix = startX;
  1223.          count = 0;
  1224.          while (coverage > 0.0F) {
  1225.             z[count] = (GLdepth) solve_plane(ix, iy, zPlane);
  1226.             rgba[count][0] = solve_plane_0_255(ix, iy, rPlane);
  1227.             rgba[count][1] = solve_plane_0_255(ix, iy, gPlane);
  1228.             rgba[count][2] = solve_plane_0_255(ix, iy, bPlane);
  1229.             rgba[count][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1230.             spec[count][0] = solve_plane_0_255(ix, iy, srPlane);
  1231.             spec[count][1] = solve_plane_0_255(ix, iy, sgPlane);
  1232.             spec[count][2] = solve_plane_0_255(ix, iy, sbPlane);
  1233.             {
  1234.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1235.                s[0][count] = solve_plane(ix, iy, s0Plane) * invQ;
  1236.                t[0][count] = solve_plane(ix, iy, t0Plane) * invQ;
  1237.                u[0][count] = solve_plane(ix, iy, u0Plane) * invQ;
  1238.                lambda[0][count] = compute_lambda(s0Plane, t0Plane, invQ,
  1239.                                                  width0, height0);
  1240.             }
  1241.             ix++;
  1242.             count++;
  1243.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1244.          }
  1245.  
  1246.          n = (GLuint) ix - (GLuint) startX;
  1247.          gl_write_texture_span(ctx, n, startX, iy, z,
  1248.                                s[0], t[0], u[0], lambda[0], rgba,
  1249.                                (const GLubyte (*)[4]) spec, GL_POLYGON);
  1250.       }
  1251.    }
  1252.    else {
  1253.       /* scan right to left */
  1254.       const GLfloat *pMin = VB->Win.data[vMin];
  1255.       const GLfloat *pMid = VB->Win.data[vMid];
  1256.       const GLfloat *pMax = VB->Win.data[vMax];
  1257.       const GLfloat dxdy = majDx / majDy;
  1258.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1259.       GLfloat x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1260.       GLint iy;
  1261.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1262.          GLint ix, left, startX = (GLint) (x + xAdj);
  1263.          GLuint count, n;
  1264.          GLfloat coverage=0.f;
  1265.          /* skip fragments with zero coverage */
  1266.          while (startX >= 0) {
  1267.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1268.             if (coverage > 0.0F)
  1269.                break;
  1270.             startX--;
  1271.          }
  1272.  
  1273.          /* enter interior of triangle */
  1274.          ix = startX;
  1275.          count = 0;
  1276.          while (coverage > 0.0F) {
  1277.             z[ix] = (GLdepth) solve_plane(ix, iy, zPlane);
  1278.             rgba[ix][0] = solve_plane_0_255(ix, iy, rPlane);
  1279.             rgba[ix][1] = solve_plane_0_255(ix, iy, gPlane);
  1280.             rgba[ix][2] = solve_plane_0_255(ix, iy, bPlane);
  1281.             rgba[ix][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1282.             spec[ix][0] = solve_plane_0_255(ix, iy, srPlane);
  1283.             spec[ix][1] = solve_plane_0_255(ix, iy, sgPlane);
  1284.             spec[ix][2] = solve_plane_0_255(ix, iy, sbPlane);
  1285.             {
  1286.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1287.                s[0][ix] = solve_plane(ix, iy, s0Plane) * invQ;
  1288.                t[0][ix] = solve_plane(ix, iy, t0Plane) * invQ;
  1289.                u[0][ix] = solve_plane(ix, iy, u0Plane) * invQ;
  1290.                lambda[0][ix] = compute_lambda(s0Plane, t0Plane, invQ,
  1291.                                               width0, height0);
  1292.             }
  1293.             ix--;
  1294.             count++;
  1295.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1296.          }
  1297.  
  1298.          n = (GLuint) startX - (GLuint) ix;
  1299.          left = ix + 1;
  1300.          gl_write_texture_span(ctx, n, left, iy, z + left,
  1301.                                s[0] + left, t[0] + left, u[0] + left,
  1302.                                lambda[0] + left, rgba + left,
  1303.                                (const GLubyte (*)[4]) (spec + left),
  1304.                                GL_POLYGON);
  1305.       }
  1306.    }
  1307. }
  1308.  
  1309.  
  1310. //#define DO_Z
  1311. //#define DO_RGBA
  1312. //#define DO_STUV0
  1313. //#define DO_STUV1
  1314.  
  1315. static void
  1316. multitex_aa_tri(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
  1317. {
  1318.    const struct vertex_buffer *VB = ctx->VB;
  1319.    const GLfloat *p0 = VB->Win.data[v0];
  1320.    const GLfloat *p1 = VB->Win.data[v1];
  1321.    const GLfloat *p2 = VB->Win.data[v2];
  1322.    GLint vMin, vMid, vMax;
  1323.    GLint iyMin, iyMax;
  1324.    GLfloat yMin, yMax;
  1325.    GLboolean ltor;
  1326.    GLfloat majDx, majDy;
  1327.    GLfloat zPlane[4];                                       /* Z (depth) */
  1328.    GLdepth z[MAX_WIDTH];
  1329.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];      /* color */
  1330.    GLubyte rgba[MAX_WIDTH][4];
  1331.    GLfloat s0Plane[4], t0Plane[4], u0Plane[4], v0Plane[4];  /* texture 0 */
  1332.    GLfloat width0, height0;
  1333.    GLfloat s[2][MAX_WIDTH];
  1334.    GLfloat t[2][MAX_WIDTH];
  1335.    GLfloat u[2][MAX_WIDTH];
  1336.    GLfloat lambda[2][MAX_WIDTH];
  1337.    GLfloat s1Plane[4], t1Plane[4], u1Plane[4], v1Plane[4];  /* texture 1 */
  1338.    GLfloat width1, height1;
  1339.    GLfloat bf = ctx->backface_sign;
  1340.  
  1341.    /* determine bottom to top order of vertices */
  1342.    {
  1343.       GLfloat y0 = VB->Win.data[v0][1];
  1344.       GLfloat y1 = VB->Win.data[v1][1];
  1345.       GLfloat y2 = VB->Win.data[v2][1];
  1346.       if (y0 <= y1) {
  1347.         if (y1 <= y2) {
  1348.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  1349.         }
  1350.         else if (y2 <= y0) {
  1351.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  1352.         }
  1353.         else {
  1354.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  1355.         }
  1356.       }
  1357.       else {
  1358.         if (y0 <= y2) {
  1359.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  1360.         }
  1361.         else if (y2 <= y1) {
  1362.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  1363.         }
  1364.         else {
  1365.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  1366.         }
  1367.       }
  1368.    }
  1369.  
  1370.    majDx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  1371.    majDy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  1372.  
  1373.    {
  1374.       const GLfloat botDx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  1375.       const GLfloat botDy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  1376.       const GLfloat area = majDx * botDy - botDx * majDy;
  1377.       ltor = (GLboolean) (area < 0.0F);
  1378.       /* Do backface culling */
  1379.       if (area * bf < 0 || area * area < .0025)
  1380.         return;
  1381.    }
  1382.  
  1383. #ifndef DO_OCCLUSION_TEST
  1384.    ctx->OcclusionResult = GL_TRUE;
  1385. #endif
  1386.  
  1387.    /* plane setup */
  1388.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1389.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  1390.       GLubyte (*rgba)[4] = VB->ColorPtr->data;
  1391.       compute_plane(p0, p1, p2, rgba[v0][0], rgba[v1][0], rgba[v2][0], rPlane);
  1392.       compute_plane(p0, p1, p2, rgba[v0][1], rgba[v1][1], rgba[v2][1], gPlane);
  1393.       compute_plane(p0, p1, p2, rgba[v0][2], rgba[v1][2], rgba[v2][2], bPlane);
  1394.       compute_plane(p0, p1, p2, rgba[v0][3], rgba[v1][3], rgba[v2][3], aPlane);
  1395.    }
  1396.    else {
  1397.       constant_plane(VB->ColorPtr->data[pv][0], rPlane);
  1398.       constant_plane(VB->ColorPtr->data[pv][1], gPlane);
  1399.       constant_plane(VB->ColorPtr->data[pv][2], bPlane);
  1400.       constant_plane(VB->ColorPtr->data[pv][3], aPlane);
  1401.    }
  1402.    {
  1403.       const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;
  1404.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1405.       const GLint tSize = 3;
  1406.       const GLfloat invW0 = VB->Win.data[v0][3];
  1407.       const GLfloat invW1 = VB->Win.data[v1][3];
  1408.       const GLfloat invW2 = VB->Win.data[v2][3];
  1409.       GLfloat (*texCoord)[4] = VB->TexCoordPtr[0]->data;
  1410.       const GLfloat s0 = texCoord[v0][0] * invW0;
  1411.       const GLfloat s1 = texCoord[v1][0] * invW1;
  1412.       const GLfloat s2 = texCoord[v2][0] * invW2;
  1413.       const GLfloat t0 = (tSize > 1) ? texCoord[v0][1] * invW0 : 0.0F;
  1414.       const GLfloat t1 = (tSize > 1) ? texCoord[v1][1] * invW1 : 0.0F;
  1415.       const GLfloat t2 = (tSize > 1) ? texCoord[v2][1] * invW2 : 0.0F;
  1416.       const GLfloat r0 = (tSize > 2) ? texCoord[v0][2] * invW0 : 0.0F;
  1417.       const GLfloat r1 = (tSize > 2) ? texCoord[v1][2] * invW1 : 0.0F;
  1418.       const GLfloat r2 = (tSize > 2) ? texCoord[v2][2] * invW2 : 0.0F;
  1419.       const GLfloat q0 = (tSize > 3) ? texCoord[v0][3] * invW0 : invW0;
  1420.       const GLfloat q1 = (tSize > 3) ? texCoord[v1][3] * invW1 : invW1;
  1421.       const GLfloat q2 = (tSize > 3) ? texCoord[v2][3] * invW2 : invW2;
  1422.       compute_plane(p0, p1, p2, s0, s1, s2, s0Plane);
  1423.       compute_plane(p0, p1, p2, t0, t1, t2, t0Plane);
  1424.       compute_plane(p0, p1, p2, r0, r1, r2, u0Plane);
  1425.       compute_plane(p0, p1, p2, q0, q1, q2, v0Plane);
  1426.       width0 = (GLfloat) texImage->Width;
  1427.       height0 = (GLfloat) texImage->Height;
  1428.    }
  1429.    {
  1430.       const struct gl_texture_object *obj = ctx->Texture.Unit[1].Current;
  1431.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1432.       const GLint tSize = VB->TexCoordPtr[1]->size;
  1433.       const GLfloat invW0 = VB->Win.data[v0][3];
  1434.       const GLfloat invW1 = VB->Win.data[v1][3];
  1435.       const GLfloat invW2 = VB->Win.data[v2][3];
  1436.       GLfloat (*texCoord)[4] = VB->TexCoordPtr[1]->data;
  1437.       const GLfloat s0 = texCoord[v0][0] * invW0;
  1438.       const GLfloat s1 = texCoord[v1][0] * invW1;
  1439.       const GLfloat s2 = texCoord[v2][0] * invW2;
  1440.       const GLfloat t0 = (tSize > 1) ? texCoord[v0][1] * invW0 : 0.0F;
  1441.       const GLfloat t1 = (tSize > 1) ? texCoord[v1][1] * invW1 : 0.0F;
  1442.       const GLfloat t2 = (tSize > 1) ? texCoord[v2][1] * invW2 : 0.0F;
  1443.       const GLfloat r0 = (tSize > 2) ? texCoord[v0][2] * invW0 : 0.0F;
  1444.       const GLfloat r1 = (tSize > 2) ? texCoord[v1][2] * invW1 : 0.0F;
  1445.       const GLfloat r2 = (tSize > 2) ? texCoord[v2][2] * invW2 : 0.0F;
  1446.       const GLfloat q0 = (tSize > 3) ? texCoord[v0][3] * invW0 : invW0;
  1447.       const GLfloat q1 = (tSize > 3) ? texCoord[v1][3] * invW1 : invW1;
  1448.       const GLfloat q2 = (tSize > 3) ? texCoord[v2][3] * invW2 : invW2;
  1449.       compute_plane(p0, p1, p2, s0, s1, s2, s1Plane);
  1450.       compute_plane(p0, p1, p2, t0, t1, t2, t1Plane);
  1451.       compute_plane(p0, p1, p2, r0, r1, r2, u1Plane);
  1452.       compute_plane(p0, p1, p2, q0, q1, q2, v1Plane);
  1453.       width1 = (GLfloat) texImage->Width;
  1454.       height1 = (GLfloat) texImage->Height;
  1455.    }
  1456.  
  1457.    yMin = VB->Win.data[vMin][1];
  1458.    yMax = VB->Win.data[vMax][1];
  1459.    iyMin = (int) yMin;
  1460.    iyMax = (int) yMax + 1;
  1461.  
  1462.    if (ltor) {
  1463.       /* scan left to right */
  1464.       const float *pMin = VB->Win.data[vMin];
  1465.       const float *pMid = VB->Win.data[vMid];
  1466.       const float *pMax = VB->Win.data[vMax];
  1467.       const float dxdy = majDx / majDy;
  1468.       const float xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1469.       float x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1470.       int iy;
  1471.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1472.          GLint ix, startX = (GLint) (x - xAdj);
  1473.          GLuint count, n;
  1474.          GLfloat coverage=0.f;
  1475.          /* skip over fragments with zero coverage */
  1476.          while (startX < MAX_WIDTH) {
  1477.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1478.             if (coverage > 0.0F)
  1479.                break;
  1480.             startX++;
  1481.          }
  1482.  
  1483.          /* enter interior of triangle */
  1484.          ix = startX;
  1485.          count = 0;
  1486.          while (coverage > 0.0F) {
  1487.             z[count] = (GLdepth) solve_plane(ix, iy, zPlane);
  1488.             rgba[count][0] = solve_plane_0_255(ix, iy, rPlane);
  1489.             rgba[count][1] = solve_plane_0_255(ix, iy, gPlane);
  1490.             rgba[count][2] = solve_plane_0_255(ix, iy, bPlane);
  1491.             rgba[count][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1492.             {
  1493.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1494.                s[0][count] = solve_plane(ix, iy, s0Plane) * invQ;
  1495.                t[0][count] = solve_plane(ix, iy, t0Plane) * invQ;
  1496.                u[0][count] = solve_plane(ix, iy, u0Plane) * invQ;
  1497.                lambda[0][count] = compute_lambda(s0Plane, t0Plane, invQ,
  1498.                                                  width0, height0);
  1499.             }
  1500.             {
  1501.                GLfloat invQ = solve_plane_recip(ix, iy, v1Plane);
  1502.                s[1][count] = solve_plane(ix, iy, s1Plane) * invQ;
  1503.                t[1][count] = solve_plane(ix, iy, t1Plane) * invQ;
  1504.                u[1][count] = solve_plane(ix, iy, u1Plane) * invQ;
  1505.                lambda[1][count] = compute_lambda(s1Plane, t1Plane, invQ,
  1506.                                                  width1, height1);
  1507.             }
  1508.             ix++;
  1509.             count++;
  1510.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1511.          }
  1512.  
  1513.          n = (GLuint) ix - (GLuint) startX;
  1514.          gl_write_multitexture_span(ctx, 2, n, startX, iy, z,
  1515.                                     (const GLfloat (*)[MAX_WIDTH]) s,
  1516.                                     (const GLfloat (*)[MAX_WIDTH]) t,
  1517.                                     (const GLfloat (*)[MAX_WIDTH]) u,
  1518.                                     lambda, rgba, 0, GL_POLYGON);
  1519.       }
  1520.    }
  1521.    else {
  1522.       /* scan right to left */
  1523.       const GLfloat *pMin = VB->Win.data[vMin];
  1524.       const GLfloat *pMid = VB->Win.data[vMid];
  1525.       const GLfloat *pMax = VB->Win.data[vMax];
  1526.       const GLfloat dxdy = majDx / majDy;
  1527.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1528.       GLfloat x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1529.       GLint iy;
  1530.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1531.          GLint ix, left, startX = (GLint) (x + xAdj);
  1532.          GLuint count, n;
  1533.          GLfloat coverage=0.f;
  1534.          /* skip fragments with zero coverage */
  1535.          while (startX >= 0) {
  1536.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1537.             if (coverage > 0.0F)
  1538.                break;
  1539.             startX--;
  1540.          }
  1541.  
  1542.          /* enter interior of triangle */
  1543.          ix = startX;
  1544.          count = 0;
  1545.          while (coverage > 0.0F) {
  1546.             z[ix] = (GLdepth) solve_plane(ix, iy, zPlane);
  1547.             rgba[ix][0] = solve_plane_0_255(ix, iy, rPlane);
  1548.             rgba[ix][1] = solve_plane_0_255(ix, iy, gPlane);
  1549.             rgba[ix][2] = solve_plane_0_255(ix, iy, bPlane);
  1550.             rgba[ix][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1551.             {
  1552.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1553.                s[0][ix] = solve_plane(ix, iy, s0Plane) * invQ;
  1554.                t[0][ix] = solve_plane(ix, iy, t0Plane) * invQ;
  1555.                u[0][ix] = solve_plane(ix, iy, u0Plane) * invQ;
  1556.                lambda[0][ix] = compute_lambda(s0Plane, t0Plane, invQ,
  1557.                                               width0, height0);
  1558.             }
  1559.             {
  1560.                GLfloat invQ = solve_plane_recip(ix, iy, v1Plane);
  1561.                s[1][ix] = solve_plane(ix, iy, s1Plane) * invQ;
  1562.                t[1][ix] = solve_plane(ix, iy, t1Plane) * invQ;
  1563.                u[1][ix] = solve_plane(ix, iy, u1Plane) * invQ;
  1564.                lambda[1][ix] = compute_lambda(s1Plane, t1Plane, invQ,
  1565.                                               width1, height1);
  1566.             }
  1567.             ix--;
  1568.             count++;
  1569.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1570.          }
  1571.  
  1572.          n = (GLuint) startX - (GLuint) ix;
  1573.          left = ix + 1;
  1574.          {
  1575.             int j;
  1576.             for (j = 0; j < n; j++) {
  1577.                s[0][j] = s[0][j + left];
  1578.                t[0][j] = t[0][j + left];
  1579.                u[0][j] = u[0][j + left];
  1580.                s[1][j] = s[1][j + left];
  1581.                t[1][j] = t[1][j + left];
  1582.                u[1][j] = u[1][j + left];
  1583.                lambda[0][j] = lambda[0][j + left];
  1584.                lambda[1][j] = lambda[1][j + left];
  1585.             }
  1586.          }
  1587.          gl_write_multitexture_span(ctx, 2, n, left, iy, z + left,
  1588.                                     (const GLfloat (*)[MAX_WIDTH]) s,
  1589.                                     (const GLfloat (*)[MAX_WIDTH]) t,
  1590.                                     (const GLfloat (*)[MAX_WIDTH]) u,
  1591.                                     lambda,
  1592.                                     rgba + left, 0, GL_POLYGON);
  1593.       }
  1594.    }
  1595. }
  1596.  
  1597.  
  1598. //#define DO_Z       compute Z values
  1599. //#define DO_RGBA    compute RGBA values
  1600. //#define DO_STUV0   compute unit 0 STRQ texcoords
  1601. //#define DO_STUV1   compute unit 1 STRQ texcoords
  1602. //#define DO_SPEC    compute specular RGB values
  1603.  
  1604.  
  1605. static void
  1606. spec_multitex_aa_tri(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv)
  1607. {
  1608.    const struct vertex_buffer *VB = ctx->VB;
  1609.    const GLfloat *p0 = VB->Win.data[v0];
  1610.    const GLfloat *p1 = VB->Win.data[v1];
  1611.    const GLfloat *p2 = VB->Win.data[v2];
  1612.    GLint vMin, vMid, vMax;
  1613.    GLint iyMin, iyMax;
  1614.    GLfloat yMin, yMax;
  1615.    GLboolean ltor;
  1616.    GLfloat majDx, majDy;
  1617.    GLfloat zPlane[4];                                       /* Z (depth) */
  1618.    GLdepth z[MAX_WIDTH];
  1619.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];      /* color */
  1620.    GLubyte rgba[MAX_WIDTH][4];
  1621.    GLfloat srPlane[4], sgPlane[4], sbPlane[4];              /* spec color */
  1622.    GLubyte spec[MAX_WIDTH][4];
  1623.    GLfloat s0Plane[4], t0Plane[4], u0Plane[4], v0Plane[4];  /* texture 0 */
  1624.    GLfloat width0, height0;
  1625.    GLfloat s[2][MAX_WIDTH];
  1626.    GLfloat t[2][MAX_WIDTH];
  1627.    GLfloat u[2][MAX_WIDTH];
  1628.    GLfloat lambda[2][MAX_WIDTH];
  1629.    GLfloat s1Plane[4], t1Plane[4], u1Plane[4], v1Plane[4];  /* texture 1 */
  1630.    GLfloat width1, height1;
  1631.    GLfloat bf = ctx->backface_sign;
  1632.  
  1633.    /* determine bottom to top order of vertices */
  1634.    {
  1635.       GLfloat y0 = VB->Win.data[v0][1];
  1636.       GLfloat y1 = VB->Win.data[v1][1];
  1637.       GLfloat y2 = VB->Win.data[v2][1];
  1638.       if (y0 <= y1) {
  1639.         if (y1 <= y2) {
  1640.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  1641.         }
  1642.         else if (y2 <= y0) {
  1643.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  1644.         }
  1645.         else {
  1646.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  1647.         }
  1648.       }
  1649.       else {
  1650.         if (y0 <= y2) {
  1651.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  1652.         }
  1653.         else if (y2 <= y1) {
  1654.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  1655.         }
  1656.         else {
  1657.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  1658.         }
  1659.       }
  1660.    }
  1661.  
  1662.    majDx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
  1663.    majDy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
  1664.  
  1665.    {
  1666.       const GLfloat botDx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
  1667.       const GLfloat botDy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
  1668.       const GLfloat area = majDx * botDy - botDx * majDy;
  1669.       ltor = (GLboolean) (area < 0.0F);
  1670.       /* Do backface culling */
  1671.       if (area * bf < 0 || area * area < .0025)
  1672.         return;
  1673.    }
  1674.  
  1675. #ifndef DO_OCCLUSION_TEST
  1676.    ctx->OcclusionResult = GL_TRUE;
  1677. #endif
  1678.  
  1679.    /* plane setup */
  1680.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1681.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  1682.       GLubyte (*rgba)[4] = VB->ColorPtr->data;
  1683.       compute_plane(p0, p1, p2, rgba[v0][0], rgba[v1][0], rgba[v2][0], rPlane);
  1684.       compute_plane(p0, p1, p2, rgba[v0][1], rgba[v1][1], rgba[v2][1], gPlane);
  1685.       compute_plane(p0, p1, p2, rgba[v0][2], rgba[v1][2], rgba[v2][2], bPlane);
  1686.       compute_plane(p0, p1, p2, rgba[v0][3], rgba[v1][3], rgba[v2][3], aPlane);
  1687.    }
  1688.    else {
  1689.       constant_plane(VB->ColorPtr->data[pv][0], rPlane);
  1690.       constant_plane(VB->ColorPtr->data[pv][1], gPlane);
  1691.       constant_plane(VB->ColorPtr->data[pv][2], bPlane);
  1692.       constant_plane(VB->ColorPtr->data[pv][3], aPlane);
  1693.    }
  1694.    {
  1695.       GLubyte (*spec)[4] = VB->Specular;
  1696.       compute_plane(p0, p1, p2, spec[v0][0], spec[v1][0], spec[v2][0],srPlane);
  1697.       compute_plane(p0, p1, p2, spec[v0][1], spec[v1][1], spec[v2][1],sgPlane);
  1698.       compute_plane(p0, p1, p2, spec[v0][2], spec[v1][2], spec[v2][2],sbPlane);
  1699.    }
  1700.    {
  1701.       const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;
  1702.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1703.       const GLint tSize = 3;
  1704.       const GLfloat invW0 = VB->Win.data[v0][3];
  1705.       const GLfloat invW1 = VB->Win.data[v1][3];
  1706.       const GLfloat invW2 = VB->Win.data[v2][3];
  1707.       GLfloat (*texCoord)[4] = VB->TexCoordPtr[0]->data;
  1708.       const GLfloat s0 = texCoord[v0][0] * invW0;
  1709.       const GLfloat s1 = texCoord[v1][0] * invW1;
  1710.       const GLfloat s2 = texCoord[v2][0] * invW2;
  1711.       const GLfloat t0 = (tSize > 1) ? texCoord[v0][1] * invW0 : 0.0F;
  1712.       const GLfloat t1 = (tSize > 1) ? texCoord[v1][1] * invW1 : 0.0F;
  1713.       const GLfloat t2 = (tSize > 1) ? texCoord[v2][1] * invW2 : 0.0F;
  1714.       const GLfloat r0 = (tSize > 2) ? texCoord[v0][2] * invW0 : 0.0F;
  1715.       const GLfloat r1 = (tSize > 2) ? texCoord[v1][2] * invW1 : 0.0F;
  1716.       const GLfloat r2 = (tSize > 2) ? texCoord[v2][2] * invW2 : 0.0F;
  1717.       const GLfloat q0 = (tSize > 3) ? texCoord[v0][3] * invW0 : invW0;
  1718.       const GLfloat q1 = (tSize > 3) ? texCoord[v1][3] * invW1 : invW1;
  1719.       const GLfloat q2 = (tSize > 3) ? texCoord[v2][3] * invW2 : invW2;
  1720.       compute_plane(p0, p1, p2, s0, s1, s2, s0Plane);
  1721.       compute_plane(p0, p1, p2, t0, t1, t2, t0Plane);
  1722.       compute_plane(p0, p1, p2, r0, r1, r2, u0Plane);
  1723.       compute_plane(p0, p1, p2, q0, q1, q2, v0Plane);
  1724.       width0 = (GLfloat) texImage->Width;
  1725.       height0 = (GLfloat) texImage->Height;
  1726.    }
  1727.    {
  1728.       const struct gl_texture_object *obj = ctx->Texture.Unit[1].Current;
  1729.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1730.       const GLint tSize = VB->TexCoordPtr[1]->size;
  1731.       const GLfloat invW0 = VB->Win.data[v0][3];
  1732.       const GLfloat invW1 = VB->Win.data[v1][3];
  1733.       const GLfloat invW2 = VB->Win.data[v2][3];
  1734.       GLfloat (*texCoord)[4] = VB->TexCoordPtr[1]->data;
  1735.       const GLfloat s0 = texCoord[v0][0] * invW0;
  1736.       const GLfloat s1 = texCoord[v1][0] * invW1;
  1737.       const GLfloat s2 = texCoord[v2][0] * invW2;
  1738.       const GLfloat t0 = (tSize > 1) ? texCoord[v0][1] * invW0 : 0.0F;
  1739.       const GLfloat t1 = (tSize > 1) ? texCoord[v1][1] * invW1 : 0.0F;
  1740.       const GLfloat t2 = (tSize > 1) ? texCoord[v2][1] * invW2 : 0.0F;
  1741.       const GLfloat r0 = (tSize > 2) ? texCoord[v0][2] * invW0 : 0.0F;
  1742.       const GLfloat r1 = (tSize > 2) ? texCoord[v1][2] * invW1 : 0.0F;
  1743.       const GLfloat r2 = (tSize > 2) ? texCoord[v2][2] * invW2 : 0.0F;
  1744.       const GLfloat q0 = (tSize > 3) ? texCoord[v0][3] * invW0 : invW0;
  1745.       const GLfloat q1 = (tSize > 3) ? texCoord[v1][3] * invW1 : invW1;
  1746.       const GLfloat q2 = (tSize > 3) ? texCoord[v2][3] * invW2 : invW2;
  1747.       compute_plane(p0, p1, p2, s0, s1, s2, s1Plane);
  1748.       compute_plane(p0, p1, p2, t0, t1, t2, t1Plane);
  1749.       compute_plane(p0, p1, p2, r0, r1, r2, u1Plane);
  1750.       compute_plane(p0, p1, p2, q0, q1, q2, v1Plane);
  1751.       width1 = (GLfloat) texImage->Width;
  1752.       height1 = (GLfloat) texImage->Height;
  1753.    }
  1754.  
  1755.    yMin = VB->Win.data[vMin][1];
  1756.    yMax = VB->Win.data[vMax][1];
  1757.    iyMin = (int) yMin;
  1758.    iyMax = (int) yMax + 1;
  1759.  
  1760.    if (ltor) {
  1761.       /* scan left to right */
  1762.       const float *pMin = VB->Win.data[vMin];
  1763.       const float *pMid = VB->Win.data[vMid];
  1764.       const float *pMax = VB->Win.data[vMax];
  1765.       const float dxdy = majDx / majDy;
  1766.       const float xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1767.       float x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1768.       int iy;
  1769.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1770.          GLint ix, startX = (GLint) (x - xAdj);
  1771.          GLuint count, n;
  1772.          GLfloat coverage=0.f;
  1773.          /* skip over fragments with zero coverage */
  1774.          while (startX < MAX_WIDTH) {
  1775.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1776.             if (coverage > 0.0F)
  1777.                break;
  1778.             startX++;
  1779.          }
  1780.  
  1781.          /* enter interior of triangle */
  1782.          ix = startX;
  1783.          count = 0;
  1784.          while (coverage > 0.0F) {
  1785.             z[count] = (GLdepth) solve_plane(ix, iy, zPlane);
  1786.             rgba[count][0] = solve_plane_0_255(ix, iy, rPlane);
  1787.             rgba[count][1] = solve_plane_0_255(ix, iy, gPlane);
  1788.             rgba[count][2] = solve_plane_0_255(ix, iy, bPlane);
  1789.             rgba[count][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1790.             spec[count][0] = solve_plane_0_255(ix, iy, srPlane);
  1791.             spec[count][1] = solve_plane_0_255(ix, iy, sgPlane);
  1792.             spec[count][2] = solve_plane_0_255(ix, iy, sbPlane);
  1793.             {
  1794.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1795.                s[0][count] = solve_plane(ix, iy, s0Plane) * invQ;
  1796.                t[0][count] = solve_plane(ix, iy, t0Plane) * invQ;
  1797.                u[0][count] = solve_plane(ix, iy, u0Plane) * invQ;
  1798.                lambda[0][count] = compute_lambda(s0Plane, t0Plane, invQ,
  1799.                                                  width0, height0);
  1800.             }
  1801.             {
  1802.                GLfloat invQ = solve_plane_recip(ix, iy, v1Plane);
  1803.                s[1][count] = solve_plane(ix, iy, s1Plane) * invQ;
  1804.                t[1][count] = solve_plane(ix, iy, t1Plane) * invQ;
  1805.                u[1][count] = solve_plane(ix, iy, u1Plane) * invQ;
  1806.                lambda[1][count] = compute_lambda(s1Plane, t1Plane, invQ,
  1807.                                                  width1, height1);
  1808.             }
  1809.             ix++;
  1810.             count++;
  1811.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1812.          }
  1813.  
  1814.          n = (GLuint) ix - (GLuint) startX;
  1815.          gl_write_multitexture_span(ctx, 2, n, startX, iy, z,
  1816.                                     (const GLfloat (*)[MAX_WIDTH]) s,
  1817.                                     (const GLfloat (*)[MAX_WIDTH]) t,
  1818.                                     (const GLfloat (*)[MAX_WIDTH]) u,
  1819.                                     (GLfloat (*)[MAX_WIDTH]) lambda,
  1820.                                     rgba, (const GLubyte (*)[4]) spec,
  1821.                                     GL_POLYGON);
  1822.       }
  1823.    }
  1824.    else {
  1825.       /* scan right to left */
  1826.       const GLfloat *pMin = VB->Win.data[vMin];
  1827.       const GLfloat *pMid = VB->Win.data[vMid];
  1828.       const GLfloat *pMax = VB->Win.data[vMax];
  1829.       const GLfloat dxdy = majDx / majDy;
  1830.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1831.       GLfloat x = VB->Win.data[vMin][0] - (yMin - iyMin) * dxdy;
  1832.       GLint iy;
  1833.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1834.          GLint ix, left, startX = (GLint) (x + xAdj);
  1835.          GLuint count, n;
  1836.          GLfloat coverage=0.f;
  1837.          /* skip fragments with zero coverage */
  1838.          while (startX >= 0) {
  1839.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1840.             if (coverage > 0.0F)
  1841.                break;
  1842.             startX--;
  1843.          }
  1844.  
  1845.          /* enter interior of triangle */
  1846.          ix = startX;
  1847.          count = 0;
  1848.          while (coverage > 0.0F) {
  1849.             z[ix] = (GLdepth) solve_plane(ix, iy, zPlane);
  1850.             rgba[ix][0] = solve_plane_0_255(ix, iy, rPlane);
  1851.             rgba[ix][1] = solve_plane_0_255(ix, iy, gPlane);
  1852.             rgba[ix][2] = solve_plane_0_255(ix, iy, bPlane);
  1853.             rgba[ix][3] = solve_plane_0_255(ix, iy, aPlane) * coverage;
  1854.             spec[ix][0] = solve_plane_0_255(ix, iy, srPlane);
  1855.             spec[ix][1] = solve_plane_0_255(ix, iy, sgPlane);
  1856.             spec[ix][2] = solve_plane_0_255(ix, iy, sbPlane);
  1857.             {
  1858.                GLfloat invQ = solve_plane_recip(ix, iy, v0Plane);
  1859.                s[0][ix] = solve_plane(ix, iy, s0Plane) * invQ;
  1860.                t[0][ix] = solve_plane(ix, iy, t0Plane) * invQ;
  1861.                u[0][ix] = solve_plane(ix, iy, u0Plane) * invQ;
  1862.                lambda[0][ix] = compute_lambda(s0Plane, t0Plane, invQ,
  1863.                                               width0, height0);
  1864.             }
  1865.             {
  1866.                GLfloat invQ = solve_plane_recip(ix, iy, v1Plane);
  1867.                s[1][ix] = solve_plane(ix, iy, s1Plane) * invQ;
  1868.                t[1][ix] = solve_plane(ix, iy, t1Plane) * invQ;
  1869.                u[1][ix] = solve_plane(ix, iy, u1Plane) * invQ;
  1870.                lambda[1][ix] = compute_lambda(s1Plane, t1Plane, invQ,
  1871.                                               width1, height1);
  1872.             }
  1873.             ix--;
  1874.             count++;
  1875.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1876.          }
  1877.  
  1878.          n = (GLuint) startX - (GLuint) ix;
  1879.          left = ix + 1;
  1880.          {
  1881.             int j;
  1882.             for (j = 0; j < n; j++) {
  1883.                s[0][j] = s[0][j + left];
  1884.                t[0][j] = t[0][j + left];
  1885.                u[0][j] = u[0][j + left];
  1886.                s[1][j] = s[1][j + left];
  1887.                t[1][j] = t[1][j + left];
  1888.                u[1][j] = u[1][j + left];
  1889.                lambda[0][j] = lambda[0][j + left];
  1890.                lambda[1][j] = lambda[1][j + left];
  1891.             }
  1892.          }
  1893.          gl_write_multitexture_span(ctx, 2, n, left, iy, z + left,
  1894.                                     (const GLfloat (*)[MAX_WIDTH]) s,
  1895.                                     (const GLfloat (*)[MAX_WIDTH]) t,
  1896.                                     (const GLfloat (*)[MAX_WIDTH]) u,
  1897.                                     lambda, rgba + left,
  1898.                                     (const GLubyte (*)[4]) (spec + left),
  1899.                                     GL_POLYGON);
  1900.       }
  1901.    }
  1902. }
  1903.  
  1904.  
  1905.  
  1906. /*
  1907.  * Examine GL state and set ctx->Driver.TriangleFunc to an
  1908.  * appropriate antialiased triangle rasterizer function.
  1909.  */
  1910. void
  1911. _mesa_set_aa_triangle_function(GLcontext *ctx)
  1912. {
  1913.    ;
  1914.    if (ctx->Texture.ReallyEnabled) {
  1915.       if (ctx->Light.Enabled &&
  1916.           ctx->Light.Model.ColorControl==0x81FA) {
  1917.          if (ctx->Texture.ReallyEnabled >= (1<<4)) {
  1918.             ctx->Driver.TriangleFunc = spec_multitex_aa_tri;
  1919.          }
  1920.          else {
  1921.             ctx->Driver.TriangleFunc = spec_tex_aa_tri;
  1922.          }
  1923.       }
  1924.       else {
  1925.          if (ctx->Texture.ReallyEnabled >= (1<<4)) {
  1926.             ctx->Driver.TriangleFunc = multitex_aa_tri;
  1927.          }
  1928.          else {
  1929.             ctx->Driver.TriangleFunc = tex_aa_tri;
  1930.          }
  1931.       }
  1932.    }
  1933.    else {
  1934.       if (ctx->Visual->RGBAflag) {
  1935.          ctx->Driver.TriangleFunc = rgba_aa_tri;
  1936.       }
  1937.       else {
  1938.          ctx->Driver.TriangleFunc = index_aa_tri;
  1939.       }
  1940.    }
  1941.    ;
  1942. }
  1943.