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

Information | Donate

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

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

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

ReactOS Development > Doxygen

s_aatriangle.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  6.5.3
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00026 /*
00027  * Antialiased Triangle rasterizers
00028  */
00029 
00030 
00031 #include "main/glheader.h"
00032 #include "main/context.h"
00033 #include "main/colormac.h"
00034 #include "main/context.h"
00035 #include "main/macros.h"
00036 #include "main/imports.h"
00037 #include "s_aatriangle.h"
00038 #include "s_context.h"
00039 #include "s_span.h"
00040 
00041 
00042 /*
00043  * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
00044  * vertices and the given Z values.
00045  * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
00046  */
00047 static INLINE void
00048 compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
00049               GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4])
00050 {
00051    const GLfloat px = v1[0] - v0[0];
00052    const GLfloat py = v1[1] - v0[1];
00053    const GLfloat pz = z1 - z0;
00054 
00055    const GLfloat qx = v2[0] - v0[0];
00056    const GLfloat qy = v2[1] - v0[1];
00057    const GLfloat qz = z2 - z0;
00058 
00059    /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
00060    const GLfloat a = py * qz - pz * qy;
00061    const GLfloat b = pz * qx - px * qz;
00062    const GLfloat c = px * qy - py * qx;
00063    /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
00064       on the distance of plane from origin and arbitrary "w" parallel
00065       to the plane. */
00066    /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
00067       which is equal to "-d" below. */
00068    const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
00069 
00070    plane[0] = a;
00071    plane[1] = b;
00072    plane[2] = c;
00073    plane[3] = d;
00074 }
00075 
00076 
00077 /*
00078  * Compute coefficients of a plane with a constant Z value.
00079  */
00080 static INLINE void
00081 constant_plane(GLfloat value, GLfloat plane[4])
00082 {
00083    plane[0] = 0.0;
00084    plane[1] = 0.0;
00085    plane[2] = -1.0;
00086    plane[3] = value;
00087 }
00088 
00089 #define CONSTANT_PLANE(VALUE, PLANE)    \
00090 do {                    \
00091    PLANE[0] = 0.0F;         \
00092    PLANE[1] = 0.0F;         \
00093    PLANE[2] = -1.0F;            \
00094    PLANE[3] = VALUE;            \
00095 } while (0)
00096 
00097 
00098 
00099 /*
00100  * Solve plane equation for Z at (X,Y).
00101  */
00102 static INLINE GLfloat
00103 solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
00104 {
00105    ASSERT(plane[2] != 0.0F);
00106    return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
00107 }
00108 
00109 
00110 #define SOLVE_PLANE(X, Y, PLANE) \
00111    ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2])
00112 
00113 
00114 /*
00115  * Return 1 / solve_plane().
00116  */
00117 static INLINE GLfloat
00118 solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
00119 {
00120    const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y;
00121    if (denom == 0.0F)
00122       return 0.0F;
00123    else
00124       return -plane[2] / denom;
00125 }
00126 
00127 
00128 /*
00129  * Solve plane and return clamped GLchan value.
00130  */
00131 static INLINE GLchan
00132 solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
00133 {
00134    const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
00135 #if CHAN_TYPE == GL_FLOAT
00136    return CLAMP(z, 0.0F, CHAN_MAXF);
00137 #else
00138    if (z < 0)
00139       return 0;
00140    else if (z > CHAN_MAX)
00141       return CHAN_MAX;
00142    return (GLchan) IROUND_POS(z);
00143 #endif
00144 }
00145 
00146 
00147 static INLINE GLfloat
00148 plane_dx(const GLfloat plane[4])
00149 {
00150    return -plane[0] / plane[2];
00151 }
00152 
00153 static INLINE GLfloat
00154 plane_dy(const GLfloat plane[4])
00155 {
00156    return -plane[1] / plane[2];
00157 }
00158 
00159 
00160 
00161 /*
00162  * Compute how much (area) of the given pixel is inside the triangle.
00163  * Vertices MUST be specified in counter-clockwise order.
00164  * Return:  coverage in [0, 1].
00165  */
00166 static GLfloat
00167 compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
00168                   const GLfloat v2[3], GLint winx, GLint winy)
00169 {
00170    /* Given a position [0,3]x[0,3] return the sub-pixel sample position.
00171     * Contributed by Ray Tice.
00172     *
00173     * Jitter sample positions -
00174     * - average should be .5 in x & y for each column
00175     * - each of the 16 rows and columns should be used once
00176     * - the rectangle formed by the first four points
00177     *   should contain the other points
00178     * - the distrubition should be fairly even in any given direction
00179     *
00180     * The pattern drawn below isn't optimal, but it's better than a regular
00181     * grid.  In the drawing, the center of each subpixel is surrounded by
00182     * four dots.  The "x" marks the jittered position relative to the
00183     * subpixel center.
00184     */
00185 #define POS(a, b) (0.5+a*4+b)/16
00186    static const GLfloat samples[16][2] = {
00187       /* start with the four corners */
00188       { POS(0, 2), POS(0, 0) },
00189       { POS(3, 3), POS(0, 2) },
00190       { POS(0, 0), POS(3, 1) },
00191       { POS(3, 1), POS(3, 3) },
00192       /* continue with interior samples */
00193       { POS(1, 1), POS(0, 1) },
00194       { POS(2, 0), POS(0, 3) },
00195       { POS(0, 3), POS(1, 3) },
00196       { POS(1, 2), POS(1, 0) },
00197       { POS(2, 3), POS(1, 2) },
00198       { POS(3, 2), POS(1, 1) },
00199       { POS(0, 1), POS(2, 2) },
00200       { POS(1, 0), POS(2, 1) },
00201       { POS(2, 1), POS(2, 3) },
00202       { POS(3, 0), POS(2, 0) },
00203       { POS(1, 3), POS(3, 0) },
00204       { POS(2, 2), POS(3, 2) }
00205    };
00206 
00207    const GLfloat x = (GLfloat) winx;
00208    const GLfloat y = (GLfloat) winy;
00209    const GLfloat dx0 = v1[0] - v0[0];
00210    const GLfloat dy0 = v1[1] - v0[1];
00211    const GLfloat dx1 = v2[0] - v1[0];
00212    const GLfloat dy1 = v2[1] - v1[1];
00213    const GLfloat dx2 = v0[0] - v2[0];
00214    const GLfloat dy2 = v0[1] - v2[1];
00215    GLint stop = 4, i;
00216    GLfloat insideCount = 16.0F;
00217 
00218 #ifdef DEBUG
00219    {
00220       const GLfloat area = dx0 * dy1 - dx1 * dy0;
00221       ASSERT(area >= 0.0);
00222    }
00223 #endif
00224 
00225    for (i = 0; i < stop; i++) {
00226       const GLfloat sx = x + samples[i][0];
00227       const GLfloat sy = y + samples[i][1];
00228       /* cross product determines if sample is inside or outside each edge */
00229       GLfloat cross = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0]));
00230       /* Check if the sample is exactly on an edge.  If so, let cross be a
00231        * positive or negative value depending on the direction of the edge.
00232        */
00233       if (cross == 0.0F)
00234          cross = dx0 + dy0;
00235       if (cross < 0.0F) {
00236          /* sample point is outside first edge */
00237          insideCount -= 1.0F;
00238          stop = 16;
00239       }
00240       else {
00241          /* sample point is inside first edge */
00242          cross = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0]));
00243          if (cross == 0.0F)
00244             cross = dx1 + dy1;
00245          if (cross < 0.0F) {
00246             /* sample point is outside second edge */
00247             insideCount -= 1.0F;
00248             stop = 16;
00249          }
00250          else {
00251             /* sample point is inside first and second edges */
00252             cross = (dx2 * (sy - v2[1]) -  dy2 * (sx - v2[0]));
00253             if (cross == 0.0F)
00254                cross = dx2 + dy2;
00255             if (cross < 0.0F) {
00256                /* sample point is outside third edge */
00257                insideCount -= 1.0F;
00258                stop = 16;
00259             }
00260          }
00261       }
00262    }
00263    if (stop == 4)
00264       return 1.0F;
00265    else
00266       return insideCount * (1.0F / 16.0F);
00267 }
00268 
00269 
00270 
00271 /*
00272  * Compute how much (area) of the given pixel is inside the triangle.
00273  * Vertices MUST be specified in counter-clockwise order.
00274  * Return:  coverage in [0, 15].
00275  */
00276 static GLint
00277 compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
00278                   const GLfloat v2[3], GLint winx, GLint winy)
00279 {
00280    /* NOTE: 15 samples instead of 16. */
00281    static const GLfloat samples[15][2] = {
00282       /* start with the four corners */
00283       { POS(0, 2), POS(0, 0) },
00284       { POS(3, 3), POS(0, 2) },
00285       { POS(0, 0), POS(3, 1) },
00286       { POS(3, 1), POS(3, 3) },
00287       /* continue with interior samples */
00288       { POS(1, 1), POS(0, 1) },
00289       { POS(2, 0), POS(0, 3) },
00290       { POS(0, 3), POS(1, 3) },
00291       { POS(1, 2), POS(1, 0) },
00292       { POS(2, 3), POS(1, 2) },
00293       { POS(3, 2), POS(1, 1) },
00294       { POS(0, 1), POS(2, 2) },
00295       { POS(1, 0), POS(2, 1) },
00296       { POS(2, 1), POS(2, 3) },
00297       { POS(3, 0), POS(2, 0) },
00298       { POS(1, 3), POS(3, 0) }
00299    };
00300    const GLfloat x = (GLfloat) winx;
00301    const GLfloat y = (GLfloat) winy;
00302    const GLfloat dx0 = v1[0] - v0[0];
00303    const GLfloat dy0 = v1[1] - v0[1];
00304    const GLfloat dx1 = v2[0] - v1[0];
00305    const GLfloat dy1 = v2[1] - v1[1];
00306    const GLfloat dx2 = v0[0] - v2[0];
00307    const GLfloat dy2 = v0[1] - v2[1];
00308    GLint stop = 4, i;
00309    GLint insideCount = 15;
00310 
00311 #ifdef DEBUG
00312    {
00313       const GLfloat area = dx0 * dy1 - dx1 * dy0;
00314       ASSERT(area >= 0.0);
00315    }
00316 #endif
00317 
00318    for (i = 0; i < stop; i++) {
00319       const GLfloat sx = x + samples[i][0];
00320       const GLfloat sy = y + samples[i][1];
00321       const GLfloat fx0 = sx - v0[0];
00322       const GLfloat fy0 = sy - v0[1];
00323       const GLfloat fx1 = sx - v1[0];
00324       const GLfloat fy1 = sy - v1[1];
00325       const GLfloat fx2 = sx - v2[0];
00326       const GLfloat fy2 = sy - v2[1];
00327       /* cross product determines if sample is inside or outside each edge */
00328       GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
00329       GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
00330       GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
00331       /* Check if the sample is exactly on an edge.  If so, let cross be a
00332        * positive or negative value depending on the direction of the edge.
00333        */
00334       if (cross0 == 0.0F)
00335          cross0 = dx0 + dy0;
00336       if (cross1 == 0.0F)
00337          cross1 = dx1 + dy1;
00338       if (cross2 == 0.0F)
00339          cross2 = dx2 + dy2;
00340       if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
00341          /* point is outside triangle */
00342          insideCount--;
00343          stop = 15;
00344       }
00345    }
00346    if (stop == 4)
00347       return 15;
00348    else
00349       return insideCount;
00350 }
00351 
00352 
00353 static void
00354 rgba_aa_tri(GLcontext *ctx,
00355         const SWvertex *v0,
00356         const SWvertex *v1,
00357         const SWvertex *v2)
00358 {
00359 #define DO_Z
00360 #define DO_RGBA
00361 #include "s_aatritemp.h"
00362 }
00363 
00364 
00365 static void
00366 index_aa_tri(GLcontext *ctx,
00367          const SWvertex *v0,
00368          const SWvertex *v1,
00369          const SWvertex *v2)
00370 {
00371 #define DO_Z
00372 #define DO_ATTRIBS
00373 #define DO_INDEX
00374 #include "s_aatritemp.h"
00375 }
00376 
00377 
00378 static void
00379 general_aa_tri(GLcontext *ctx,
00380                const SWvertex *v0,
00381                const SWvertex *v1,
00382                const SWvertex *v2)
00383 {
00384 #define DO_Z
00385 #define DO_RGBA
00386 #define DO_ATTRIBS
00387 #include "s_aatritemp.h"
00388 }
00389 
00390 
00391 
00392 /*
00393  * Examine GL state and set swrast->Triangle to an
00394  * appropriate antialiased triangle rasterizer function.
00395  */
00396 void
00397 _swrast_set_aa_triangle_function(GLcontext *ctx)
00398 {
00399    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00400 
00401    ASSERT(ctx->Polygon.SmoothFlag);
00402 
00403    if (ctx->Texture._EnabledCoordUnits != 0
00404        || ctx->FragmentProgram._Current
00405        || swrast->_FogEnabled
00406        || NEED_SECONDARY_COLOR(ctx)) {
00407       SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
00408    }
00409    else if (ctx->Visual.rgbMode) {
00410       SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri;
00411    }
00412    else {
00413       SWRAST_CONTEXT(ctx)->Triangle = index_aa_tri;
00414    }
00415 
00416    ASSERT(SWRAST_CONTEXT(ctx)->Triangle);
00417 }

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

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