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_texcombine.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  6.5.1
00004  *
00005  * Copyright (C) 1999-2006  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/context.h"
00028 #include "main/colormac.h"
00029 #include "main/image.h"
00030 #include "main/imports.h"
00031 #include "main/macros.h"
00032 #include "main/pixel.h"
00033 
00034 #include "s_context.h"
00035 #include "s_texcombine.h"
00036 
00037 
00038 #define PROD(A,B)   ( (GLuint)(A) * ((GLuint)(B)+1) )
00039 #define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
00040 #if CHAN_BITS == 32
00041 typedef GLfloat ChanTemp;
00042 #else
00043 typedef GLuint ChanTemp;
00044 #endif
00045 
00046 
00062 static void
00063 texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
00064                  CONST GLchan (*primary_rgba)[4],
00065                  CONST GLchan *texelBuffer,
00066                  GLchan (*rgba)[4] )
00067 {
00068    const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
00069    const GLchan (*argRGB [3])[4];
00070    const GLchan (*argA [3])[4];
00071    const GLuint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB;
00072    const GLuint Ashift   = textureUnit->_CurrentCombine->ScaleShiftA;
00073 #if CHAN_TYPE == GL_FLOAT
00074    const GLchan RGBmult = (GLfloat) (1 << RGBshift);
00075    const GLchan Amult = (GLfloat) (1 << Ashift);
00076 #else
00077    const GLint half = (CHAN_MAX + 1) / 2;
00078 #endif
00079    static const GLchan one[4] = { CHAN_MAX, CHAN_MAX, CHAN_MAX, CHAN_MAX };
00080    static const GLchan zero[4] = { 0, 0, 0, 0 };
00081    const GLuint numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB;
00082    const GLuint numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA;
00083    GLchan ccolor[3][MAX_WIDTH][4];
00084    GLuint i, j;
00085 
00086    ASSERT(ctx->Extensions.EXT_texture_env_combine ||
00087           ctx->Extensions.ARB_texture_env_combine);
00088    ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine);
00089 
00090    /*
00091    printf("modeRGB 0x%x  modeA 0x%x  srcRGB1 0x%x  srcA1 0x%x  srcRGB2 0x%x  srcA2 0x%x\n",
00092           textureUnit->_CurrentCombine->ModeRGB,
00093           textureUnit->_CurrentCombine->ModeA,
00094           textureUnit->_CurrentCombine->SourceRGB[0],
00095           textureUnit->_CurrentCombine->SourceA[0],
00096           textureUnit->_CurrentCombine->SourceRGB[1],
00097           textureUnit->_CurrentCombine->SourceA[1]);
00098    */
00099 
00100    /*
00101     * Do operand setup for up to 3 operands.  Loop over the terms.
00102     */
00103    for (j = 0; j < numColorArgs; j++) {
00104       const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j];
00105 
00106       switch (srcRGB) {
00107          case GL_TEXTURE:
00108             argRGB[j] = (const GLchan (*)[4])
00109                (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
00110             break;
00111          case GL_PRIMARY_COLOR:
00112             argRGB[j] = primary_rgba;
00113             break;
00114          case GL_PREVIOUS:
00115             argRGB[j] = (const GLchan (*)[4]) rgba;
00116             break;
00117          case GL_CONSTANT:
00118             {
00119                GLchan (*c)[4] = ccolor[j];
00120                GLchan red, green, blue, alpha;
00121                UNCLAMPED_FLOAT_TO_CHAN(red,   textureUnit->EnvColor[0]);
00122                UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]);
00123                UNCLAMPED_FLOAT_TO_CHAN(blue,  textureUnit->EnvColor[2]);
00124                UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
00125                for (i = 0; i < n; i++) {
00126                   c[i][RCOMP] = red;
00127                   c[i][GCOMP] = green;
00128                   c[i][BCOMP] = blue;
00129                   c[i][ACOMP] = alpha;
00130                }
00131                argRGB[j] = (const GLchan (*)[4]) ccolor[j];
00132             }
00133             break;
00134      /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
00135       */
00136      case GL_ZERO:
00137             argRGB[j] = & zero;
00138             break;
00139      case GL_ONE:
00140             argRGB[j] = & one;
00141             break;
00142          default:
00143             /* ARB_texture_env_crossbar source */
00144             {
00145                const GLuint srcUnit = srcRGB - GL_TEXTURE0;
00146                ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
00147                if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
00148                   return;
00149                argRGB[j] = (const GLchan (*)[4])
00150                   (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
00151             }
00152       }
00153 
00154       if (textureUnit->_CurrentCombine->OperandRGB[j] != GL_SRC_COLOR) {
00155          const GLchan (*src)[4] = argRGB[j];
00156          GLchan (*dst)[4] = ccolor[j];
00157 
00158          /* point to new arg[j] storage */
00159          argRGB[j] = (const GLchan (*)[4]) ccolor[j];
00160 
00161          if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) {
00162             for (i = 0; i < n; i++) {
00163                dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP];
00164                dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP];
00165                dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP];
00166             }
00167          }
00168          else if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_SRC_ALPHA) {
00169             for (i = 0; i < n; i++) {
00170                dst[i][RCOMP] = src[i][ACOMP];
00171                dst[i][GCOMP] = src[i][ACOMP];
00172                dst[i][BCOMP] = src[i][ACOMP];
00173             }
00174          }
00175          else {
00176             ASSERT(textureUnit->_CurrentCombine->OperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA);
00177             for (i = 0; i < n; i++) {
00178                dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP];
00179                dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP];
00180                dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP];
00181             }
00182          }
00183       }
00184    }
00185 
00186    /*
00187     * Set up the argA[i] pointers
00188     */
00189    for (j = 0; j < numAlphaArgs; j++) {
00190       const GLenum srcA = textureUnit->_CurrentCombine->SourceA[j];
00191 
00192       switch (srcA) {
00193          case GL_TEXTURE:
00194             argA[j] = (const GLchan (*)[4])
00195                (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
00196             break;
00197          case GL_PRIMARY_COLOR:
00198             argA[j] = primary_rgba;
00199             break;
00200          case GL_PREVIOUS:
00201             argA[j] = (const GLchan (*)[4]) rgba;
00202             break;
00203          case GL_CONSTANT:
00204             {
00205                GLchan alpha, (*c)[4] = ccolor[j];
00206                UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
00207                for (i = 0; i < n; i++)
00208                   c[i][ACOMP] = alpha;
00209                argA[j] = (const GLchan (*)[4]) ccolor[j];
00210             }
00211             break;
00212      /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
00213       */
00214      case GL_ZERO:
00215             argA[j] = & zero;
00216             break;
00217      case GL_ONE:
00218             argA[j] = & one;
00219             break;
00220          default:
00221             /* ARB_texture_env_crossbar source */
00222             {
00223                const GLuint srcUnit = srcA - GL_TEXTURE0;
00224                ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
00225                if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
00226                   return;
00227                argA[j] = (const GLchan (*)[4])
00228                   (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
00229             }
00230       }
00231 
00232       if (textureUnit->_CurrentCombine->OperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
00233          const GLchan (*src)[4] = argA[j];
00234          GLchan (*dst)[4] = ccolor[j];
00235          argA[j] = (const GLchan (*)[4]) ccolor[j];
00236          for (i = 0; i < n; i++) {
00237             dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP];
00238          }
00239       }
00240    }
00241 
00242    /*
00243     * Do the texture combine.
00244     */
00245    switch (textureUnit->_CurrentCombine->ModeRGB) {
00246       case GL_REPLACE:
00247          {
00248             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00249             if (RGBshift) {
00250                for (i = 0; i < n; i++) {
00251 #if CHAN_TYPE == GL_FLOAT
00252                   rgba[i][RCOMP] = arg0[i][RCOMP] * RGBmult;
00253                   rgba[i][GCOMP] = arg0[i][GCOMP] * RGBmult;
00254                   rgba[i][BCOMP] = arg0[i][BCOMP] * RGBmult;
00255 #else
00256                   GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift;
00257                   GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift;
00258                   GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift;
00259                   rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
00260                   rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
00261                   rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
00262 #endif
00263                }
00264             }
00265             else {
00266                for (i = 0; i < n; i++) {
00267                   rgba[i][RCOMP] = arg0[i][RCOMP];
00268                   rgba[i][GCOMP] = arg0[i][GCOMP];
00269                   rgba[i][BCOMP] = arg0[i][BCOMP];
00270                }
00271             }
00272          }
00273          break;
00274       case GL_MODULATE:
00275          {
00276             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00277             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00278 #if CHAN_TYPE != GL_FLOAT
00279             const GLint shift = CHAN_BITS - RGBshift;
00280 #endif
00281             for (i = 0; i < n; i++) {
00282 #if CHAN_TYPE == GL_FLOAT
00283                rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * RGBmult;
00284                rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * RGBmult;
00285                rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * RGBmult;
00286 #else
00287                GLuint r = PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift;
00288                GLuint g = PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift;
00289                GLuint b = PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift;
00290                rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
00291                rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
00292                rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
00293 #endif
00294             }
00295          }
00296          break;
00297       case GL_ADD:
00298          {
00299             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00300             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00301             for (i = 0; i < n; i++) {
00302 #if CHAN_TYPE == GL_FLOAT
00303                rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * RGBmult;
00304                rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * RGBmult;
00305                rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * RGBmult;
00306 #else
00307                GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift;
00308                GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift;
00309                GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift;
00310                rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
00311                rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
00312                rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
00313 #endif
00314             }
00315          }
00316          break;
00317       case GL_ADD_SIGNED:
00318          {
00319             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00320             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00321             for (i = 0; i < n; i++) {
00322 #if CHAN_TYPE == GL_FLOAT
00323                rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * RGBmult;
00324                rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult;
00325                rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult;
00326 #else
00327                GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] -half;
00328                GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] -half;
00329                GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] -half;
00330                r = (r < 0) ? 0 : r << RGBshift;
00331                g = (g < 0) ? 0 : g << RGBshift;
00332                b = (b < 0) ? 0 : b << RGBshift;
00333                rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
00334                rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
00335                rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
00336 #endif
00337             }
00338          }
00339          break;
00340       case GL_INTERPOLATE:
00341          {
00342             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00343             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00344             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
00345 #if CHAN_TYPE != GL_FLOAT
00346             const GLint shift = CHAN_BITS - RGBshift;
00347 #endif
00348             for (i = 0; i < n; i++) {
00349 #if CHAN_TYPE == GL_FLOAT
00350                rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] +
00351                       arg1[i][RCOMP] * (CHAN_MAXF - arg2[i][RCOMP])) * RGBmult;
00352                rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] +
00353                       arg1[i][GCOMP] * (CHAN_MAXF - arg2[i][GCOMP])) * RGBmult;
00354                rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] +
00355                       arg1[i][BCOMP] * (CHAN_MAXF - arg2[i][BCOMP])) * RGBmult;
00356 #else
00357                GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP])
00358                            + PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP]))
00359                               >> shift;
00360                GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP])
00361                            + PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP]))
00362                               >> shift;
00363                GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP])
00364                            + PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP]))
00365                               >> shift;
00366                rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
00367                rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
00368                rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
00369 #endif
00370             }
00371          }
00372          break;
00373       case GL_SUBTRACT:
00374          {
00375             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00376             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00377             for (i = 0; i < n; i++) {
00378 #if CHAN_TYPE == GL_FLOAT
00379                rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * RGBmult;
00380                rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * RGBmult;
00381                rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * RGBmult;
00382 #else
00383                GLint r = ((GLint) arg0[i][RCOMP] - (GLint) arg1[i][RCOMP]) << RGBshift;
00384                GLint g = ((GLint) arg0[i][GCOMP] - (GLint) arg1[i][GCOMP]) << RGBshift;
00385                GLint b = ((GLint) arg0[i][BCOMP] - (GLint) arg1[i][BCOMP]) << RGBshift;
00386                rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
00387                rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
00388                rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
00389 #endif
00390             }
00391          }
00392          break;
00393       case GL_DOT3_RGB_EXT:
00394       case GL_DOT3_RGBA_EXT:
00395          {
00396             /* Do not scale the result by 1 2 or 4 */
00397             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00398             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00399             for (i = 0; i < n; i++) {
00400 #if CHAN_TYPE == GL_FLOAT
00401                GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
00402                              (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
00403                              (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
00404                             * 4.0F;
00405                dot = CLAMP(dot, 0.0F, CHAN_MAXF);
00406 #else
00407                GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half,
00408                    (GLint)arg1[i][RCOMP] - half) +
00409                 S_PROD((GLint)arg0[i][GCOMP] - half,
00410                    (GLint)arg1[i][GCOMP] - half) +
00411                 S_PROD((GLint)arg0[i][BCOMP] - half,
00412                    (GLint)arg1[i][BCOMP] - half)) >> 6;
00413                dot = CLAMP(dot, 0, CHAN_MAX);
00414 #endif
00415                rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot;
00416             }
00417          }
00418          break;
00419       case GL_DOT3_RGB:
00420       case GL_DOT3_RGBA:
00421          {
00422             /* DO scale the result by 1 2 or 4 */
00423             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00424             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00425             for (i = 0; i < n; i++) {
00426 #if CHAN_TYPE == GL_FLOAT
00427                GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
00428                              (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
00429                              (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
00430                             * 4.0F * RGBmult;
00431                dot = CLAMP(dot, 0.0, CHAN_MAXF);
00432 #else
00433                GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half,
00434                    (GLint)arg1[i][RCOMP] - half) +
00435                 S_PROD((GLint)arg0[i][GCOMP] - half,
00436                    (GLint)arg1[i][GCOMP] - half) +
00437                 S_PROD((GLint)arg0[i][BCOMP] - half,
00438                    (GLint)arg1[i][BCOMP] - half)) >> 6;
00439                dot <<= RGBshift;
00440                dot = CLAMP(dot, 0, CHAN_MAX);
00441 #endif
00442                rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot;
00443             }
00444          }
00445          break;
00446       case GL_MODULATE_ADD_ATI:
00447          {
00448             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00449             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00450             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
00451 #if CHAN_TYPE != GL_FLOAT
00452             const GLint shift = CHAN_BITS - RGBshift;
00453 #endif
00454             for (i = 0; i < n; i++) {
00455 #if CHAN_TYPE == GL_FLOAT
00456                rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * RGBmult;
00457                rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * RGBmult;
00458                rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * RGBmult;
00459 #else
00460                GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP])
00461                            + ((GLuint) arg1[i][RCOMP] << CHAN_BITS)) >> shift;
00462                GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP])
00463                            + ((GLuint) arg1[i][GCOMP] << CHAN_BITS)) >> shift;
00464                GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP])
00465                            + ((GLuint) arg1[i][BCOMP] << CHAN_BITS)) >> shift;
00466                rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
00467                rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
00468                rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
00469 #endif
00470             }
00471      }
00472          break;
00473       case GL_MODULATE_SIGNED_ADD_ATI:
00474          {
00475             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00476             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00477             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
00478 #if CHAN_TYPE != GL_FLOAT
00479             const GLint shift = CHAN_BITS - RGBshift;
00480 #endif
00481             for (i = 0; i < n; i++) {
00482 #if CHAN_TYPE == GL_FLOAT
00483                rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5) * RGBmult;
00484                rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5) * RGBmult;
00485                rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5) * RGBmult;
00486 #else
00487                GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP])
00488               + (((GLint) arg1[i][RCOMP] - half) << CHAN_BITS))
00489             >> shift;
00490                GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP])
00491               + (((GLint) arg1[i][GCOMP] - half) << CHAN_BITS))
00492             >> shift;
00493                GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP])
00494               + (((GLint) arg1[i][BCOMP] - half) << CHAN_BITS))
00495             >> shift;
00496                rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
00497                rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
00498                rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
00499 #endif
00500             }
00501      }
00502          break;
00503       case GL_MODULATE_SUBTRACT_ATI:
00504          {
00505             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
00506             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
00507             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
00508 #if CHAN_TYPE != GL_FLOAT
00509             const GLint shift = CHAN_BITS - RGBshift;
00510 #endif
00511             for (i = 0; i < n; i++) {
00512 #if CHAN_TYPE == GL_FLOAT
00513                rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * RGBmult;
00514                rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * RGBmult;
00515                rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * RGBmult;
00516 #else
00517                GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP])
00518               - ((GLint) arg1[i][RCOMP] << CHAN_BITS))
00519             >> shift;
00520                GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP])
00521               - ((GLint) arg1[i][GCOMP] << CHAN_BITS))
00522             >> shift;
00523                GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP])
00524               - ((GLint) arg1[i][BCOMP] << CHAN_BITS))
00525             >> shift;
00526                rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
00527                rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
00528                rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
00529 #endif
00530             }
00531      }
00532          break;
00533       default:
00534          _mesa_problem(ctx, "invalid combine mode");
00535    }
00536 
00537    switch (textureUnit->_CurrentCombine->ModeA) {
00538       case GL_REPLACE:
00539          {
00540             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00541             if (Ashift) {
00542                for (i = 0; i < n; i++) {
00543 #if CHAN_TYPE == GL_FLOAT
00544                   GLchan a = arg0[i][ACOMP] * Amult;
00545 #else
00546                   GLuint a = (GLuint) arg0[i][ACOMP] << Ashift;
00547 #endif
00548                   rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
00549                }
00550             }
00551             else {
00552                for (i = 0; i < n; i++) {
00553                   rgba[i][ACOMP] = arg0[i][ACOMP];
00554                }
00555             }
00556          }
00557          break;
00558       case GL_MODULATE:
00559          {
00560             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00561             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00562 #if CHAN_TYPE != GL_FLOAT
00563             const GLint shift = CHAN_BITS - Ashift;
00564 #endif
00565             for (i = 0; i < n; i++) {
00566 #if CHAN_TYPE == GL_FLOAT
00567                rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * Amult;
00568 #else
00569                GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift);
00570                rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
00571 #endif
00572             }
00573          }
00574          break;
00575       case GL_ADD:
00576          {
00577             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00578             const GLchan  (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00579             for (i = 0; i < n; i++) {
00580 #if CHAN_TYPE == GL_FLOAT
00581                rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult;
00582 #else
00583                GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift;
00584                rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
00585 #endif
00586             }
00587          }
00588          break;
00589       case GL_ADD_SIGNED:
00590          {
00591             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00592             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00593             for (i = 0; i < n; i++) {
00594 #if CHAN_TYPE == GL_FLOAT
00595                rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * Amult;
00596 #else
00597                GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half;
00598                a = (a < 0) ? 0 : a << Ashift;
00599                rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
00600 #endif
00601             }
00602          }
00603          break;
00604       case GL_INTERPOLATE:
00605          {
00606             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00607             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00608             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
00609 #if CHAN_TYPE != GL_FLOAT
00610             const GLint shift = CHAN_BITS - Ashift;
00611 #endif
00612             for (i=0; i<n; i++) {
00613 #if CHAN_TYPE == GL_FLOAT
00614                rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] +
00615                                  arg1[i][ACOMP] * (CHAN_MAXF - arg2[i][ACOMP]))
00616                                 * Amult;
00617 #else
00618                GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP])
00619                            + PROD(arg1[i][ACOMP], CHAN_MAX - arg2[i][ACOMP]))
00620                               >> shift;
00621                rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
00622 #endif
00623             }
00624          }
00625          break;
00626       case GL_SUBTRACT:
00627          {
00628             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00629             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00630             for (i = 0; i < n; i++) {
00631 #if CHAN_TYPE == GL_FLOAT
00632                rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * Amult;
00633 #else
00634                GLint a = ((GLint) arg0[i][ACOMP] - (GLint) arg1[i][ACOMP]) << Ashift;
00635                rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
00636 #endif
00637             }
00638          }
00639          break;
00640       case GL_MODULATE_ADD_ATI:
00641          {
00642             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00643             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00644             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
00645 #if CHAN_TYPE != GL_FLOAT
00646             const GLint shift = CHAN_BITS - Ashift;
00647 #endif
00648             for (i = 0; i < n; i++) {
00649 #if CHAN_TYPE == GL_FLOAT
00650                rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * Amult;
00651 #else
00652                GLint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP])
00653                + ((GLuint) arg1[i][ACOMP] << CHAN_BITS))
00654             >> shift;
00655                rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
00656 #endif
00657             }
00658          }
00659          break;
00660       case GL_MODULATE_SIGNED_ADD_ATI:
00661          {
00662             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00663             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00664             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
00665 #if CHAN_TYPE != GL_FLOAT
00666             const GLint shift = CHAN_BITS - Ashift;
00667 #endif
00668             for (i = 0; i < n; i++) {
00669 #if CHAN_TYPE == GL_FLOAT
00670                rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * Amult;
00671 #else
00672                GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP])
00673               + (((GLint) arg1[i][ACOMP] - half) << CHAN_BITS))
00674             >> shift;
00675                rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
00676 #endif
00677             }
00678          }
00679          break;
00680       case GL_MODULATE_SUBTRACT_ATI:
00681          {
00682             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
00683             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
00684             const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
00685 #if CHAN_TYPE != GL_FLOAT
00686             const GLint shift = CHAN_BITS - Ashift;
00687 #endif
00688             for (i = 0; i < n; i++) {
00689 #if CHAN_TYPE == GL_FLOAT
00690                rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * Amult;
00691 #else
00692                GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 
00693               - ((GLint) arg1[i][ACOMP] << CHAN_BITS))
00694             >> shift;
00695                rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
00696 #endif
00697             }
00698          }
00699          break;
00700       default:
00701          _mesa_problem(ctx, "invalid combine mode");
00702    }
00703 
00704    /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining.
00705     * This is kind of a kludge.  It would have been better if the spec
00706     * were written such that the GL_COMBINE_ALPHA value could be set to
00707     * GL_DOT3.
00708     */
00709    if (textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT ||
00710        textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) {
00711       for (i = 0; i < n; i++) {
00712      rgba[i][ACOMP] = rgba[i][RCOMP];
00713       }
00714    }
00715 }
00716 #undef PROD
00717 
00718 
00730 static void
00731 texture_apply( const GLcontext *ctx,
00732                const struct gl_texture_unit *texUnit,
00733                GLuint n,
00734                CONST GLchan primary_rgba[][4], CONST GLchan texel[][4],
00735                GLchan rgba[][4] )
00736 {
00737    GLint baseLevel;
00738    GLuint i;
00739    GLchan Rc, Gc, Bc, Ac;
00740    GLenum format;
00741    (void) primary_rgba;
00742 
00743    ASSERT(texUnit);
00744    ASSERT(texUnit->_Current);
00745 
00746    baseLevel = texUnit->_Current->BaseLevel;
00747    ASSERT(texUnit->_Current->Image[0][baseLevel]);
00748 
00749    format = texUnit->_Current->Image[0][baseLevel]->_BaseFormat;
00750 
00751    if (format == GL_COLOR_INDEX || format == GL_YCBCR_MESA) {
00752       format = GL_RGBA;  /* a bit of a hack */
00753    }
00754    else if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
00755       format = texUnit->_Current->DepthMode;
00756    }
00757 
00758    switch (texUnit->EnvMode) {
00759       case GL_REPLACE:
00760      switch (format) {
00761         case GL_ALPHA:
00762            for (i=0;i<n;i++) {
00763           /* Cv = Cf */
00764                   /* Av = At */
00765                   rgba[i][ACOMP] = texel[i][ACOMP];
00766            }
00767            break;
00768         case GL_LUMINANCE:
00769            for (i=0;i<n;i++) {
00770           /* Cv = Lt */
00771                   GLchan Lt = texel[i][RCOMP];
00772                   rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
00773                   /* Av = Af */
00774            }
00775            break;
00776         case GL_LUMINANCE_ALPHA:
00777            for (i=0;i<n;i++) {
00778                   GLchan Lt = texel[i][RCOMP];
00779           /* Cv = Lt */
00780           rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
00781           /* Av = At */
00782           rgba[i][ACOMP] = texel[i][ACOMP];
00783            }
00784            break;
00785         case GL_INTENSITY:
00786            for (i=0;i<n;i++) {
00787           /* Cv = It */
00788                   GLchan It = texel[i][RCOMP];
00789                   rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It;
00790                   /* Av = It */
00791                   rgba[i][ACOMP] = It;
00792            }
00793            break;
00794         case GL_RGB:
00795            for (i=0;i<n;i++) {
00796           /* Cv = Ct */
00797           rgba[i][RCOMP] = texel[i][RCOMP];
00798           rgba[i][GCOMP] = texel[i][GCOMP];
00799           rgba[i][BCOMP] = texel[i][BCOMP];
00800           /* Av = Af */
00801            }
00802            break;
00803         case GL_RGBA:
00804            for (i=0;i<n;i++) {
00805           /* Cv = Ct */
00806           rgba[i][RCOMP] = texel[i][RCOMP];
00807           rgba[i][GCOMP] = texel[i][GCOMP];
00808           rgba[i][BCOMP] = texel[i][BCOMP];
00809           /* Av = At */
00810           rgba[i][ACOMP] = texel[i][ACOMP];
00811            }
00812            break;
00813             default:
00814                _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
00815                return;
00816      }
00817      break;
00818 
00819       case GL_MODULATE:
00820          switch (format) {
00821         case GL_ALPHA:
00822            for (i=0;i<n;i++) {
00823           /* Cv = Cf */
00824           /* Av = AfAt */
00825           rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
00826            }
00827            break;
00828         case GL_LUMINANCE:
00829            for (i=0;i<n;i++) {
00830           /* Cv = LtCf */
00831                   GLchan Lt = texel[i][RCOMP];
00832           rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt );
00833           rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt );
00834           rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt );
00835           /* Av = Af */
00836            }
00837            break;
00838         case GL_LUMINANCE_ALPHA:
00839            for (i=0;i<n;i++) {
00840           /* Cv = CfLt */
00841                   GLchan Lt = texel[i][RCOMP];
00842           rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt );
00843           rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt );
00844           rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt );
00845           /* Av = AfAt */
00846           rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
00847            }
00848            break;
00849         case GL_INTENSITY:
00850            for (i=0;i<n;i++) {
00851           /* Cv = CfIt */
00852                   GLchan It = texel[i][RCOMP];
00853           rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], It );
00854           rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], It );
00855           rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], It );
00856           /* Av = AfIt */
00857           rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], It );
00858            }
00859            break;
00860         case GL_RGB:
00861            for (i=0;i<n;i++) {
00862           /* Cv = CfCt */
00863           rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] );
00864           rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] );
00865           rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] );
00866           /* Av = Af */
00867            }
00868            break;
00869         case GL_RGBA:
00870            for (i=0;i<n;i++) {
00871           /* Cv = CfCt */
00872           rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] );
00873           rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] );
00874           rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] );
00875           /* Av = AfAt */
00876           rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
00877            }
00878            break;
00879             default:
00880                _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
00881                return;
00882      }
00883      break;
00884 
00885       case GL_DECAL:
00886          switch (format) {
00887             case GL_ALPHA:
00888             case GL_LUMINANCE:
00889             case GL_LUMINANCE_ALPHA:
00890             case GL_INTENSITY:
00891                /* undefined */
00892                break;
00893         case GL_RGB:
00894            for (i=0;i<n;i++) {
00895           /* Cv = Ct */
00896           rgba[i][RCOMP] = texel[i][RCOMP];
00897           rgba[i][GCOMP] = texel[i][GCOMP];
00898           rgba[i][BCOMP] = texel[i][BCOMP];
00899           /* Av = Af */
00900            }
00901            break;
00902         case GL_RGBA:
00903            for (i=0;i<n;i++) {
00904           /* Cv = Cf(1-At) + CtAt */
00905           GLchan t = texel[i][ACOMP], s = CHAN_MAX - t;
00906           rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(texel[i][RCOMP],t);
00907           rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(texel[i][GCOMP],t);
00908           rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(texel[i][BCOMP],t);
00909           /* Av = Af */
00910            }
00911            break;
00912             default:
00913                _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
00914                return;
00915      }
00916      break;
00917 
00918       case GL_BLEND:
00919          UNCLAMPED_FLOAT_TO_CHAN(Rc, texUnit->EnvColor[0]);
00920          UNCLAMPED_FLOAT_TO_CHAN(Gc, texUnit->EnvColor[1]);
00921          UNCLAMPED_FLOAT_TO_CHAN(Bc, texUnit->EnvColor[2]);
00922          UNCLAMPED_FLOAT_TO_CHAN(Ac, texUnit->EnvColor[3]);
00923      switch (format) {
00924         case GL_ALPHA:
00925            for (i=0;i<n;i++) {
00926           /* Cv = Cf */
00927           /* Av = AfAt */
00928                   rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
00929            }
00930            break;
00931             case GL_LUMINANCE:
00932            for (i=0;i<n;i++) {
00933           /* Cv = Cf(1-Lt) + CcLt */
00934           GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt;
00935           rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt);
00936           rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt);
00937           rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt);
00938           /* Av = Af */
00939            }
00940            break;
00941         case GL_LUMINANCE_ALPHA:
00942            for (i=0;i<n;i++) {
00943           /* Cv = Cf(1-Lt) + CcLt */
00944           GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt;
00945           rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt);
00946           rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt);
00947           rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt);
00948           /* Av = AfAt */
00949           rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]);
00950            }
00951            break;
00952             case GL_INTENSITY:
00953            for (i=0;i<n;i++) {
00954           /* Cv = Cf(1-It) + CcIt */
00955           GLchan It = texel[i][RCOMP], s = CHAN_MAX - It;
00956           rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, It);
00957           rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, It);
00958           rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, It);
00959                   /* Av = Af(1-It) + Ac*It */
00960                   rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], s) + CHAN_PRODUCT(Ac, It);
00961                }
00962                break;
00963         case GL_RGB:
00964            for (i=0;i<n;i++) {
00965           /* Cv = Cf(1-Ct) + CcCt */
00966           rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]);
00967           rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]);
00968           rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]);
00969           /* Av = Af */
00970            }
00971            break;
00972         case GL_RGBA:
00973            for (i=0;i<n;i++) {
00974           /* Cv = Cf(1-Ct) + CcCt */
00975           rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]);
00976           rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]);
00977           rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]);
00978           /* Av = AfAt */
00979           rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]);
00980            }
00981            break;
00982             default:
00983                _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
00984                return;
00985      }
00986      break;
00987 
00988      /* XXX don't clamp results if GLchan is float??? */
00989 
00990       case GL_ADD:  /* GL_EXT_texture_add_env */
00991          switch (format) {
00992             case GL_ALPHA:
00993                for (i=0;i<n;i++) {
00994                   /* Rv = Rf */
00995                   /* Gv = Gf */
00996                   /* Bv = Bf */
00997                   rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
00998                }
00999                break;
01000             case GL_LUMINANCE:
01001                for (i=0;i<n;i++) {
01002                   ChanTemp Lt = texel[i][RCOMP];
01003                   ChanTemp r = rgba[i][RCOMP] + Lt;
01004                   ChanTemp g = rgba[i][GCOMP] + Lt;
01005                   ChanTemp b = rgba[i][BCOMP] + Lt;
01006                   rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
01007                   rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
01008                   rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
01009                   /* Av = Af */
01010                }
01011                break;
01012             case GL_LUMINANCE_ALPHA:
01013                for (i=0;i<n;i++) {
01014                   ChanTemp Lt = texel[i][RCOMP];
01015                   ChanTemp r = rgba[i][RCOMP] + Lt;
01016                   ChanTemp g = rgba[i][GCOMP] + Lt;
01017                   ChanTemp b = rgba[i][BCOMP] + Lt;
01018                   rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
01019                   rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
01020                   rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
01021                   rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
01022                }
01023                break;
01024             case GL_INTENSITY:
01025                for (i=0;i<n;i++) {
01026                   GLchan It = texel[i][RCOMP];
01027                   ChanTemp r = rgba[i][RCOMP] + It;
01028                   ChanTemp g = rgba[i][GCOMP] + It;
01029                   ChanTemp b = rgba[i][BCOMP] + It;
01030                   ChanTemp a = rgba[i][ACOMP] + It;
01031                   rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
01032                   rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
01033                   rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
01034                   rgba[i][ACOMP] = MIN2(a, CHAN_MAX);
01035                }
01036                break;
01037         case GL_RGB:
01038            for (i=0;i<n;i++) {
01039                   ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP];
01040                   ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP];
01041                   ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP];
01042           rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
01043           rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
01044           rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
01045           /* Av = Af */
01046            }
01047            break;
01048         case GL_RGBA:
01049            for (i=0;i<n;i++) {
01050                   ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP];
01051                   ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP];
01052                   ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP];
01053           rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
01054           rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
01055           rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
01056                   rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
01057                }
01058                break;
01059             default:
01060                _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
01061                return;
01062      }
01063      break;
01064 
01065       default:
01066          _mesa_problem(ctx, "Bad env mode in texture_apply");
01067          return;
01068    }
01069 }
01070 
01071 
01072 
01076 void
01077 _swrast_texture_span( GLcontext *ctx, SWspan *span )
01078 {
01079    SWcontext *swrast = SWRAST_CONTEXT(ctx);
01080    GLchan primary_rgba[MAX_WIDTH][4];
01081    GLuint unit;
01082 
01083    ASSERT(span->end < MAX_WIDTH);
01084 
01085    /*
01086     * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
01087     */
01088    if (swrast->_AnyTextureCombine)
01089       MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan));
01090 
01091    /*
01092     * Must do all texture sampling before combining in order to
01093     * accomodate GL_ARB_texture_env_crossbar.
01094     */
01095    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
01096       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
01097          const GLfloat (*texcoords)[4]
01098             = (const GLfloat (*)[4])
01099             span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
01100          const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
01101          const struct gl_texture_object *curObj = texUnit->_Current;
01102          GLfloat *lambda = span->array->lambda[unit];
01103          GLchan (*texels)[4] = (GLchan (*)[4])
01104             (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
01105 
01106          /* adjust texture lod (lambda) */
01107          if (span->arrayMask & SPAN_LAMBDA) {
01108             if (texUnit->LodBias + curObj->LodBias != 0.0F) {
01109                /* apply LOD bias, but don't clamp yet */
01110                const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias,
01111                                           -ctx->Const.MaxTextureLodBias,
01112                                           ctx->Const.MaxTextureLodBias);
01113                GLuint i;
01114                for (i = 0; i < span->end; i++) {
01115                   lambda[i] += bias;
01116                }
01117             }
01118 
01119             if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
01120                /* apply LOD clamping to lambda */
01121                const GLfloat min = curObj->MinLod;
01122                const GLfloat max = curObj->MaxLod;
01123                GLuint i;
01124                for (i = 0; i < span->end; i++) {
01125                   GLfloat l = lambda[i];
01126                   lambda[i] = CLAMP(l, min, max);
01127                }
01128             }
01129          }
01130 
01131          /* Sample the texture (span->end = number of fragments) */
01132          swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
01133                                       texcoords, lambda, texels );
01134 
01135          /* GL_SGI_texture_color_table */
01136          if (texUnit->ColorTableEnabled) {
01137 #if CHAN_TYPE == GL_UNSIGNED_BYTE
01138             _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels);
01139 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
01140             _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels);
01141 #else
01142             _mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels);
01143 #endif
01144          }
01145       }
01146    }
01147 
01148    /*
01149     * OK, now apply the texture (aka texture combine/blend).
01150     * We modify the span->color.rgba values.
01151     */
01152    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
01153       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
01154          const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
01155          if (texUnit->_CurrentCombine != &texUnit->_EnvMode ) {
01156             texture_combine( ctx, unit, span->end,
01157                              (CONST GLchan (*)[4]) primary_rgba,
01158                              swrast->TexelBuffer,
01159                              span->array->rgba );
01160          }
01161          else {
01162             /* conventional texture blend */
01163             const GLchan (*texels)[4] = (const GLchan (*)[4])
01164                (swrast->TexelBuffer + unit *
01165                 (span->end * 4 * sizeof(GLchan)));
01166             texture_apply( ctx, texUnit, span->end,
01167                            (CONST GLchan (*)[4]) primary_rgba, texels,
01168                            span->array->rgba );
01169          }
01170       }
01171    }
01172 }

Generated on Sun May 27 2012 04:20:44 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.