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_aaline.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 #include "main/glheader.h"
00027 #include "main/imports.h"
00028 #include "main/macros.h"
00029 #include "main/mtypes.h"
00030 #include "swrast/s_aaline.h"
00031 #include "swrast/s_context.h"
00032 #include "swrast/s_span.h"
00033 #include "swrast/swrast.h"
00034 
00035 
00036 #define SUB_PIXEL 4
00037 
00038 
00039 /*
00040  * Info about the AA line we're rendering
00041  */
00042 struct LineInfo
00043 {
00044    GLfloat x0, y0;        /* start */
00045    GLfloat x1, y1;        /* end */
00046    GLfloat dx, dy;        /* direction vector */
00047    GLfloat len;           /* length */
00048    GLfloat halfWidth;     /* half of line width */
00049    GLfloat xAdj, yAdj;    /* X and Y adjustment for quad corners around line */
00050    /* for coverage computation */
00051    GLfloat qx0, qy0;      /* quad vertices */
00052    GLfloat qx1, qy1;
00053    GLfloat qx2, qy2;
00054    GLfloat qx3, qy3;
00055    GLfloat ex0, ey0;      /* quad edge vectors */
00056    GLfloat ex1, ey1;
00057    GLfloat ex2, ey2;
00058    GLfloat ex3, ey3;
00059 
00060    /* DO_Z */
00061    GLfloat zPlane[4];
00062    /* DO_RGBA */
00063    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
00064    /* DO_INDEX */
00065    GLfloat iPlane[4];
00066    /* DO_ATTRIBS */
00067    GLfloat wPlane[4];
00068    GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
00069    GLfloat lambda[FRAG_ATTRIB_MAX];
00070    GLfloat texWidth[FRAG_ATTRIB_MAX];
00071    GLfloat texHeight[FRAG_ATTRIB_MAX];
00072 
00073    SWspan span;
00074 };
00075 
00076 
00077 
00078 /*
00079  * Compute the equation of a plane used to interpolate line fragment data
00080  * such as color, Z, texture coords, etc.
00081  * Input: (x0, y0) and (x1,y1) are the endpoints of the line.
00082  *        z0, and z1 are the end point values to interpolate.
00083  * Output:  plane - the plane equation.
00084  *
00085  * Note: we don't really have enough parameters to specify a plane.
00086  * We take the endpoints of the line and compute a plane such that
00087  * the cross product of the line vector and the plane normal is
00088  * parallel to the projection plane.
00089  */
00090 static void
00091 compute_plane(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
00092               GLfloat z0, GLfloat z1, GLfloat plane[4])
00093 {
00094 #if 0
00095    /* original */
00096    const GLfloat px = x1 - x0;
00097    const GLfloat py = y1 - y0;
00098    const GLfloat pz = z1 - z0;
00099    const GLfloat qx = -py;
00100    const GLfloat qy = px;
00101    const GLfloat qz = 0;
00102    const GLfloat a = py * qz - pz * qy;
00103    const GLfloat b = pz * qx - px * qz;
00104    const GLfloat c = px * qy - py * qx;
00105    const GLfloat d = -(a * x0 + b * y0 + c * z0);
00106    plane[0] = a;
00107    plane[1] = b;
00108    plane[2] = c;
00109    plane[3] = d;
00110 #else
00111    /* simplified */
00112    const GLfloat px = x1 - x0;
00113    const GLfloat py = y1 - y0;
00114    const GLfloat pz = z0 - z1;
00115    const GLfloat a = pz * px;
00116    const GLfloat b = pz * py;
00117    const GLfloat c = px * px + py * py;
00118    const GLfloat d = -(a * x0 + b * y0 + c * z0);
00119    if (a == 0.0 && b == 0.0 && c == 0.0 && d == 0.0) {
00120       plane[0] = 0.0;
00121       plane[1] = 0.0;
00122       plane[2] = 1.0;
00123       plane[3] = 0.0;
00124    }
00125    else {
00126       plane[0] = a;
00127       plane[1] = b;
00128       plane[2] = c;
00129       plane[3] = d;
00130    }
00131 #endif
00132 }
00133 
00134 
00135 static INLINE void
00136 constant_plane(GLfloat value, GLfloat plane[4])
00137 {
00138    plane[0] = 0.0;
00139    plane[1] = 0.0;
00140    plane[2] = -1.0;
00141    plane[3] = value;
00142 }
00143 
00144 
00145 static INLINE GLfloat
00146 solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
00147 {
00148    const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
00149    return z;
00150 }
00151 
00152 #define SOLVE_PLANE(X, Y, PLANE) \
00153    ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2])
00154 
00155 
00156 /*
00157  * Return 1 / solve_plane().
00158  */
00159 static INLINE GLfloat
00160 solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
00161 {
00162    const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y;
00163    if (denom == 0.0)
00164       return 0.0;
00165    else
00166       return -plane[2] / denom;
00167 }
00168 
00169 
00170 /*
00171  * Solve plane and return clamped GLchan value.
00172  */
00173 static INLINE GLchan
00174 solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
00175 {
00176    const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
00177 #if CHAN_TYPE == GL_FLOAT
00178    return CLAMP(z, 0.0F, CHAN_MAXF);
00179 #else
00180    if (z < 0)
00181       return 0;
00182    else if (z > CHAN_MAX)
00183       return CHAN_MAX;
00184    return (GLchan) IROUND_POS(z);
00185 #endif
00186 }
00187 
00188 
00189 /*
00190  * Compute mipmap level of detail.
00191  */
00192 static INLINE GLfloat
00193 compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
00194                GLfloat invQ, GLfloat width, GLfloat height)
00195 {
00196    GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width;
00197    GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width;
00198    GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height;
00199    GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height;
00200    GLfloat r1 = dudx * dudx + dudy * dudy;
00201    GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
00202    GLfloat rho2 = r1 + r2;
00203    /* return log base 2 of rho */
00204    if (rho2 == 0.0F)
00205       return 0.0;
00206    else
00207       return (GLfloat) (LOGF(rho2) * 1.442695 * 0.5);/* 1.442695 = 1/log(2) */
00208 }
00209 
00210 
00211 
00212 
00213 /*
00214  * Fill in the samples[] array with the (x,y) subpixel positions of
00215  * xSamples * ySamples sample positions.
00216  * Note that the four corner samples are put into the first four
00217  * positions of the array.  This allows us to optimize for the common
00218  * case of all samples being inside the polygon.
00219  */
00220 static void
00221 make_sample_table(GLint xSamples, GLint ySamples, GLfloat samples[][2])
00222 {
00223    const GLfloat dx = 1.0F / (GLfloat) xSamples;
00224    const GLfloat dy = 1.0F / (GLfloat) ySamples;
00225    GLint x, y;
00226    GLint i;
00227 
00228    i = 4;
00229    for (x = 0; x < xSamples; x++) {
00230       for (y = 0; y < ySamples; y++) {
00231          GLint j;
00232          if (x == 0 && y == 0) {
00233             /* lower left */
00234             j = 0;
00235          }
00236          else if (x == xSamples - 1 && y == 0) {
00237             /* lower right */
00238             j = 1;
00239          }
00240          else if (x == 0 && y == ySamples - 1) {
00241             /* upper left */
00242             j = 2;
00243          }
00244          else if (x == xSamples - 1 && y == ySamples - 1) {
00245             /* upper right */
00246             j = 3;
00247          }
00248          else {
00249             j = i++;
00250          }
00251          samples[j][0] = x * dx + 0.5F * dx;
00252          samples[j][1] = y * dy + 0.5F * dy;
00253       }
00254    }
00255 }
00256 
00257 
00258 
00259 /*
00260  * Compute how much of the given pixel's area is inside the rectangle
00261  * defined by vertices v0, v1, v2, v3.
00262  * Vertices MUST be specified in counter-clockwise order.
00263  * Return:  coverage in [0, 1].
00264  */
00265 static GLfloat
00266 compute_coveragef(const struct LineInfo *info,
00267                   GLint winx, GLint winy)
00268 {
00269    static GLfloat samples[SUB_PIXEL * SUB_PIXEL][2];
00270    static GLboolean haveSamples = GL_FALSE;
00271    const GLfloat x = (GLfloat) winx;
00272    const GLfloat y = (GLfloat) winy;
00273    GLint stop = 4, i;
00274    GLfloat insideCount = SUB_PIXEL * SUB_PIXEL;
00275 
00276    if (!haveSamples) {
00277       make_sample_table(SUB_PIXEL, SUB_PIXEL, samples);
00278       haveSamples = GL_TRUE;
00279    }
00280 
00281 #if 0 /*DEBUG*/
00282    {
00283       const GLfloat area = dx0 * dy1 - dx1 * dy0;
00284       assert(area >= 0.0);
00285    }
00286 #endif
00287 
00288    for (i = 0; i < stop; i++) {
00289       const GLfloat sx = x + samples[i][0];
00290       const GLfloat sy = y + samples[i][1];
00291       const GLfloat fx0 = sx - info->qx0;
00292       const GLfloat fy0 = sy - info->qy0;
00293       const GLfloat fx1 = sx - info->qx1;
00294       const GLfloat fy1 = sy - info->qy1;
00295       const GLfloat fx2 = sx - info->qx2;
00296       const GLfloat fy2 = sy - info->qy2;
00297       const GLfloat fx3 = sx - info->qx3;
00298       const GLfloat fy3 = sy - info->qy3;
00299       /* cross product determines if sample is inside or outside each edge */
00300       GLfloat cross0 = (info->ex0 * fy0 - info->ey0 * fx0);
00301       GLfloat cross1 = (info->ex1 * fy1 - info->ey1 * fx1);
00302       GLfloat cross2 = (info->ex2 * fy2 - info->ey2 * fx2);
00303       GLfloat cross3 = (info->ex3 * fy3 - info->ey3 * fx3);
00304       /* Check if the sample is exactly on an edge.  If so, let cross be a
00305        * positive or negative value depending on the direction of the edge.
00306        */
00307       if (cross0 == 0.0F)
00308          cross0 = info->ex0 + info->ey0;
00309       if (cross1 == 0.0F)
00310          cross1 = info->ex1 + info->ey1;
00311       if (cross2 == 0.0F)
00312          cross2 = info->ex2 + info->ey2;
00313       if (cross3 == 0.0F)
00314          cross3 = info->ex3 + info->ey3;
00315       if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F || cross3 < 0.0F) {
00316          /* point is outside quadrilateral */
00317          insideCount -= 1.0F;
00318          stop = SUB_PIXEL * SUB_PIXEL;
00319       }
00320    }
00321    if (stop == 4)
00322       return 1.0F;
00323    else
00324       return insideCount * (1.0F / (SUB_PIXEL * SUB_PIXEL));
00325 }
00326 
00327 
00333 static GLfloat
00334 compute_coveragei(const struct LineInfo *info,
00335                   GLint winx, GLint winy)
00336 {
00337    return compute_coveragef(info, winx, winy) * 15.0F;
00338 }
00339 
00340 
00341 
00342 typedef void (*plot_func)(GLcontext *ctx, struct LineInfo *line,
00343                           int ix, int iy);
00344                          
00345 
00346 
00347 /*
00348  * Draw an AA line segment (called many times per line when stippling)
00349  */
00350 static void
00351 segment(GLcontext *ctx,
00352         struct LineInfo *line,
00353         plot_func plot,
00354         GLfloat t0, GLfloat t1)
00355 {
00356    const GLfloat absDx = (line->dx < 0.0F) ? -line->dx : line->dx;
00357    const GLfloat absDy = (line->dy < 0.0F) ? -line->dy : line->dy;
00358    /* compute the actual segment's endpoints */
00359    const GLfloat x0 = line->x0 + t0 * line->dx;
00360    const GLfloat y0 = line->y0 + t0 * line->dy;
00361    const GLfloat x1 = line->x0 + t1 * line->dx;
00362    const GLfloat y1 = line->y0 + t1 * line->dy;
00363 
00364    /* compute vertices of the line-aligned quadrilateral */
00365    line->qx0 = x0 - line->yAdj;
00366    line->qy0 = y0 + line->xAdj;
00367    line->qx1 = x0 + line->yAdj;
00368    line->qy1 = y0 - line->xAdj;
00369    line->qx2 = x1 + line->yAdj;
00370    line->qy2 = y1 - line->xAdj;
00371    line->qx3 = x1 - line->yAdj;
00372    line->qy3 = y1 + line->xAdj;
00373    /* compute the quad's edge vectors (for coverage calc) */
00374    line->ex0 = line->qx1 - line->qx0;
00375    line->ey0 = line->qy1 - line->qy0;
00376    line->ex1 = line->qx2 - line->qx1;
00377    line->ey1 = line->qy2 - line->qy1;
00378    line->ex2 = line->qx3 - line->qx2;
00379    line->ey2 = line->qy3 - line->qy2;
00380    line->ex3 = line->qx0 - line->qx3;
00381    line->ey3 = line->qy0 - line->qy3;
00382 
00383    if (absDx > absDy) {
00384       /* X-major line */
00385       GLfloat dydx = line->dy / line->dx;
00386       GLfloat xLeft, xRight, yBot, yTop;
00387       GLint ix, ixRight;
00388       if (x0 < x1) {
00389          xLeft = x0 - line->halfWidth;
00390          xRight = x1 + line->halfWidth;
00391          if (line->dy >= 0.0) {
00392             yBot = y0 - 3.0F * line->halfWidth;
00393             yTop = y0 + line->halfWidth;
00394          }
00395          else {
00396             yBot = y0 - line->halfWidth;
00397             yTop = y0 + 3.0F * line->halfWidth;
00398          }
00399       }
00400       else {
00401          xLeft = x1 - line->halfWidth;
00402          xRight = x0 + line->halfWidth;
00403          if (line->dy <= 0.0) {
00404             yBot = y1 - 3.0F * line->halfWidth;
00405             yTop = y1 + line->halfWidth;
00406          }
00407          else {
00408             yBot = y1 - line->halfWidth;
00409             yTop = y1 + 3.0F * line->halfWidth;
00410          }
00411       }
00412 
00413       /* scan along the line, left-to-right */
00414       ixRight = (GLint) (xRight + 1.0F);
00415 
00416       /*printf("avg span height: %g\n", yTop - yBot);*/
00417       for (ix = (GLint) xLeft; ix < ixRight; ix++) {
00418          const GLint iyBot = (GLint) yBot;
00419          const GLint iyTop = (GLint) (yTop + 1.0F);
00420          GLint iy;
00421          /* scan across the line, bottom-to-top */
00422          for (iy = iyBot; iy < iyTop; iy++) {
00423             (*plot)(ctx, line, ix, iy);
00424          }
00425          yBot += dydx;
00426          yTop += dydx;
00427       }
00428    }
00429    else {
00430       /* Y-major line */
00431       GLfloat dxdy = line->dx / line->dy;
00432       GLfloat yBot, yTop, xLeft, xRight;
00433       GLint iy, iyTop;
00434       if (y0 < y1) {
00435          yBot = y0 - line->halfWidth;
00436          yTop = y1 + line->halfWidth;
00437          if (line->dx >= 0.0) {
00438             xLeft = x0 - 3.0F * line->halfWidth;
00439             xRight = x0 + line->halfWidth;
00440          }
00441          else {
00442             xLeft = x0 - line->halfWidth;
00443             xRight = x0 + 3.0F * line->halfWidth;
00444          }
00445       }
00446       else {
00447          yBot = y1 - line->halfWidth;
00448          yTop = y0 + line->halfWidth;
00449          if (line->dx <= 0.0) {
00450             xLeft = x1 - 3.0F * line->halfWidth;
00451             xRight = x1 + line->halfWidth;
00452          }
00453          else {
00454             xLeft = x1 - line->halfWidth;
00455             xRight = x1 + 3.0F * line->halfWidth;
00456          }
00457       }
00458 
00459       /* scan along the line, bottom-to-top */
00460       iyTop = (GLint) (yTop + 1.0F);
00461 
00462       /*printf("avg span width: %g\n", xRight - xLeft);*/
00463       for (iy = (GLint) yBot; iy < iyTop; iy++) {
00464          const GLint ixLeft = (GLint) xLeft;
00465          const GLint ixRight = (GLint) (xRight + 1.0F);
00466          GLint ix;
00467          /* scan across the line, left-to-right */
00468          for (ix = ixLeft; ix < ixRight; ix++) {
00469             (*plot)(ctx, line, ix, iy);
00470          }
00471          xLeft += dxdy;
00472          xRight += dxdy;
00473       }
00474    }
00475 }
00476 
00477 
00478 #define NAME(x) aa_ci_##x
00479 #define DO_Z
00480 #define DO_ATTRIBS /* for fog */
00481 #define DO_INDEX
00482 #include "s_aalinetemp.h"
00483 
00484 
00485 #define NAME(x) aa_rgba_##x
00486 #define DO_Z
00487 #define DO_RGBA
00488 #include "s_aalinetemp.h"
00489 
00490 
00491 #define NAME(x)  aa_general_rgba_##x
00492 #define DO_Z
00493 #define DO_RGBA
00494 #define DO_ATTRIBS
00495 #include "s_aalinetemp.h"
00496 
00497 
00498 
00499 void
00500 _swrast_choose_aa_line_function(GLcontext *ctx)
00501 {
00502    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00503 
00504    ASSERT(ctx->Line.SmoothFlag);
00505 
00506    if (ctx->Visual.rgbMode) {
00507       /* RGBA */
00508       if (ctx->Texture._EnabledCoordUnits != 0
00509           || ctx->FragmentProgram._Current
00510           || (ctx->Light.Enabled &&
00511               ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
00512           || ctx->Fog.ColorSumEnabled
00513           || swrast->_FogEnabled) {
00514          swrast->Line = aa_general_rgba_line;
00515       }
00516       else {
00517          swrast->Line = aa_rgba_line;
00518       }
00519    }
00520    else {
00521       /* Color Index */
00522       swrast->Line = aa_ci_line;
00523    }
00524 }

Generated on Mon May 28 2012 04:20:21 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.