home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / AATRIANGLE / s_aatriangle_1.cpp < prev   
C/C++ Source or Header  |  2002-12-12  |  19KB  |  592 lines

  1. /* $Id: s_aatriangle_1.c,v 1.26 2002/10/24 23:57:24 brianp Exp $ */
  2. #include "glheader.h"
  3. #include "macros.h"
  4. #include "imports.h"
  5. #include "mmath.h"
  6. #include "s_aatriangle.h"
  7. #include "s_context.h"
  8. #include "s_span.h"
  9.  
  10. /****************************/
  11. #define FIST_MAGIC ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))
  12.  
  13. /*
  14.  * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
  15.  * vertices and the given Z values.
  16.  * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
  17.  */
  18. static   void INLINE
  19. compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
  20.               GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4])
  21. {
  22.    const GLfloat px = v1[0] - v0[0];
  23.    const GLfloat py = v1[1] - v0[1];
  24.    const GLfloat pz = z1 - z0;
  25.  
  26.    const GLfloat qx = v2[0] - v0[0];
  27.    const GLfloat qy = v2[1] - v0[1];
  28.    const GLfloat qz = z2 - z0;
  29.  
  30.    /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
  31.    const GLfloat a = py * qz - pz * qy;
  32.    const GLfloat b = pz * qx - px * qz;
  33.    const GLfloat c = px * qy - py * qx;
  34.    /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
  35.       on the distance of plane from origin and arbitrary "w" parallel
  36.       to the plane. */
  37.    /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
  38.       which is equal to "-d" below. */
  39.    const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
  40.  
  41.    plane[0] = a;
  42.    plane[1] = b;
  43.    plane[2] = c;
  44.    plane[3] = d;
  45. }
  46.  
  47.  
  48. /*
  49.  * Compute coefficients of a plane with a constant Z value.
  50.  */
  51. static void INLINE
  52. constant_plane(GLfloat value, GLfloat plane[4])
  53. {
  54.    plane[0] = 0.0;
  55.    plane[1] = 0.0;
  56.    plane[2] = -1.0;
  57.    plane[3] = value;
  58. }
  59.  
  60.  
  61. /*
  62.  * Solve plane equation for Z at (X,Y).
  63.  */
  64. static  GLfloat INLINE
  65. solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
  66. {
  67.    return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
  68. }
  69.  
  70. /*
  71.  * Solve plane and return clamped GLchan value.
  72.  */
  73. static  GLchan INLINE
  74. solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
  75. {
  76.    GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F;
  77.    if (z < 0.0F)
  78.       return 0;
  79.    else if (z > 255.0F)
  80.       return (GLchan) 255.0F;
  81.    return (GLchan) (GLint) z;
  82. }
  83.  
  84. static  GLfloat
  85. AAA_compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
  86.                   const GLfloat v2[3], GLint winx, GLint winy)
  87. {
  88.    static const GLfloat samples[16][2] = {
  89.       /* start with the four corners */
  90.       { (0.5+0*4+2)/16, (0.5+0*4+0)/16 },
  91.       { (0.5+3*4+3)/16, (0.5+0*4+2)/16 },
  92.       { (0.5+0*4+0)/16, (0.5+3*4+1)/16 },
  93.       { (0.5+3*4+1)/16, (0.5+3*4+3)/16 },
  94.       /* continue with interior samples */
  95.       { (0.5+1*4+1)/16, (0.5+0*4+1)/16 },
  96.       { (0.5+2*4+0)/16, (0.5+0*4+3)/16 },
  97.       { (0.5+0*4+3)/16, (0.5+1*4+3)/16 },
  98.       { (0.5+1*4+2)/16, (0.5+1*4+0)/16 },
  99.       { (0.5+2*4+3)/16, (0.5+1*4+2)/16 },
  100.       { (0.5+3*4+2)/16, (0.5+1*4+1)/16 },
  101.       { (0.5+0*4+1)/16, (0.5+2*4+2)/16 },
  102.       { (0.5+1*4+0)/16, (0.5+2*4+1)/16 },
  103.       { (0.5+2*4+1)/16, (0.5+2*4+3)/16 },
  104.       { (0.5+3*4+0)/16, (0.5+2*4+0)/16 },
  105.       { (0.5+1*4+3)/16, (0.5+3*4+0)/16 },
  106.       { (0.5+2*4+2)/16, (0.5+3*4+2)/16 }
  107.    };
  108.  
  109.    const GLfloat x = (GLfloat) winx;
  110.    const GLfloat y = (GLfloat) winy;
  111.    const GLfloat dx0 = v1[0] - v0[0];
  112.    const GLfloat dy0 = v1[1] - v0[1];
  113.    const GLfloat dx1 = v2[0] - v1[0];
  114.    const GLfloat dy1 = v2[1] - v1[1];
  115. /* const */ GLfloat dx2 = v0[0] - v2[0];
  116. /* const */ GLfloat dy2 = v0[1] - v2[1];
  117.    GLfloat cross0,cross1,cross2;
  118.    GLint stop = 4, i;
  119.    GLfloat insideCount = 16.0F;
  120.  
  121.  
  122.    for (i = 0; i < stop; i++) {
  123.       const GLfloat sx = x + samples[i][0];
  124.       const GLfloat sy = y + samples[i][1];
  125. //      const GLfloat fx0 = sx - v0[0];
  126. //      const GLfloat fy0 = sy - v0[1];
  127. //      const GLfloat fx1 = sx - v1[0];
  128. //      const GLfloat fy1 = sy - v1[1];
  129. //      const GLfloat fx2 = sx - v2[0];
  130. //      const GLfloat fy2 = sy - v2[1];
  131.  
  132. //      fx0 = sx - v0[0];
  133. //      fy0 = sy - v0[1];
  134.       /* cross product determines if sample is inside or outside each edge */
  135.       cross0 = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0]));
  136.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  137.        * positive or negative value depending on the direction of the edge.
  138.        */
  139.       if (cross0 == 0.0F)
  140.          cross0 = dx0 + dy0;
  141.       if (cross0 < 0.0F) {
  142.          /* point is outside triangle */
  143.          insideCount--;
  144.          stop = 16;
  145.          continue;
  146.       }
  147. //      fx1 = sx - v1[0];
  148. //      fy1 = sy - v1[1];
  149.  
  150. //      cross1 = (dx1 * fy1 - dy1 * fx1);
  151.       cross1 = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0]));
  152.  
  153.       if (cross1 == 0.0F)
  154.          cross1 = dx1 + dy1;
  155.       if (cross1 < 0.0F) {
  156.          /* point is outside triangle */
  157.          insideCount--;
  158.          stop = 16;
  159.          continue;
  160.       }
  161. //      fx2 = sx - v2[0];
  162. //      fy2 = sy - v2[1];
  163. //    cross2 = (dx2 * fy2 - dy2 * fx2);
  164.       cross2 = (dx2 * (sy - v2[1]) - dy2 * (sx - v2[0]));
  165.       if (cross2 == 0.0F)
  166.          cross2 = dx2 + dy2;
  167.       if (cross2 < 0.0F) {
  168.          /* point is outside triangle */
  169.          insideCount--;
  170.          stop = 16;
  171.       }
  172.    }
  173.  
  174.    if (stop == 4)
  175.       return 1.0F;
  176.    else
  177.       return insideCount * (1.0F / 16.0F);
  178.  
  179. }
  180. /**********************************************/
  181. /*
  182.  * Compute how much (area) of the given pixel is inside the triangle.
  183.  * Vertices MUST be specified in counter-clockwise order.
  184.  * Return:  coverage in [0, 1].
  185.  */
  186. static GLfloat
  187. compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
  188.                   const GLfloat v2[3], GLint winx, GLint winy)
  189. {
  190.    /* Given a position [0,3]x[0,3] return the sub-pixel sample position.
  191.     * Contributed by Ray Tice.
  192.     *
  193.     * Jitter sample positions -
  194.     * - average should be .5 in x & y for each column
  195.     * - each of the 16 rows and columns should be used once
  196.     * - the rectangle formed by the first four points
  197.     *   should contain the other points
  198.     * - the distrubition should be fairly even in any given direction
  199.     *
  200.     * The pattern drawn below isn't optimal, but it's better than a regular
  201.     * grid.  In the drawing, the center of each subpixel is surrounded by
  202.     * four dots.  The "x" marks the jittered position relative to the
  203.     * subpixel center.
  204.     */
  205. #define POS(a, b) (0.5+a*4+b)/16
  206.    static const GLfloat samples[16][2] = {
  207.       /* start with the four corners */
  208.       { POS(0, 2), POS(0, 0) },
  209.       { POS(3, 3), POS(0, 2) },
  210.       { POS(0, 0), POS(3, 1) },
  211.       { POS(3, 1), POS(3, 3) },
  212.       /* continue with interior samples */
  213.       { POS(1, 1), POS(0, 1) },
  214.       { POS(2, 0), POS(0, 3) },
  215.       { POS(0, 3), POS(1, 3) },
  216.       { POS(1, 2), POS(1, 0) },
  217.       { POS(2, 3), POS(1, 2) },
  218.       { POS(3, 2), POS(1, 1) },
  219.       { POS(0, 1), POS(2, 2) },
  220.       { POS(1, 0), POS(2, 1) },
  221.       { POS(2, 1), POS(2, 3) },
  222.       { POS(3, 0), POS(2, 0) },
  223.       { POS(1, 3), POS(3, 0) },
  224.       { POS(2, 2), POS(3, 2) }
  225.    };
  226.  
  227.    const GLfloat x = (GLfloat) winx;
  228.    const GLfloat y = (GLfloat) winy;
  229.    const GLfloat dx0 = v1[0] - v0[0];
  230.    const GLfloat dy0 = v1[1] - v0[1];
  231.    const GLfloat dx1 = v2[0] - v1[0];
  232.    const GLfloat dy1 = v2[1] - v1[1];
  233.    const GLfloat dx2 = v0[0] - v2[0];
  234.    const GLfloat dy2 = v0[1] - v2[1];
  235.    GLint stop = 4, i;
  236.    GLfloat insideCount = 16.0F;
  237.  
  238. #ifdef DEBUG
  239.    {
  240.       const GLfloat area = dx0 * dy1 - dx1 * dy0;
  241.       ASSERT(area >= 0.0);
  242.    }
  243. #endif
  244.  
  245.    for (i = 0; i < stop; i++) {
  246.       const GLfloat sx = x + samples[i][0];
  247.       const GLfloat sy = y + samples[i][1];
  248.       const GLfloat fx0 = sx - v0[0];
  249.       const GLfloat fy0 = sy - v0[1];
  250.       const GLfloat fx1 = sx - v1[0];
  251.       const GLfloat fy1 = sy - v1[1];
  252.       const GLfloat fx2 = sx - v2[0];
  253.       const GLfloat fy2 = sy - v2[1];
  254.       /* cross product determines if sample is inside or outside each edge */
  255.       GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
  256.       GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
  257.       GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
  258.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  259.        * positive or negative value depending on the direction of the edge.
  260.        */
  261.       if (cross0 == 0.0F)
  262.          cross0 = dx0 + dy0;
  263.       if (cross1 == 0.0F)
  264.          cross1 = dx1 + dy1;
  265.       if (cross2 == 0.0F)
  266.          cross2 = dx2 + dy2;
  267.       if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
  268.          /* point is outside triangle */
  269.          insideCount -= 1.0F;
  270.          stop = 16;
  271.       }
  272.    }
  273.    if (stop == 4)
  274.       return 1.0F;
  275.    else
  276.       return insideCount * (1.0F / 16.0F);
  277. }
  278.  
  279.  
  280. /**********************************************/
  281. //EK DEBUG
  282. int debug_write(int *buff, int n);
  283.  
  284. extern void
  285. _mesa_debug( const __GLcontext *ctx, const char *fmtString, ... );
  286.  
  287. /* static */
  288. //void
  289. //rgba_aa_tri(GLcontext *ctx,
  290. //           const SWvertex *v0,
  291. //           const SWvertex *v1,
  292. //           const SWvertex *v2)
  293. F_swrast_tri_func rgba_aa_tri;
  294.  
  295. void
  296. rgba_aa_tri(GLcontext *ctx,
  297.            const SWvertex *v0,
  298.            const SWvertex *v1,
  299.            const SWvertex *v2)
  300.  
  301. /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
  302. {
  303.      const GLfloat *p0 = v0->win;
  304.      const GLfloat *p1 = v1->win;
  305.      const GLfloat *p2 = v2->win;
  306.      const SWvertex *vMin, *vMid, *vMax;
  307.      GLint   iyMin, iyMax, ixMin,ixMax;
  308.      GLfloat yMin,  yMax,  xMax, xMin;
  309.      GLboolean ltor;
  310.      GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  311.      struct sw_span span;
  312.      GLint iy;
  313.      GLint ix, left;
  314.      GLint j,jj;
  315.      GLint  startX;
  316.      GLuint count, n;
  317.      GLfloat x;
  318.      GLfloat zPlane[4];
  319.      GLfloat fogPlane[4];
  320.      GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  321.      GLfloat coverage;
  322. /* static */   GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  323.  
  324. // {
  325. //      _mesa_debug(ctx, "rgba_aa_tri_start: v0=%p,v1=%p, v2=%p\n",v0,v1,v2);
  326. //      _mesa_debug(ctx, "(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",
  327. //        v0->win[0],v0->win[1],v0->win[2],
  328. //        v1->win[0],v1->win[1],v1->win[2],
  329. //        v2->win[0],v2->win[1],v2->win[2] );
  330. //
  331. // }
  332. //printf(__FUNCTION__"ctx=%p,pv1=%p,pv2=%p,v3=%p",   ctx, v0,v1,v2);
  333. //            printf(",v1=%i,v2=%i,3=%i\n",  *v0,*v1,*v2);
  334. //  { int tmp[4];
  335. //    tmp[0] = 0;
  336. //    if(ctx) tmp[0] = 1;
  337. //    tmp[1] = 0;
  338. //    if(v0) tmp[1] = 1;
  339. //    tmp[2] = 0;
  340. //    if(v1) tmp[2] = 1;
  341. //    tmp[3] = 0;
  342. //    if(v1) tmp[3] = 1;
  343. //
  344. //   debug_write(tmp, 4);
  345. //  }
  346.     (span).primitive = (0x0009);
  347.     (span).interpMask = (0);
  348.     (span).arrayMask = (0x100);
  349.     (span).start = 0;
  350.     (span).end = (0);
  351.     (span).facing = 0;
  352.     (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  353.  
  354.    /* determine bottom to top order of vertices */
  355.    {
  356.       GLfloat y0;
  357.       GLfloat y1;
  358.       GLfloat y2;
  359.       y0 = v0->win[1];
  360.       y1 = v1->win[1];
  361.       y2 = v2->win[1];
  362.       if (y0 <= y1) {
  363.         if (y1 <= y2) {
  364.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  365.         }
  366.         else if (y2 <= y0) {
  367.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  368.         }
  369.         else {
  370.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  371.         }
  372.       }
  373.       else {
  374.         if (y0 <= y2) {
  375.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  376.         }
  377.         else if (y2 <= y1) {
  378.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  379.         }
  380.         else {
  381.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  382.         }
  383.       }
  384.    }
  385.  
  386.    majDx = vMax->win[0] - vMin->win[0];
  387.    majDy = vMax->win[1] - vMin->win[1];
  388.  
  389.    {
  390. /* static */      const GLfloat botDx = vMid->win[0] - vMin->win[0];
  391. /* static */      const GLfloat botDy = vMid->win[1] - vMin->win[1];
  392. /* static */      const GLfloat area = majDx * botDy - botDx * majDy;
  393.       ltor = (GLboolean) (area < 0.0F);
  394.       /* Do backface culling */
  395.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  396.         return;
  397.    }
  398.  
  399. #ifndef DO_OCCLUSION_TEST
  400.    ctx->OcclusionResult = GL_TRUE;
  401. #endif
  402.  
  403.    /* Plane equation setup:
  404.     * We evaluate plane equations at window (x,y) coordinates in order
  405.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  406.     * efficient but it's easy and reliable.
  407.     */
  408.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  409.    span.arrayMask |= 0x008;
  410.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  411.    span.arrayMask |= 0x010;
  412.    if (ctx->Light.ShadeModel == 0x1D01) {
  413.       compute_plane(p0, p1, p2, v0->color[0], v1->color[0], v2->color[0], rPlane);
  414.       compute_plane(p0, p1, p2, v0->color[1], v1->color[1], v2->color[1], gPlane);
  415.       compute_plane(p0, p1, p2, v0->color[2], v1->color[2], v2->color[2], bPlane);
  416.       compute_plane(p0, p1, p2, v0->color[3], v1->color[3], v2->color[3], aPlane);
  417.    }
  418.    else {
  419.       constant_plane(v2->color[0], rPlane);
  420.       constant_plane(v2->color[1], gPlane);
  421.       constant_plane(v2->color[2], bPlane);
  422.       constant_plane(v2->color[3], aPlane);
  423.    }
  424.    span.arrayMask |= 0x001;
  425.  
  426.    /* Begin bottom-to-top scan over the triangle.
  427.     * The long edge will either be on the left or right side of the
  428.     * triangle.  We always scan from the long edge toward the shorter
  429.     * edges, stopping when we find that coverage = 0.  If the long edge
  430.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  431.     */
  432.    yMin = vMin->win[1];
  433.    yMax = vMax->win[1];
  434.    iyMin = (GLint) yMin;
  435.    iyMax = (GLint) yMax + 1;
  436.  
  437. /* EK */
  438.    xMax = xMin = vMax->win[0];
  439.    if(vMin->win[0] > xMax) xMax = vMin->win[0];
  440.    if(vMin->win[0] < xMin) xMin = vMin->win[0];
  441.    if(vMid->win[0] > xMax) xMax = vMid->win[0];
  442.    if(vMid->win[0] < xMin) xMin = vMid->win[0];
  443.    ixMin = (int) xMin;
  444.    ixMax = (int) xMax + 1;
  445. //   if(ixMin < 0) ixMin = 0;
  446.    if(ixMax >= ctx->DrawBuffer->Width) ixMax = ctx->DrawBuffer->Width - 1;
  447.    if(iyMax >= ctx->DrawBuffer->Height) iyMax = ctx->DrawBuffer->Height - 1;
  448.  
  449.    if (ltor) {
  450.       /* scan left to right */
  451.       const GLfloat *pMin = vMin->win;
  452.       const GLfloat *pMid = vMid->win;
  453.       const GLfloat *pMax = vMax->win;
  454.       const GLfloat dxdy = majDx / majDy;
  455.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  456.  
  457.      x = pMin[0] - (yMin - iyMin) * dxdy;
  458.  
  459.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy)
  460.       {
  461.          GLint ix, startX = (GLint) (x - xAdj);
  462.          coverage = 0.0F;
  463.  
  464.          /* skip over fragments with zero coverage */
  465.          while (startX < ixMax /* MAX_WIDTH EK */ ) { 
  466.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  467.             if (coverage > 0.0F)
  468.                break;
  469.             startX++;
  470.          }
  471.  
  472.          /* enter interior of triangle */
  473.          ix = startX;
  474.          count = 0;
  475.          while (coverage > 0.0F) {
  476.             /* (cx,cy) = center of fragment */
  477. /* static */             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  478. /* static */            struct span_arrays *array = span.array;
  479.             array->coverage[count] = coverage;
  480.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  481.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  482.             array->rgba[count][0] = solve_plane_chan(cx, cy, rPlane);
  483.             array->rgba[count][1] = solve_plane_chan(cx, cy, gPlane);
  484.             array->rgba[count][2] = solve_plane_chan(cx, cy, bPlane);
  485.             array->rgba[count][3] = solve_plane_chan(cx, cy, aPlane);
  486.             ix++;
  487.             if(ix >= ixMax)
  488.                    break;
  489.             count++;
  490.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  491.          }
  492.  
  493.          if (ix <= startX)
  494.             continue;
  495.  
  496.          span.x = startX;
  497.          span.y = iy;
  498.          span.end = (GLuint) ix - (GLuint) startX;
  499.          _mesa_write_rgba_span(ctx, &span);
  500.       }
  501.    }
  502.    else {
  503.       /* scan right to left */
  504. /* static */      const GLfloat *pMin = vMin->win;
  505. /* static */      const GLfloat *pMid = vMid->win;
  506. /* static */      const GLfloat *pMax = vMax->win;
  507. /* static */      const GLfloat dxdy = majDx / majDy;
  508. /* static */      const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  509.       x = pMin[0] - (yMin - iyMin) * dxdy;
  510.  
  511.  
  512.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  513.        coverage = 0.0F;
  514.        startX = (GLint) (x + xAdj);
  515.  
  516.          /* make sure we're not past the window edge */
  517.          if (startX >= ctx->DrawBuffer->_Xmax) {
  518.             startX = ctx->DrawBuffer->_Xmax - 1;
  519.          }
  520.  
  521.          /* skip fragments with zero coverage */
  522.          while (startX  >= ixMin /* 0 EK */) {
  523.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  524.             if (coverage > 0.0F)
  525.                break;
  526.             startX--;
  527.          }
  528.  
  529.          /* enter interior of triangle */
  530.          ix = startX;
  531.          count = 0;
  532.          while (coverage > 0.0F) {
  533.             /* (cx,cy) = center of fragment */
  534.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  535.             struct span_arrays *array = span.array;
  536.             array->coverage[ix] = coverage;
  537.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  538.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  539.             array->rgba[ix][0] = solve_plane_chan(cx, cy, rPlane);
  540.             array->rgba[ix][1] = solve_plane_chan(cx, cy, gPlane);
  541.             array->rgba[ix][2] = solve_plane_chan(cx, cy, bPlane);
  542.             array->rgba[ix][3] = solve_plane_chan(cx, cy, aPlane);
  543.             ix--;
  544.             if(ix < ixMin)
  545.                    break;
  546.             count++;
  547.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  548.          }
  549.  
  550.          if (startX <= ix)
  551.             continue;
  552.  
  553.          n = (GLuint) startX - (GLuint) ix;
  554.  
  555.          left = ix + 1;
  556.  
  557.          /* shift all values to the left */
  558.          /* XXX this is temporary */
  559.          {
  560.              struct span_arrays *array = span.array;
  561.             for (j = 0; j < (GLint) n; j++)
  562.             { jj = j + left;
  563.                (array->rgba[j])[0] = (array->rgba[jj])[0];
  564.                (array->rgba[j])[1] = (array->rgba[jj])[1];
  565.                (array->rgba[j])[2] = (array->rgba[jj])[2];
  566.                (array->rgba[j])[3] = (array->rgba[jj])[3];
  567.                array->z[j]         = array->z[jj];
  568.                array->fog[j]       = array->fog[jj];
  569.                array->coverage[j]  = array->coverage[jj];
  570.             }
  571.          }
  572.  
  573.          span.x = left;
  574.          span.y = iy;
  575.          span.end = n;
  576.          _mesa_write_rgba_span(ctx, &span);
  577.       }
  578.    }
  579.  
  580. // {
  581. //      _mesa_debug(ctx, "rgba_aa_tri_End  : v0=%p,v1=%p, v2=%p\n",v0,v1,v2);
  582. //      _mesa_debug(ctx, "(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",
  583. //        v0->win[0],v0->win[1],v0->win[2],
  584. //        v1->win[0],v1->win[1],v1->win[2],
  585. //        v2->win[0],v2->win[1],v2->win[2] );
  586. //
  587. // }
  588.  
  589. }
  590.  
  591.  
  592.