Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_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
1.7.6.1
|