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