Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.0.3
  4.  *
  5.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /*
  27.  * Antialiased Triangle Rasterizer Template
  28.  *
  29.  * This file is #include'd to generate custom AA triangle rasterizers.
  30.  * NOTE: this code hasn't been optimized yet.  That'll come after it
  31.  * works correctly.
  32.  *
  33.  * The following macros may be defined to indicate what auxillary information
  34.  * must be copmuted across the triangle:
  35.  *    DO_Z         - if defined, compute Z values
  36.  *    DO_ATTRIBS   - if defined, compute texcoords, varying, etc.
  37.  */
  38.  
  39. /*void triangle( struct gl_context *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
  40. {
  41.    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
  42.    const GLfloat *p0 = v0->attrib[FRAG_ATTRIB_WPOS];
  43.    const GLfloat *p1 = v1->attrib[FRAG_ATTRIB_WPOS];
  44.    const GLfloat *p2 = v2->attrib[FRAG_ATTRIB_WPOS];
  45.    const SWvertex *vMin, *vMid, *vMax;
  46.    GLint iyMin, iyMax;
  47.    GLfloat yMin, yMax;
  48.    GLboolean ltor;
  49.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  50.    
  51.    SWspan span;
  52.    
  53. #ifdef DO_Z
  54.    GLfloat zPlane[4];
  55. #endif
  56.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  57. #if defined(DO_ATTRIBS)
  58.    GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
  59.    GLfloat wPlane[4];  /* win[3] */
  60. #endif
  61.    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceCullSign;
  62.    
  63.    (void) swrast;
  64.  
  65.    INIT_SPAN(span, GL_POLYGON);
  66.    span.arrayMask = SPAN_COVERAGE;
  67.  
  68.    /* determine bottom to top order of vertices */
  69.    {
  70.       GLfloat y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
  71.       GLfloat y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
  72.       GLfloat y2 = v2->attrib[FRAG_ATTRIB_WPOS][1];
  73.       if (y0 <= y1) {
  74.          if (y1 <= y2) {
  75.             vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  76.          }
  77.          else if (y2 <= y0) {
  78.             vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  79.          }
  80.          else {
  81.             vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  82.          }
  83.       }
  84.       else {
  85.          if (y0 <= y2) {
  86.             vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  87.          }
  88.          else if (y2 <= y1) {
  89.             vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  90.          }
  91.          else {
  92.             vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  93.          }
  94.       }
  95.    }
  96.  
  97.    majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
  98.    majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
  99.  
  100.    /* front/back-face determination and cullling */
  101.    {
  102.       const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
  103.       const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
  104.       const GLfloat area = majDx * botDy - botDx * majDy;
  105.       /* Do backface culling */
  106.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  107.          return;
  108.       ltor = (GLboolean) (area < 0.0F);
  109.  
  110.       span.facing = area * swrast->_BackfaceSign > 0.0F;
  111.    }
  112.  
  113.    /* Plane equation setup:
  114.     * We evaluate plane equations at window (x,y) coordinates in order
  115.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  116.     * efficient but it's easy and reliable.
  117.     */
  118. #ifdef DO_Z
  119.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  120.    span.arrayMask |= SPAN_Z;
  121. #endif
  122.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  123.       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
  124.       compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane);
  125.       compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane);
  126.       compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane);
  127.    }
  128.    else {
  129.       constant_plane(v2->color[RCOMP], rPlane);
  130.       constant_plane(v2->color[GCOMP], gPlane);
  131.       constant_plane(v2->color[BCOMP], bPlane);
  132.       constant_plane(v2->color[ACOMP], aPlane);
  133.    }
  134.    span.arrayMask |= SPAN_RGBA;
  135. #if defined(DO_ATTRIBS)
  136.    {
  137.       const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
  138.       const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
  139.       const GLfloat invW2 = v2->attrib[FRAG_ATTRIB_WPOS][3];
  140.       compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane);
  141.       span.attrStepX[FRAG_ATTRIB_WPOS][3] = plane_dx(wPlane);
  142.       span.attrStepY[FRAG_ATTRIB_WPOS][3] = plane_dy(wPlane);
  143.       ATTRIB_LOOP_BEGIN
  144.          GLuint c;
  145.          if (swrast->_InterpMode[attr] == GL_FLAT) {
  146.             for (c = 0; c < 4; c++) {
  147.                constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]);
  148.             }
  149.          }
  150.          else {
  151.             for (c = 0; c < 4; c++) {
  152.                const GLfloat a0 = v0->attrib[attr][c] * invW0;
  153.                const GLfloat a1 = v1->attrib[attr][c] * invW1;
  154.                const GLfloat a2 = v2->attrib[attr][c] * invW2;
  155.                compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]);
  156.             }
  157.          }
  158.          for (c = 0; c < 4; c++) {
  159.             span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]);
  160.             span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]);
  161.          }
  162.       ATTRIB_LOOP_END
  163.    }
  164. #endif
  165.  
  166.    /* Begin bottom-to-top scan over the triangle.
  167.     * The long edge will either be on the left or right side of the
  168.     * triangle.  We always scan from the long edge toward the shorter
  169.     * edges, stopping when we find that coverage = 0.  If the long edge
  170.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  171.     */
  172.    yMin = vMin->attrib[FRAG_ATTRIB_WPOS][1];
  173.    yMax = vMax->attrib[FRAG_ATTRIB_WPOS][1];
  174.    iyMin = (GLint) yMin;
  175.    iyMax = (GLint) yMax + 1;
  176.  
  177.    if (ltor) {
  178.       /* scan left to right */
  179.       const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
  180.       const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
  181.       const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
  182.       const GLfloat dxdy = majDx / majDy;
  183.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  184.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  185.       GLint iy;
  186.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  187.          GLint ix, startX = (GLint) (x - xAdj);
  188.          GLuint count;
  189.          GLfloat coverage = 0.0F;
  190.  
  191.          /* skip over fragments with zero coverage */
  192.          while (startX < MAX_WIDTH) {
  193.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  194.             if (coverage > 0.0F)
  195.                break;
  196.             startX++;
  197.          }
  198.  
  199.          /* enter interior of triangle */
  200.          ix = startX;
  201.  
  202. #if defined(DO_ATTRIBS)
  203.          /* compute attributes at left-most fragment */
  204.          span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5F, iy + 0.5F, wPlane);
  205.          ATTRIB_LOOP_BEGIN
  206.             GLuint c;
  207.             for (c = 0; c < 4; c++) {
  208.                span.attrStart[attr][c] = solve_plane(ix + 0.5F, iy + 0.5F, attrPlane[attr][c]);
  209.             }
  210.          ATTRIB_LOOP_END
  211. #endif
  212.  
  213.          count = 0;
  214.          while (coverage > 0.0F) {
  215.             /* (cx,cy) = center of fragment */
  216.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  217.             SWspanarrays *array = span.array;
  218.             array->coverage[count] = coverage;
  219. #ifdef DO_Z
  220.             array->z[count] = (GLuint) solve_plane(cx, cy, zPlane);
  221. #endif
  222.             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  223.             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  224.             array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  225.             array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  226.             ix++;
  227.             count++;
  228.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  229.          }
  230.          
  231.          if (ix <= startX)
  232.             continue;
  233.          
  234.          span.x = startX;
  235.          span.y = iy;
  236.          span.end = (GLuint) ix - (GLuint) startX;
  237.          _swrast_write_rgba_span(ctx, &span);
  238.       }
  239.    }
  240.    else {
  241.       /* scan right to left */
  242.       const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
  243.       const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
  244.       const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
  245.       const GLfloat dxdy = majDx / majDy;
  246.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  247.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  248.       GLint iy;
  249.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  250.          GLint ix, left, startX = (GLint) (x + xAdj);
  251.          GLuint count, n;
  252.          GLfloat coverage = 0.0F;
  253.          
  254.          /* make sure we're not past the window edge */
  255.          if (startX >= ctx->DrawBuffer->_Xmax) {
  256.             startX = ctx->DrawBuffer->_Xmax - 1;
  257.          }
  258.  
  259.          /* skip fragments with zero coverage */
  260.          while (startX > 0) {
  261.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  262.             if (coverage > 0.0F)
  263.                break;
  264.             startX--;
  265.          }
  266.          
  267.          /* enter interior of triangle */
  268.          ix = startX;
  269.          count = 0;
  270.          while (coverage > 0.0F) {
  271.             /* (cx,cy) = center of fragment */
  272.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  273.             SWspanarrays *array = span.array;
  274.             ASSERT(ix >= 0);
  275.             array->coverage[ix] = coverage;
  276. #ifdef DO_Z
  277.             array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane);
  278. #endif
  279.             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  280.             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  281.             array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  282.             array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  283.             ix--;
  284.             count++;
  285.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  286.          }
  287.          
  288. #if defined(DO_ATTRIBS)
  289.          /* compute attributes at left-most fragment */
  290.          span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5F, iy + 0.5F, wPlane);
  291.          ATTRIB_LOOP_BEGIN
  292.             GLuint c;
  293.             for (c = 0; c < 4; c++) {
  294.                span.attrStart[attr][c] = solve_plane(ix + 1.5F, iy + 0.5F, attrPlane[attr][c]);
  295.             }
  296.          ATTRIB_LOOP_END
  297. #endif
  298.  
  299.          if (startX <= ix)
  300.             continue;
  301.  
  302.          n = (GLuint) startX - (GLuint) ix;
  303.  
  304.          left = ix + 1;
  305.  
  306.          /* shift all values to the left */
  307.          /* XXX this is temporary */
  308.          {
  309.             SWspanarrays *array = span.array;
  310.             GLint j;
  311.             for (j = 0; j < (GLint) n; j++) {
  312.                array->coverage[j] = array->coverage[j + left];
  313.                COPY_CHAN4(array->rgba[j], array->rgba[j + left]);
  314. #ifdef DO_Z
  315.                array->z[j] = array->z[j + left];
  316. #endif
  317.             }
  318.          }
  319.  
  320.          span.x = left;
  321.          span.y = iy;
  322.          span.end = n;
  323.          _swrast_write_rgba_span(ctx, &span);
  324.       }
  325.    }
  326. }
  327.  
  328.  
  329. #undef DO_Z
  330. #undef DO_ATTRIBS
  331. #undef DO_OCCLUSION_TEST
  332.