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_triangle.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.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  * When the device driver doesn't implement triangle rasterization it
00028  * can hook in _swrast_Triangle, which eventually calls one of these
00029  * functions to draw triangles.
00030  */
00031 
00032 #include "main/glheader.h"
00033 #include "main/context.h"
00034 #include "main/colormac.h"
00035 #include "main/imports.h"
00036 #include "main/macros.h"
00037 #include "main/texformat.h"
00038 
00039 #include "s_aatriangle.h"
00040 #include "s_context.h"
00041 #include "s_feedback.h"
00042 #include "s_span.h"
00043 #include "s_triangle.h"
00044 
00045 
00046 /*
00047  * Just used for feedback mode.
00048  */
00049 GLboolean
00050 _swrast_culltriangle( GLcontext *ctx,
00051                       const SWvertex *v0,
00052                       const SWvertex *v1,
00053                       const SWvertex *v2 )
00054 {
00055    GLfloat ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
00056    GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
00057    GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
00058    GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
00059    GLfloat c = ex*fy-ey*fx;
00060 
00061    if (c * SWRAST_CONTEXT(ctx)->_BackfaceCullSign > 0)
00062       return 0;
00063 
00064    return 1;
00065 }
00066 
00067 
00068 
00069 /*
00070  * Render a smooth or flat-shaded color index triangle.
00071  */
00072 #define NAME ci_triangle
00073 #define INTERP_Z 1
00074 #define INTERP_ATTRIBS 1  /* just for fog */
00075 #define INTERP_INDEX 1
00076 #define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
00077 #include "s_tritemp.h"
00078 
00079 
00080 
00081 /*
00082  * Render a flat-shaded RGBA triangle.
00083  */
00084 #define NAME flat_rgba_triangle
00085 #define INTERP_Z 1
00086 #define SETUP_CODE              \
00087    ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
00088    ASSERT(ctx->Light.ShadeModel==GL_FLAT);  \
00089    span.interpMask |= SPAN_RGBA;        \
00090    span.red = ChanToFixed(v2->color[0]);    \
00091    span.green = ChanToFixed(v2->color[1]);  \
00092    span.blue = ChanToFixed(v2->color[2]);   \
00093    span.alpha = ChanToFixed(v2->color[3]);  \
00094    span.redStep = 0;                \
00095    span.greenStep = 0;              \
00096    span.blueStep = 0;               \
00097    span.alphaStep = 0;
00098 #define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
00099 #include "s_tritemp.h"
00100 
00101 
00102 
00103 /*
00104  * Render a smooth-shaded RGBA triangle.
00105  */
00106 #define NAME smooth_rgba_triangle
00107 #define INTERP_Z 1
00108 #define INTERP_RGB 1
00109 #define INTERP_ALPHA 1
00110 #define SETUP_CODE              \
00111    {                        \
00112       /* texturing must be off */       \
00113       ASSERT(ctx->Texture._EnabledCoordUnits == 0); \
00114       ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); \
00115    }
00116 #define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
00117 #include "s_tritemp.h"
00118 
00119 
00120 
00121 /*
00122  * Render an RGB, GL_DECAL, textured triangle.
00123  * Interpolate S,T only w/out mipmapping or perspective correction.
00124  *
00125  * No fog.  No depth testing.
00126  */
00127 #define NAME simple_textured_triangle
00128 #define INTERP_INT_TEX 1
00129 #define S_SCALE twidth
00130 #define T_SCALE theight
00131 
00132 #define SETUP_CODE                          \
00133    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];  \
00134    struct gl_texture_object *obj =                  \
00135       ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];        \
00136    const GLint b = obj->BaseLevel;                  \
00137    const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;        \
00138    const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;      \
00139    const GLint twidth_log2 = obj->Image[0][b]->WidthLog2;       \
00140    const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data; \
00141    const GLint smask = obj->Image[0][b]->Width - 1;         \
00142    const GLint tmask = obj->Image[0][b]->Height - 1;            \
00143    if (!rb || !texture) {                       \
00144       return;                               \
00145    }
00146 
00147 #define RENDER_SPAN( span )                     \
00148    GLuint i;                                \
00149    GLchan rgb[MAX_WIDTH][3];                        \
00150    span.intTex[0] -= FIXED_HALF; /* off-by-one error? */        \
00151    span.intTex[1] -= FIXED_HALF;                    \
00152    for (i = 0; i < span.end; i++) {                 \
00153       GLint s = FixedToInt(span.intTex[0]) & smask;         \
00154       GLint t = FixedToInt(span.intTex[1]) & tmask;         \
00155       GLint pos = (t << twidth_log2) + s;               \
00156       pos = pos + pos + pos;  /* multiply by 3 */           \
00157       rgb[i][RCOMP] = texture[pos];                 \
00158       rgb[i][GCOMP] = texture[pos+1];                   \
00159       rgb[i][BCOMP] = texture[pos+2];                   \
00160       span.intTex[0] += span.intTexStep[0];             \
00161       span.intTex[1] += span.intTexStep[1];             \
00162    }                                    \
00163    rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, rgb, NULL);
00164 
00165 #include "s_tritemp.h"
00166 
00167 
00168 
00169 /*
00170  * Render an RGB, GL_DECAL, textured triangle.
00171  * Interpolate S,T, GL_LESS depth test, w/out mipmapping or
00172  * perspective correction.
00173  * Depth buffer bits must be <= sizeof(DEFAULT_SOFTWARE_DEPTH_TYPE)
00174  *
00175  * No fog.
00176  */
00177 #define NAME simple_z_textured_triangle
00178 #define INTERP_Z 1
00179 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
00180 #define INTERP_INT_TEX 1
00181 #define S_SCALE twidth
00182 #define T_SCALE theight
00183 
00184 #define SETUP_CODE                          \
00185    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];  \
00186    struct gl_texture_object *obj =                  \
00187       ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];        \
00188    const GLint b = obj->BaseLevel;                  \
00189    const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;        \
00190    const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;      \
00191    const GLint twidth_log2 = obj->Image[0][b]->WidthLog2;       \
00192    const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data; \
00193    const GLint smask = obj->Image[0][b]->Width - 1;         \
00194    const GLint tmask = obj->Image[0][b]->Height - 1;            \
00195    if (!rb || !texture) {                       \
00196       return;                               \
00197    }
00198 
00199 #define RENDER_SPAN( span )                     \
00200    GLuint i;                                    \
00201    GLchan rgb[MAX_WIDTH][3];                        \
00202    span.intTex[0] -= FIXED_HALF; /* off-by-one error? */        \
00203    span.intTex[1] -= FIXED_HALF;                    \
00204    for (i = 0; i < span.end; i++) {                 \
00205       const GLuint z = FixedToDepth(span.z);                \
00206       if (z < zRow[i]) {                        \
00207          GLint s = FixedToInt(span.intTex[0]) & smask;          \
00208          GLint t = FixedToInt(span.intTex[1]) & tmask;          \
00209          GLint pos = (t << twidth_log2) + s;                \
00210          pos = pos + pos + pos;  /* multiply by 3 */            \
00211          rgb[i][RCOMP] = texture[pos];                  \
00212          rgb[i][GCOMP] = texture[pos+1];                \
00213          rgb[i][BCOMP] = texture[pos+2];                \
00214          zRow[i] = z;                           \
00215          span.array->mask[i] = 1;                   \
00216       }                                 \
00217       else {                                \
00218          span.array->mask[i] = 0;                   \
00219       }                                 \
00220       span.intTex[0] += span.intTexStep[0];             \
00221       span.intTex[1] += span.intTexStep[1];             \
00222       span.z += span.zStep;                     \
00223    }                                    \
00224    rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, rgb, span.array->mask);
00225 
00226 #include "s_tritemp.h"
00227 
00228 
00229 #if CHAN_TYPE != GL_FLOAT
00230 
00231 struct affine_info
00232 {
00233    GLenum filter;
00234    GLenum format;
00235    GLenum envmode;
00236    GLint smask, tmask;
00237    GLint twidth_log2;
00238    const GLchan *texture;
00239    GLfixed er, eg, eb, ea;
00240    GLint tbytesline, tsize;
00241 };
00242 
00243 
00244 static INLINE GLint
00245 ilerp(GLint t, GLint a, GLint b)
00246 {
00247    return a + ((t * (b - a)) >> FIXED_SHIFT);
00248 }
00249 
00250 static INLINE GLint
00251 ilerp_2d(GLint ia, GLint ib, GLint v00, GLint v10, GLint v01, GLint v11)
00252 {
00253    const GLint temp0 = ilerp(ia, v00, v10);
00254    const GLint temp1 = ilerp(ia, v01, v11);
00255    return ilerp(ib, temp0, temp1);
00256 }
00257 
00258 
00259 /* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA
00260  * textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
00261  * texture env modes.
00262  */
00263 static INLINE void
00264 affine_span(GLcontext *ctx, SWspan *span,
00265             struct affine_info *info)
00266 {
00267    GLchan sample[4];  /* the filtered texture sample */
00268    const GLuint texEnableSave = ctx->Texture._EnabledUnits;
00269 
00270    /* Instead of defining a function for each mode, a test is done
00271     * between the outer and inner loops. This is to reduce code size
00272     * and complexity. Observe that an optimizing compiler kills
00273     * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
00274     */
00275 
00276 #define NEAREST_RGB         \
00277    sample[RCOMP] = tex00[RCOMP];    \
00278    sample[GCOMP] = tex00[GCOMP];    \
00279    sample[BCOMP] = tex00[BCOMP];    \
00280    sample[ACOMP] = CHAN_MAX
00281 
00282 #define LINEAR_RGB                          \
00283    sample[RCOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]);\
00284    sample[GCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\
00285    sample[BCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\
00286    sample[ACOMP] = CHAN_MAX;
00287 
00288 #define NEAREST_RGBA  COPY_CHAN4(sample, tex00)
00289 
00290 #define LINEAR_RGBA                         \
00291    sample[RCOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]);\
00292    sample[GCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\
00293    sample[BCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\
00294    sample[ACOMP] = ilerp_2d(sf, tf, tex00[3], tex01[3], tex10[3], tex11[3])
00295 
00296 #define MODULATE                              \
00297    dest[RCOMP] = span->red   * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \
00298    dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \
00299    dest[BCOMP] = span->blue  * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \
00300    dest[ACOMP] = span->alpha * (sample[ACOMP] + 1u) >> (FIXED_SHIFT + 8)
00301 
00302 #define DECAL                               \
00303    dest[RCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->red +      \
00304                ((sample[ACOMP] + 1) * sample[RCOMP] << FIXED_SHIFT))    \
00305                >> (FIXED_SHIFT + 8);                    \
00306    dest[GCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->green +        \
00307                ((sample[ACOMP] + 1) * sample[GCOMP] << FIXED_SHIFT))    \
00308                >> (FIXED_SHIFT + 8);                    \
00309    dest[BCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->blue +     \
00310                ((sample[ACOMP] + 1) * sample[BCOMP] << FIXED_SHIFT))    \
00311                >> (FIXED_SHIFT + 8);                    \
00312    dest[ACOMP] = FixedToInt(span->alpha)
00313 
00314 #define BLEND                               \
00315    dest[RCOMP] = ((CHAN_MAX - sample[RCOMP]) * span->red        \
00316                + (sample[RCOMP] + 1) * info->er) >> (FIXED_SHIFT + 8);  \
00317    dest[GCOMP] = ((CHAN_MAX - sample[GCOMP]) * span->green      \
00318                + (sample[GCOMP] + 1) * info->eg) >> (FIXED_SHIFT + 8);  \
00319    dest[BCOMP] = ((CHAN_MAX - sample[BCOMP]) * span->blue       \
00320                + (sample[BCOMP] + 1) * info->eb) >> (FIXED_SHIFT + 8);  \
00321    dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8)
00322 
00323 #define REPLACE  COPY_CHAN4(dest, sample)
00324 
00325 #define ADD                             \
00326    {                                    \
00327       GLint rSum = FixedToInt(span->red)   + (GLint) sample[RCOMP]; \
00328       GLint gSum = FixedToInt(span->green) + (GLint) sample[GCOMP]; \
00329       GLint bSum = FixedToInt(span->blue)  + (GLint) sample[BCOMP]; \
00330       dest[RCOMP] = MIN2(rSum, CHAN_MAX);               \
00331       dest[GCOMP] = MIN2(gSum, CHAN_MAX);               \
00332       dest[BCOMP] = MIN2(bSum, CHAN_MAX);               \
00333       dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8); \
00334   }
00335 
00336 /* shortcuts */
00337 
00338 #define NEAREST_RGB_REPLACE     \
00339    NEAREST_RGB;             \
00340    dest[0] = sample[0];         \
00341    dest[1] = sample[1];         \
00342    dest[2] = sample[2];         \
00343    dest[3] = FixedToInt(span->alpha);
00344 
00345 #define NEAREST_RGBA_REPLACE  COPY_CHAN4(dest, tex00)
00346 
00347 #define SPAN_NEAREST(DO_TEX, COMPS)                 \
00348     for (i = 0; i < span->end; i++) {               \
00349            /* Isn't it necessary to use FixedFloor below?? */       \
00350            GLint s = FixedToInt(span->intTex[0]) & info->smask;     \
00351            GLint t = FixedToInt(span->intTex[1]) & info->tmask;     \
00352            GLint pos = (t << info->twidth_log2) + s;            \
00353            const GLchan *tex00 = info->texture + COMPS * pos;       \
00354            DO_TEX;                          \
00355            span->red += span->redStep;                  \
00356        span->green += span->greenStep;              \
00357            span->blue += span->blueStep;                \
00358        span->alpha += span->alphaStep;              \
00359        span->intTex[0] += span->intTexStep[0];          \
00360        span->intTex[1] += span->intTexStep[1];          \
00361            dest += 4;                           \
00362     }
00363 
00364 #define SPAN_LINEAR(DO_TEX, COMPS)                  \
00365     for (i = 0; i < span->end; i++) {               \
00366            /* Isn't it necessary to use FixedFloor below?? */       \
00367            const GLint s = FixedToInt(span->intTex[0]) & info->smask;   \
00368            const GLint t = FixedToInt(span->intTex[1]) & info->tmask;   \
00369            const GLfixed sf = span->intTex[0] & FIXED_FRAC_MASK;    \
00370            const GLfixed tf = span->intTex[1] & FIXED_FRAC_MASK;    \
00371            const GLint pos = (t << info->twidth_log2) + s;      \
00372            const GLchan *tex00 = info->texture + COMPS * pos;       \
00373            const GLchan *tex10 = tex00 + info->tbytesline;      \
00374            const GLchan *tex01 = tex00 + COMPS;             \
00375            const GLchan *tex11 = tex10 + COMPS;             \
00376            if (t == info->tmask) {                  \
00377               tex10 -= info->tsize;                 \
00378               tex11 -= info->tsize;                 \
00379            }                                \
00380            if (s == info->smask) {                  \
00381               tex01 -= info->tbytesline;                \
00382               tex11 -= info->tbytesline;                \
00383            }                                \
00384            DO_TEX;                          \
00385            span->red += span->redStep;                  \
00386        span->green += span->greenStep;              \
00387            span->blue += span->blueStep;                \
00388        span->alpha += span->alphaStep;              \
00389        span->intTex[0] += span->intTexStep[0];          \
00390        span->intTex[1] += span->intTexStep[1];          \
00391            dest += 4;                           \
00392     }
00393 
00394 
00395    GLuint i;
00396    GLchan *dest = span->array->rgba[0];
00397 
00398    /* Disable tex units so they're not re-applied in swrast_write_rgba_span */
00399    ctx->Texture._EnabledUnits = 0x0;
00400 
00401    span->intTex[0] -= FIXED_HALF;
00402    span->intTex[1] -= FIXED_HALF;
00403    switch (info->filter) {
00404    case GL_NEAREST:
00405       switch (info->format) {
00406       case GL_RGB:
00407          switch (info->envmode) {
00408          case GL_MODULATE:
00409             SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
00410             break;
00411          case GL_DECAL:
00412          case GL_REPLACE:
00413             SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
00414             break;
00415          case GL_BLEND:
00416             SPAN_NEAREST(NEAREST_RGB;BLEND,3);
00417             break;
00418          case GL_ADD:
00419             SPAN_NEAREST(NEAREST_RGB;ADD,3);
00420             break;
00421          default:
00422             _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
00423             return;
00424          }
00425          break;
00426       case GL_RGBA:
00427          switch(info->envmode) {
00428          case GL_MODULATE:
00429             SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
00430             break;
00431          case GL_DECAL:
00432             SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
00433             break;
00434          case GL_BLEND:
00435             SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
00436             break;
00437          case GL_ADD:
00438             SPAN_NEAREST(NEAREST_RGBA;ADD,4);
00439             break;
00440          case GL_REPLACE:
00441             SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
00442             break;
00443          default:
00444             _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
00445             return;
00446          }
00447          break;
00448       }
00449       break;
00450 
00451    case GL_LINEAR:
00452       span->intTex[0] -= FIXED_HALF;
00453       span->intTex[1] -= FIXED_HALF;
00454       switch (info->format) {
00455       case GL_RGB:
00456          switch (info->envmode) {
00457          case GL_MODULATE:
00458             SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
00459             break;
00460          case GL_DECAL:
00461          case GL_REPLACE:
00462             SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
00463             break;
00464          case GL_BLEND:
00465             SPAN_LINEAR(LINEAR_RGB;BLEND,3);
00466             break;
00467          case GL_ADD:
00468             SPAN_LINEAR(LINEAR_RGB;ADD,3);
00469             break;
00470          default:
00471             _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
00472             return;
00473          }
00474          break;
00475       case GL_RGBA:
00476          switch (info->envmode) {
00477          case GL_MODULATE:
00478             SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
00479             break;
00480          case GL_DECAL:
00481             SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
00482             break;
00483          case GL_BLEND:
00484             SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
00485             break;
00486          case GL_ADD:
00487             SPAN_LINEAR(LINEAR_RGBA;ADD,4);
00488             break;
00489          case GL_REPLACE:
00490             SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
00491             break;
00492          default:
00493             _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
00494             return;
00495          }
00496          break;
00497       }
00498       break;
00499    }
00500    span->interpMask &= ~SPAN_RGBA;
00501    ASSERT(span->arrayMask & SPAN_RGBA);
00502 
00503    _swrast_write_rgba_span(ctx, span);
00504 
00505    /* re-enable texture units */
00506    ctx->Texture._EnabledUnits = texEnableSave;
00507 
00508 #undef SPAN_NEAREST
00509 #undef SPAN_LINEAR
00510 }
00511 
00512 
00513 
00514 /*
00515  * Render an RGB/RGBA textured triangle without perspective correction.
00516  */
00517 #define NAME affine_textured_triangle
00518 #define INTERP_Z 1
00519 #define INTERP_RGB 1
00520 #define INTERP_ALPHA 1
00521 #define INTERP_INT_TEX 1
00522 #define S_SCALE twidth
00523 #define T_SCALE theight
00524 
00525 #define SETUP_CODE                          \
00526    struct affine_info info;                     \
00527    struct gl_texture_unit *unit = ctx->Texture.Unit+0;          \
00528    struct gl_texture_object *obj =                  \
00529       ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];        \
00530    const GLint b = obj->BaseLevel;                  \
00531    const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;        \
00532    const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;      \
00533    info.texture = (const GLchan *) obj->Image[0][b]->Data;      \
00534    info.twidth_log2 = obj->Image[0][b]->WidthLog2;          \
00535    info.smask = obj->Image[0][b]->Width - 1;                \
00536    info.tmask = obj->Image[0][b]->Height - 1;               \
00537    info.format = obj->Image[0][b]->_BaseFormat;             \
00538    info.filter = obj->MinFilter;                    \
00539    info.envmode = unit->EnvMode;                    \
00540    span.arrayMask |= SPAN_RGBA;                     \
00541                                     \
00542    if (info.envmode == GL_BLEND) {                  \
00543       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */    \
00544       info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF);    \
00545       info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF);    \
00546       info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF);    \
00547       info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF);    \
00548    }                                    \
00549    if (!info.texture) {                         \
00550       /* this shouldn't happen */                   \
00551       return;                               \
00552    }                                    \
00553                                     \
00554    switch (info.format) {                       \
00555    case GL_ALPHA:                           \
00556    case GL_LUMINANCE:                           \
00557    case GL_INTENSITY:                           \
00558       info.tbytesline = obj->Image[0][b]->Width;            \
00559       break;                                \
00560    case GL_LUMINANCE_ALPHA:                     \
00561       info.tbytesline = obj->Image[0][b]->Width * 2;            \
00562       break;                                \
00563    case GL_RGB:                             \
00564       info.tbytesline = obj->Image[0][b]->Width * 3;            \
00565       break;                                \
00566    case GL_RGBA:                            \
00567       info.tbytesline = obj->Image[0][b]->Width * 4;            \
00568       break;                                \
00569    default:                             \
00570       _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
00571       return;                               \
00572    }                                    \
00573    info.tsize = obj->Image[0][b]->Height * info.tbytesline;
00574 
00575 #define RENDER_SPAN( span )   affine_span(ctx, &span, &info);
00576 
00577 #include "s_tritemp.h"
00578 
00579 
00580 
00581 struct persp_info
00582 {
00583    GLenum filter;
00584    GLenum format;
00585    GLenum envmode;
00586    GLint smask, tmask;
00587    GLint twidth_log2;
00588    const GLchan *texture;
00589    GLfixed er, eg, eb, ea;   /* texture env color */
00590    GLint tbytesline, tsize;
00591 };
00592 
00593 
00594 static INLINE void
00595 fast_persp_span(GLcontext *ctx, SWspan *span,
00596         struct persp_info *info)
00597 {
00598    GLchan sample[4];  /* the filtered texture sample */
00599 
00600   /* Instead of defining a function for each mode, a test is done
00601    * between the outer and inner loops. This is to reduce code size
00602    * and complexity. Observe that an optimizing compiler kills
00603    * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
00604    */
00605 #define SPAN_NEAREST(DO_TEX,COMP)                   \
00606     for (i = 0; i < span->end; i++) {               \
00607            GLdouble invQ = tex_coord[2] ?               \
00608                                  (1.0 / tex_coord[2]) : 1.0;            \
00609            GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ);     \
00610            GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ);     \
00611            GLint s = IFLOOR(s_tmp) & info->smask;               \
00612            GLint t = IFLOOR(t_tmp) & info->tmask;               \
00613            GLint pos = (t << info->twidth_log2) + s;            \
00614            const GLchan *tex00 = info->texture + COMP * pos;        \
00615            DO_TEX;                          \
00616            span->red += span->redStep;                  \
00617        span->green += span->greenStep;              \
00618            span->blue += span->blueStep;                \
00619        span->alpha += span->alphaStep;              \
00620        tex_coord[0] += tex_step[0];                 \
00621        tex_coord[1] += tex_step[1];                 \
00622        tex_coord[2] += tex_step[2];                 \
00623            dest += 4;                           \
00624     }
00625 
00626 #define SPAN_LINEAR(DO_TEX,COMP)                    \
00627     for (i = 0; i < span->end; i++) {               \
00628            GLdouble invQ = tex_coord[2] ?               \
00629                                  (1.0 / tex_coord[2]) : 1.0;            \
00630            const GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ);   \
00631            const GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ);   \
00632            const GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF;  \
00633            const GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF;      \
00634            const GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \
00635            const GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \
00636            const GLfixed sf = s_fix & FIXED_FRAC_MASK;          \
00637            const GLfixed tf = t_fix & FIXED_FRAC_MASK;          \
00638            const GLint pos = (t << info->twidth_log2) + s;      \
00639            const GLchan *tex00 = info->texture + COMP * pos;        \
00640            const GLchan *tex10 = tex00 + info->tbytesline;      \
00641            const GLchan *tex01 = tex00 + COMP;              \
00642            const GLchan *tex11 = tex10 + COMP;              \
00643            if (t == info->tmask) {                  \
00644               tex10 -= info->tsize;                 \
00645               tex11 -= info->tsize;                 \
00646            }                                \
00647            if (s == info->smask) {                  \
00648               tex01 -= info->tbytesline;                \
00649               tex11 -= info->tbytesline;                \
00650            }                                \
00651            DO_TEX;                          \
00652            span->red   += span->redStep;                \
00653        span->green += span->greenStep;              \
00654            span->blue  += span->blueStep;               \
00655        span->alpha += span->alphaStep;              \
00656        tex_coord[0] += tex_step[0];                 \
00657        tex_coord[1] += tex_step[1];                 \
00658        tex_coord[2] += tex_step[2];                 \
00659            dest += 4;                           \
00660     }
00661 
00662    GLuint i;
00663    GLfloat tex_coord[3], tex_step[3];
00664    GLchan *dest = span->array->rgba[0];
00665 
00666    const GLuint savedTexEnable = ctx->Texture._EnabledUnits;
00667    ctx->Texture._EnabledUnits = 0;
00668 
00669    tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0]  * (info->smask + 1);
00670    tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
00671    tex_coord[1] = span->attrStart[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
00672    tex_step[1] = span->attrStepX[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
00673    /* span->attrStart[FRAG_ATTRIB_TEX0][2] only if 3D-texturing, here only 2D */
00674    tex_coord[2] = span->attrStart[FRAG_ATTRIB_TEX0][3];
00675    tex_step[2] = span->attrStepX[FRAG_ATTRIB_TEX0][3];
00676 
00677    switch (info->filter) {
00678    case GL_NEAREST:
00679       switch (info->format) {
00680       case GL_RGB:
00681          switch (info->envmode) {
00682          case GL_MODULATE:
00683             SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
00684             break;
00685          case GL_DECAL:
00686          case GL_REPLACE:
00687             SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
00688             break;
00689          case GL_BLEND:
00690             SPAN_NEAREST(NEAREST_RGB;BLEND,3);
00691             break;
00692          case GL_ADD:
00693             SPAN_NEAREST(NEAREST_RGB;ADD,3);
00694             break;
00695          default:
00696             _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
00697             return;
00698          }
00699          break;
00700       case GL_RGBA:
00701          switch(info->envmode) {
00702          case GL_MODULATE:
00703             SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
00704             break;
00705          case GL_DECAL:
00706             SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
00707             break;
00708          case GL_BLEND:
00709             SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
00710             break;
00711          case GL_ADD:
00712             SPAN_NEAREST(NEAREST_RGBA;ADD,4);
00713             break;
00714          case GL_REPLACE:
00715             SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
00716             break;
00717          default:
00718             _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
00719             return;
00720          }
00721          break;
00722       }
00723       break;
00724 
00725    case GL_LINEAR:
00726       switch (info->format) {
00727       case GL_RGB:
00728          switch (info->envmode) {
00729          case GL_MODULATE:
00730             SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
00731             break;
00732          case GL_DECAL:
00733          case GL_REPLACE:
00734             SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
00735             break;
00736          case GL_BLEND:
00737             SPAN_LINEAR(LINEAR_RGB;BLEND,3);
00738             break;
00739          case GL_ADD:
00740             SPAN_LINEAR(LINEAR_RGB;ADD,3);
00741             break;
00742          default:
00743             _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
00744             return;
00745          }
00746          break;
00747       case GL_RGBA:
00748          switch (info->envmode) {
00749          case GL_MODULATE:
00750             SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
00751             break;
00752          case GL_DECAL:
00753             SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
00754             break;
00755          case GL_BLEND:
00756             SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
00757             break;
00758          case GL_ADD:
00759             SPAN_LINEAR(LINEAR_RGBA;ADD,4);
00760             break;
00761          case GL_REPLACE:
00762             SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
00763             break;
00764          default:
00765             _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
00766             return;
00767          }
00768          break;
00769       }
00770       break;
00771    }
00772    
00773    ASSERT(span->arrayMask & SPAN_RGBA);
00774    _swrast_write_rgba_span(ctx, span);
00775 
00776 #undef SPAN_NEAREST
00777 #undef SPAN_LINEAR
00778 
00779    /* restore state */
00780    ctx->Texture._EnabledUnits = savedTexEnable;
00781 }
00782 
00783 
00784 /*
00785  * Render an perspective corrected RGB/RGBA textured triangle.
00786  * The Q (aka V in Mesa) coordinate must be zero such that the divide
00787  * by interpolated Q/W comes out right.
00788  *
00789  */
00790 #define NAME persp_textured_triangle
00791 #define INTERP_Z 1
00792 #define INTERP_RGB 1
00793 #define INTERP_ALPHA 1
00794 #define INTERP_ATTRIBS 1
00795 
00796 #define SETUP_CODE                          \
00797    struct persp_info info;                      \
00798    const struct gl_texture_unit *unit = ctx->Texture.Unit+0;        \
00799    struct gl_texture_object *obj =                  \
00800       ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];        \
00801    const GLint b = obj->BaseLevel;                  \
00802    info.texture = (const GLchan *) obj->Image[0][b]->Data;      \
00803    info.twidth_log2 = obj->Image[0][b]->WidthLog2;          \
00804    info.smask = obj->Image[0][b]->Width - 1;                \
00805    info.tmask = obj->Image[0][b]->Height - 1;               \
00806    info.format = obj->Image[0][b]->_BaseFormat;             \
00807    info.filter = obj->MinFilter;                    \
00808    info.envmode = unit->EnvMode;                    \
00809                                     \
00810    if (info.envmode == GL_BLEND) {                  \
00811       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */    \
00812       info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF);    \
00813       info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF);    \
00814       info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF);    \
00815       info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF);    \
00816    }                                    \
00817    if (!info.texture) {                         \
00818       /* this shouldn't happen */                   \
00819       return;                               \
00820    }                                    \
00821                                     \
00822    switch (info.format) {                       \
00823    case GL_ALPHA:                           \
00824    case GL_LUMINANCE:                           \
00825    case GL_INTENSITY:                           \
00826       info.tbytesline = obj->Image[0][b]->Width;            \
00827       break;                                \
00828    case GL_LUMINANCE_ALPHA:                     \
00829       info.tbytesline = obj->Image[0][b]->Width * 2;            \
00830       break;                                \
00831    case GL_RGB:                             \
00832       info.tbytesline = obj->Image[0][b]->Width * 3;            \
00833       break;                                \
00834    case GL_RGBA:                            \
00835       info.tbytesline = obj->Image[0][b]->Width * 4;            \
00836       break;                                \
00837    default:                             \
00838       _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
00839       return;                               \
00840    }                                    \
00841    info.tsize = obj->Image[0][b]->Height * info.tbytesline;
00842 
00843 #define RENDER_SPAN( span )         \
00844    span.interpMask &= ~SPAN_RGBA;       \
00845    span.arrayMask |= SPAN_RGBA;         \
00846    fast_persp_span(ctx, &span, &info);
00847 
00848 #include "s_tritemp.h"
00849 
00850 #endif /*CHAN_TYPE != GL_FLOAT*/
00851 
00852 
00853 
00854 /*
00855  * Render an RGBA triangle with arbitrary attributes.
00856  */
00857 #define NAME general_triangle
00858 #define INTERP_Z 1
00859 #define INTERP_RGB 1
00860 #define INTERP_ALPHA 1
00861 #define INTERP_ATTRIBS 1
00862 #define RENDER_SPAN( span )   _swrast_write_rgba_span(ctx, &span);
00863 #include "s_tritemp.h"
00864 
00865 
00866 
00867 
00868 /*
00869  * Special tri function for occlusion testing
00870  */
00871 #define NAME occlusion_zless_triangle
00872 #define INTERP_Z 1
00873 #define SETUP_CODE                          \
00874    struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer;      \
00875    struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;   \
00876    ASSERT(ctx->Depth.Test);                     \
00877    ASSERT(!ctx->Depth.Mask);                        \
00878    ASSERT(ctx->Depth.Func == GL_LESS);                  \
00879    if (!q) {                                \
00880       return;                               \
00881    }
00882 #define RENDER_SPAN( span )                     \
00883    if (rb->DepthBits <= 16) {                       \
00884       GLuint i;                             \
00885       const GLushort *zRow = (const GLushort *)             \
00886          rb->GetPointer(ctx, rb, span.x, span.y);           \
00887       for (i = 0; i < span.end; i++) {                  \
00888          GLuint z = FixedToDepth(span.z);               \
00889          if (z < zRow[i]) {                     \
00890             q->Result++;                        \
00891          }                              \
00892          span.z += span.zStep;                      \
00893       }                                 \
00894    }                                    \
00895    else {                               \
00896       GLuint i;                             \
00897       const GLuint *zRow = (const GLuint *)             \
00898          rb->GetPointer(ctx, rb, span.x, span.y);           \
00899       for (i = 0; i < span.end; i++) {                  \
00900          if ((GLuint)span.z < zRow[i]) {                \
00901             q->Result++;                        \
00902          }                              \
00903          span.z += span.zStep;                      \
00904       }                                 \
00905    }
00906 #include "s_tritemp.h"
00907 
00908 
00909 
00910 static void
00911 nodraw_triangle( GLcontext *ctx,
00912                  const SWvertex *v0,
00913                  const SWvertex *v1,
00914                  const SWvertex *v2 )
00915 {
00916    (void) (ctx && v0 && v1 && v2);
00917 }
00918 
00919 
00920 /*
00921  * This is used when separate specular color is enabled, but not
00922  * texturing.  We add the specular color to the primary color,
00923  * draw the triangle, then restore the original primary color.
00924  * Inefficient, but seldom needed.
00925  */
00926 void
00927 _swrast_add_spec_terms_triangle(GLcontext *ctx, const SWvertex *v0,
00928                                 const SWvertex *v1, const SWvertex *v2)
00929 {
00930    SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
00931    SWvertex *ncv1 = (SWvertex *)v1;
00932    SWvertex *ncv2 = (SWvertex *)v2;
00933    GLfloat rSum, gSum, bSum;
00934    GLchan cSave[3][4];
00935 
00936    /* save original colors */
00937    COPY_CHAN4( cSave[0], ncv0->color );
00938    COPY_CHAN4( cSave[1], ncv1->color );
00939    COPY_CHAN4( cSave[2], ncv2->color );
00940    /* sum v0 */
00941    rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
00942    gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
00943    bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
00944    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
00945    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
00946    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
00947    /* sum v1 */
00948    rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
00949    gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
00950    bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
00951    UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
00952    UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
00953    UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
00954    /* sum v2 */
00955    rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0];
00956    gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1];
00957    bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2];
00958    UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum);
00959    UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum);
00960    UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum);
00961    /* draw */
00962    SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
00963    /* restore original colors */
00964    COPY_CHAN4( ncv0->color, cSave[0] );
00965    COPY_CHAN4( ncv1->color, cSave[1] );
00966    COPY_CHAN4( ncv2->color, cSave[2] );
00967 }
00968 
00969 
00970 
00971 #ifdef DEBUG
00972 
00973 /* record the current triangle function name */
00974 const char *_mesa_triFuncName = NULL;
00975 
00976 #define USE(triFunc)                \
00977 do {                        \
00978     _mesa_triFuncName = #triFunc;       \
00979     /*printf("%s\n", _mesa_triFuncName);*/  \
00980     swrast->Triangle = triFunc;         \
00981 } while (0)
00982 
00983 #else
00984 
00985 #define USE(triFunc)  swrast->Triangle = triFunc;
00986 
00987 #endif
00988 
00989 
00990 
00991 
00992 /*
00993  * Determine which triangle rendering function to use given the current
00994  * rendering context.
00995  *
00996  * Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or
00997  * remove tests to this code.
00998  */
00999 void
01000 _swrast_choose_triangle( GLcontext *ctx )
01001 {
01002    SWcontext *swrast = SWRAST_CONTEXT(ctx);
01003    const GLboolean rgbmode = ctx->Visual.rgbMode;
01004 
01005    if (ctx->Polygon.CullFlag &&
01006        ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
01007       USE(nodraw_triangle);
01008       return;
01009    }
01010 
01011    if (ctx->RenderMode==GL_RENDER) {
01012 
01013       if (ctx->Polygon.SmoothFlag) {
01014          _swrast_set_aa_triangle_function(ctx);
01015          ASSERT(swrast->Triangle);
01016          return;
01017       }
01018 
01019       /* special case for occlusion testing */
01020       if (ctx->Query.CurrentOcclusionObject &&
01021           ctx->Depth.Test &&
01022           ctx->Depth.Mask == GL_FALSE &&
01023           ctx->Depth.Func == GL_LESS &&
01024           !ctx->Stencil.Enabled) {
01025          if ((rgbmode &&
01026               ctx->Color.ColorMask[0] == 0 &&
01027               ctx->Color.ColorMask[1] == 0 &&
01028               ctx->Color.ColorMask[2] == 0 &&
01029               ctx->Color.ColorMask[3] == 0)
01030              ||
01031              (!rgbmode && ctx->Color.IndexMask == 0)) {
01032             USE(occlusion_zless_triangle);
01033             return;
01034          }
01035       }
01036 
01037       if (!rgbmode) {
01038          USE(ci_triangle);
01039          return;
01040       }
01041 
01042       /*
01043        * XXX should examine swrast->_ActiveAttribMask to determine what
01044        * needs to be interpolated.
01045        */
01046       if (ctx->Texture._EnabledCoordUnits ||
01047           ctx->FragmentProgram._Current ||
01048           ctx->ATIFragmentShader._Enabled ||
01049           NEED_SECONDARY_COLOR(ctx) ||
01050           swrast->_FogEnabled) {
01051          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
01052          const struct gl_texture_object *texObj2D;
01053          const struct gl_texture_image *texImg;
01054          GLenum minFilter, magFilter, envMode;
01055          GLint format;
01056          texObj2D = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
01057 
01058          texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
01059          format = texImg ? texImg->TexFormat->MesaFormat : -1;
01060          minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
01061          magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
01062          envMode = ctx->Texture.Unit[0].EnvMode;
01063 
01064          /* First see if we can use an optimized 2-D texture function */
01065          if (ctx->Texture._EnabledCoordUnits == 0x1
01066              && !ctx->FragmentProgram._Current
01067              && !ctx->ATIFragmentShader._Enabled
01068              && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
01069              && texObj2D->WrapS == GL_REPEAT
01070              && texObj2D->WrapT == GL_REPEAT
01071              && texImg->_IsPowerOfTwo
01072              && texImg->Border == 0
01073              && texImg->Width == texImg->RowStride
01074              && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
01075              && minFilter == magFilter
01076              && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
01077              && !swrast->_FogEnabled
01078              && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
01079         if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
01080            if (minFilter == GL_NEAREST
01081            && format == MESA_FORMAT_RGB
01082            && (envMode == GL_REPLACE || envMode == GL_DECAL)
01083            && ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)
01084             && ctx->Depth.Func == GL_LESS
01085             && ctx->Depth.Mask == GL_TRUE)
01086                || swrast->_RasterMask == TEXTURE_BIT)
01087            && ctx->Polygon.StippleFlag == GL_FALSE
01088                    && ctx->DrawBuffer->Visual.depthBits <= 16) {
01089           if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) {
01090              USE(simple_z_textured_triangle);
01091           }
01092           else {
01093              USE(simple_textured_triangle);
01094           }
01095            }
01096            else {
01097 #if CHAN_BITS != 8
01098                   USE(general_triangle);
01099 #else
01100                   USE(affine_textured_triangle);
01101 #endif
01102            }
01103         }
01104         else {
01105 #if CHAN_BITS != 8
01106                USE(general_triangle);
01107 #else
01108                USE(persp_textured_triangle);
01109 #endif
01110         }
01111      }
01112          else {
01113             /* general case textured triangles */
01114             USE(general_triangle);
01115          }
01116       }
01117       else {
01118          ASSERT(!swrast->_FogEnabled);
01119          ASSERT(!NEED_SECONDARY_COLOR(ctx));
01120      if (ctx->Light.ShadeModel==GL_SMOOTH) {
01121         /* smooth shaded, no texturing, stippled or some raster ops */
01122 #if CHAN_BITS != 8
01123                USE(general_triangle);
01124 #else
01125                USE(smooth_rgba_triangle);
01126 #endif
01127      }
01128      else {
01129         /* flat shaded, no texturing, stippled or some raster ops */
01130 #if CHAN_BITS != 8
01131             USE(general_triangle);
01132 #else
01133             USE(flat_rgba_triangle);
01134 #endif
01135      }
01136       }
01137    }
01138    else if (ctx->RenderMode==GL_FEEDBACK) {
01139       USE(_swrast_feedback_triangle);
01140    }
01141    else {
01142       /* GL_SELECT mode */
01143       USE(_swrast_select_triangle);
01144    }
01145 }

Generated on Sat May 26 2012 04:19:34 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.