s_texcombine.c revision 7117f1b4
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.1 4 * 5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26#include "glheader.h" 27#include "context.h" 28#include "colormac.h" 29#include "imports.h" 30#include "macros.h" 31#include "pixel.h" 32 33#include "s_context.h" 34#include "s_texcombine.h" 35 36 37#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) ) 38#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) ) 39#if CHAN_BITS == 32 40typedef GLfloat ChanTemp; 41#else 42typedef GLuint ChanTemp; 43#endif 44 45 46/** 47 * Do texture application for GL_ARB/EXT_texture_env_combine. 48 * This function also supports GL_{EXT,ARB}_texture_env_dot3 and 49 * GL_ATI_texture_env_combine3. Since "classic" texture environments are 50 * implemented using GL_ARB_texture_env_combine-like state, this same function 51 * is used for classic texture environment application as well. 52 * 53 * \param ctx rendering context 54 * \param textureUnit the texture unit to apply 55 * \param n number of fragments to process (span width) 56 * \param primary_rgba incoming fragment color array 57 * \param texelBuffer pointer to texel colors for all texture units 58 * 59 * \param rgba incoming colors, which get modified here 60 */ 61static void 62texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, 63 CONST GLchan (*primary_rgba)[4], 64 CONST GLchan *texelBuffer, 65 GLchan (*rgba)[4] ) 66{ 67 const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); 68 const GLchan (*argRGB [3])[4]; 69 const GLchan (*argA [3])[4]; 70 const GLuint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB; 71 const GLuint Ashift = textureUnit->_CurrentCombine->ScaleShiftA; 72#if CHAN_TYPE == GL_FLOAT 73 const GLchan RGBmult = (GLfloat) (1 << RGBshift); 74 const GLchan Amult = (GLfloat) (1 << Ashift); 75#else 76 const GLint half = (CHAN_MAX + 1) / 2; 77#endif 78 static const GLchan one[4] = { CHAN_MAX, CHAN_MAX, CHAN_MAX, CHAN_MAX }; 79 static const GLchan zero[4] = { 0, 0, 0, 0 }; 80 const GLuint numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB; 81 const GLuint numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA; 82 GLchan ccolor[3][MAX_WIDTH][4]; 83 GLuint i, j; 84 85 ASSERT(ctx->Extensions.EXT_texture_env_combine || 86 ctx->Extensions.ARB_texture_env_combine); 87 ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine); 88 89 /* 90 printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n", 91 textureUnit->_CurrentCombine->ModeRGB, 92 textureUnit->_CurrentCombine->ModeA, 93 textureUnit->_CurrentCombine->SourceRGB[0], 94 textureUnit->_CurrentCombine->SourceA[0], 95 textureUnit->_CurrentCombine->SourceRGB[1], 96 textureUnit->_CurrentCombine->SourceA[1]); 97 */ 98 99 /* 100 * Do operand setup for up to 3 operands. Loop over the terms. 101 */ 102 for (j = 0; j < numColorArgs; j++) { 103 const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j]; 104 105 switch (srcRGB) { 106 case GL_TEXTURE: 107 argRGB[j] = (const GLchan (*)[4]) 108 (texelBuffer + unit * (n * 4 * sizeof(GLchan))); 109 break; 110 case GL_PRIMARY_COLOR: 111 argRGB[j] = primary_rgba; 112 break; 113 case GL_PREVIOUS: 114 argRGB[j] = (const GLchan (*)[4]) rgba; 115 break; 116 case GL_CONSTANT: 117 { 118 GLchan (*c)[4] = ccolor[j]; 119 GLchan red, green, blue, alpha; 120 UNCLAMPED_FLOAT_TO_CHAN(red, textureUnit->EnvColor[0]); 121 UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]); 122 UNCLAMPED_FLOAT_TO_CHAN(blue, textureUnit->EnvColor[2]); 123 UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); 124 for (i = 0; i < n; i++) { 125 c[i][RCOMP] = red; 126 c[i][GCOMP] = green; 127 c[i][BCOMP] = blue; 128 c[i][ACOMP] = alpha; 129 } 130 argRGB[j] = (const GLchan (*)[4]) ccolor[j]; 131 } 132 break; 133 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. 134 */ 135 case GL_ZERO: 136 argRGB[j] = & zero; 137 break; 138 case GL_ONE: 139 argRGB[j] = & one; 140 break; 141 default: 142 /* ARB_texture_env_crossbar source */ 143 { 144 const GLuint srcUnit = srcRGB - GL_TEXTURE0; 145 ASSERT(srcUnit < ctx->Const.MaxTextureUnits); 146 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) 147 return; 148 argRGB[j] = (const GLchan (*)[4]) 149 (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); 150 } 151 } 152 153 if (textureUnit->_CurrentCombine->OperandRGB[j] != GL_SRC_COLOR) { 154 const GLchan (*src)[4] = argRGB[j]; 155 GLchan (*dst)[4] = ccolor[j]; 156 157 /* point to new arg[j] storage */ 158 argRGB[j] = (const GLchan (*)[4]) ccolor[j]; 159 160 if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) { 161 for (i = 0; i < n; i++) { 162 dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP]; 163 dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP]; 164 dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP]; 165 } 166 } 167 else if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_SRC_ALPHA) { 168 for (i = 0; i < n; i++) { 169 dst[i][RCOMP] = src[i][ACOMP]; 170 dst[i][GCOMP] = src[i][ACOMP]; 171 dst[i][BCOMP] = src[i][ACOMP]; 172 } 173 } 174 else { 175 ASSERT(textureUnit->_CurrentCombine->OperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA); 176 for (i = 0; i < n; i++) { 177 dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP]; 178 dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP]; 179 dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP]; 180 } 181 } 182 } 183 } 184 185 /* 186 * Set up the argA[i] pointers 187 */ 188 for (j = 0; j < numAlphaArgs; j++) { 189 const GLenum srcA = textureUnit->_CurrentCombine->SourceA[j]; 190 191 switch (srcA) { 192 case GL_TEXTURE: 193 argA[j] = (const GLchan (*)[4]) 194 (texelBuffer + unit * (n * 4 * sizeof(GLchan))); 195 break; 196 case GL_PRIMARY_COLOR: 197 argA[j] = primary_rgba; 198 break; 199 case GL_PREVIOUS: 200 argA[j] = (const GLchan (*)[4]) rgba; 201 break; 202 case GL_CONSTANT: 203 { 204 GLchan alpha, (*c)[4] = ccolor[j]; 205 UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); 206 for (i = 0; i < n; i++) 207 c[i][ACOMP] = alpha; 208 argA[j] = (const GLchan (*)[4]) ccolor[j]; 209 } 210 break; 211 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. 212 */ 213 case GL_ZERO: 214 argA[j] = & zero; 215 break; 216 case GL_ONE: 217 argA[j] = & one; 218 break; 219 default: 220 /* ARB_texture_env_crossbar source */ 221 { 222 const GLuint srcUnit = srcA - GL_TEXTURE0; 223 ASSERT(srcUnit < ctx->Const.MaxTextureUnits); 224 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) 225 return; 226 argA[j] = (const GLchan (*)[4]) 227 (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); 228 } 229 } 230 231 if (textureUnit->_CurrentCombine->OperandA[j] == GL_ONE_MINUS_SRC_ALPHA) { 232 const GLchan (*src)[4] = argA[j]; 233 GLchan (*dst)[4] = ccolor[j]; 234 argA[j] = (const GLchan (*)[4]) ccolor[j]; 235 for (i = 0; i < n; i++) { 236 dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP]; 237 } 238 } 239 } 240 241 /* 242 * Do the texture combine. 243 */ 244 switch (textureUnit->_CurrentCombine->ModeRGB) { 245 case GL_REPLACE: 246 { 247 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 248 if (RGBshift) { 249 for (i = 0; i < n; i++) { 250#if CHAN_TYPE == GL_FLOAT 251 rgba[i][RCOMP] = arg0[i][RCOMP] * RGBmult; 252 rgba[i][GCOMP] = arg0[i][GCOMP] * RGBmult; 253 rgba[i][BCOMP] = arg0[i][BCOMP] * RGBmult; 254#else 255 GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift; 256 GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift; 257 GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift; 258 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 259 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 260 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 261#endif 262 } 263 } 264 else { 265 for (i = 0; i < n; i++) { 266 rgba[i][RCOMP] = arg0[i][RCOMP]; 267 rgba[i][GCOMP] = arg0[i][GCOMP]; 268 rgba[i][BCOMP] = arg0[i][BCOMP]; 269 } 270 } 271 } 272 break; 273 case GL_MODULATE: 274 { 275 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 276 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 277#if CHAN_TYPE != GL_FLOAT 278 const GLint shift = CHAN_BITS - RGBshift; 279#endif 280 for (i = 0; i < n; i++) { 281#if CHAN_TYPE == GL_FLOAT 282 rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * RGBmult; 283 rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * RGBmult; 284 rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * RGBmult; 285#else 286 GLuint r = PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift; 287 GLuint g = PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift; 288 GLuint b = PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift; 289 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 290 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 291 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 292#endif 293 } 294 } 295 break; 296 case GL_ADD: 297 { 298 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 299 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 300 for (i = 0; i < n; i++) { 301#if CHAN_TYPE == GL_FLOAT 302 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * RGBmult; 303 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * RGBmult; 304 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * RGBmult; 305#else 306 GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift; 307 GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift; 308 GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift; 309 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 310 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 311 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 312#endif 313 } 314 } 315 break; 316 case GL_ADD_SIGNED: 317 { 318 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 319 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 320 for (i = 0; i < n; i++) { 321#if CHAN_TYPE == GL_FLOAT 322 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * RGBmult; 323 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult; 324 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult; 325#else 326 GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] -half; 327 GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] -half; 328 GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] -half; 329 r = (r < 0) ? 0 : r << RGBshift; 330 g = (g < 0) ? 0 : g << RGBshift; 331 b = (b < 0) ? 0 : b << RGBshift; 332 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 333 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 334 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 335#endif 336 } 337 } 338 break; 339 case GL_INTERPOLATE: 340 { 341 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 342 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 343 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 344#if CHAN_TYPE != GL_FLOAT 345 const GLint shift = CHAN_BITS - RGBshift; 346#endif 347 for (i = 0; i < n; i++) { 348#if CHAN_TYPE == GL_FLOAT 349 rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + 350 arg1[i][RCOMP] * (CHAN_MAXF - arg2[i][RCOMP])) * RGBmult; 351 rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + 352 arg1[i][GCOMP] * (CHAN_MAXF - arg2[i][GCOMP])) * RGBmult; 353 rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + 354 arg1[i][BCOMP] * (CHAN_MAXF - arg2[i][BCOMP])) * RGBmult; 355#else 356 GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 357 + PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP])) 358 >> shift; 359 GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 360 + PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP])) 361 >> shift; 362 GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 363 + PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP])) 364 >> shift; 365 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 366 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 367 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 368#endif 369 } 370 } 371 break; 372 case GL_SUBTRACT: 373 { 374 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 375 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 376 for (i = 0; i < n; i++) { 377#if CHAN_TYPE == GL_FLOAT 378 rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * RGBmult; 379 rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * RGBmult; 380 rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * RGBmult; 381#else 382 GLint r = ((GLint) arg0[i][RCOMP] - (GLint) arg1[i][RCOMP]) << RGBshift; 383 GLint g = ((GLint) arg0[i][GCOMP] - (GLint) arg1[i][GCOMP]) << RGBshift; 384 GLint b = ((GLint) arg0[i][BCOMP] - (GLint) arg1[i][BCOMP]) << RGBshift; 385 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 386 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 387 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 388#endif 389 } 390 } 391 break; 392 case GL_DOT3_RGB_EXT: 393 case GL_DOT3_RGBA_EXT: 394 { 395 /* Do not scale the result by 1 2 or 4 */ 396 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 397 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 398 for (i = 0; i < n; i++) { 399#if CHAN_TYPE == GL_FLOAT 400 GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) + 401 (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) + 402 (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F)) 403 * 4.0F; 404 dot = CLAMP(dot, 0.0F, CHAN_MAXF); 405#else 406 GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half, 407 (GLint)arg1[i][RCOMP] - half) + 408 S_PROD((GLint)arg0[i][GCOMP] - half, 409 (GLint)arg1[i][GCOMP] - half) + 410 S_PROD((GLint)arg0[i][BCOMP] - half, 411 (GLint)arg1[i][BCOMP] - half)) >> 6; 412 dot = CLAMP(dot, 0, CHAN_MAX); 413#endif 414 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; 415 } 416 } 417 break; 418 case GL_DOT3_RGB: 419 case GL_DOT3_RGBA: 420 { 421 /* DO scale the result by 1 2 or 4 */ 422 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 423 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 424 for (i = 0; i < n; i++) { 425#if CHAN_TYPE == GL_FLOAT 426 GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) + 427 (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) + 428 (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F)) 429 * 4.0F * RGBmult; 430 dot = CLAMP(dot, 0.0, CHAN_MAXF); 431#else 432 GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half, 433 (GLint)arg1[i][RCOMP] - half) + 434 S_PROD((GLint)arg0[i][GCOMP] - half, 435 (GLint)arg1[i][GCOMP] - half) + 436 S_PROD((GLint)arg0[i][BCOMP] - half, 437 (GLint)arg1[i][BCOMP] - half)) >> 6; 438 dot <<= RGBshift; 439 dot = CLAMP(dot, 0, CHAN_MAX); 440#endif 441 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; 442 } 443 } 444 break; 445 case GL_MODULATE_ADD_ATI: 446 { 447 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 448 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 449 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 450#if CHAN_TYPE != GL_FLOAT 451 const GLint shift = CHAN_BITS - RGBshift; 452#endif 453 for (i = 0; i < n; i++) { 454#if CHAN_TYPE == GL_FLOAT 455 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * RGBmult; 456 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * RGBmult; 457 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * RGBmult; 458#else 459 GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 460 + ((GLuint) arg1[i][RCOMP] << CHAN_BITS)) >> shift; 461 GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 462 + ((GLuint) arg1[i][GCOMP] << CHAN_BITS)) >> shift; 463 GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 464 + ((GLuint) arg1[i][BCOMP] << CHAN_BITS)) >> shift; 465 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 466 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 467 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 468#endif 469 } 470 } 471 break; 472 case GL_MODULATE_SIGNED_ADD_ATI: 473 { 474 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 475 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 476 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 477#if CHAN_TYPE != GL_FLOAT 478 const GLint shift = CHAN_BITS - RGBshift; 479#endif 480 for (i = 0; i < n; i++) { 481#if CHAN_TYPE == GL_FLOAT 482 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5) * RGBmult; 483 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5) * RGBmult; 484 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5) * RGBmult; 485#else 486 GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 487 + (((GLint) arg1[i][RCOMP] - half) << CHAN_BITS)) 488 >> shift; 489 GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 490 + (((GLint) arg1[i][GCOMP] - half) << CHAN_BITS)) 491 >> shift; 492 GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 493 + (((GLint) arg1[i][BCOMP] - half) << CHAN_BITS)) 494 >> shift; 495 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 496 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 497 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 498#endif 499 } 500 } 501 break; 502 case GL_MODULATE_SUBTRACT_ATI: 503 { 504 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 505 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 506 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 507#if CHAN_TYPE != GL_FLOAT 508 const GLint shift = CHAN_BITS - RGBshift; 509#endif 510 for (i = 0; i < n; i++) { 511#if CHAN_TYPE == GL_FLOAT 512 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * RGBmult; 513 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * RGBmult; 514 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * RGBmult; 515#else 516 GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 517 - ((GLint) arg1[i][RCOMP] << CHAN_BITS)) 518 >> shift; 519 GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 520 - ((GLint) arg1[i][GCOMP] << CHAN_BITS)) 521 >> shift; 522 GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 523 - ((GLint) arg1[i][BCOMP] << CHAN_BITS)) 524 >> shift; 525 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 526 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 527 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 528#endif 529 } 530 } 531 break; 532 default: 533 _mesa_problem(ctx, "invalid combine mode"); 534 } 535 536 switch (textureUnit->_CurrentCombine->ModeA) { 537 case GL_REPLACE: 538 { 539 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 540 if (Ashift) { 541 for (i = 0; i < n; i++) { 542#if CHAN_TYPE == GL_FLOAT 543 GLchan a = arg0[i][ACOMP] * Amult; 544#else 545 GLuint a = (GLuint) arg0[i][ACOMP] << Ashift; 546#endif 547 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 548 } 549 } 550 else { 551 for (i = 0; i < n; i++) { 552 rgba[i][ACOMP] = arg0[i][ACOMP]; 553 } 554 } 555 } 556 break; 557 case GL_MODULATE: 558 { 559 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 560 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 561#if CHAN_TYPE != GL_FLOAT 562 const GLint shift = CHAN_BITS - Ashift; 563#endif 564 for (i = 0; i < n; i++) { 565#if CHAN_TYPE == GL_FLOAT 566 rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * Amult; 567#else 568 GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift); 569 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 570#endif 571 } 572 } 573 break; 574 case GL_ADD: 575 { 576 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 577 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 578 for (i = 0; i < n; i++) { 579#if CHAN_TYPE == GL_FLOAT 580 rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult; 581#else 582 GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift; 583 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 584#endif 585 } 586 } 587 break; 588 case GL_ADD_SIGNED: 589 { 590 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 591 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 592 for (i = 0; i < n; i++) { 593#if CHAN_TYPE == GL_FLOAT 594 rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * Amult; 595#else 596 GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half; 597 a = (a < 0) ? 0 : a << Ashift; 598 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 599#endif 600 } 601 } 602 break; 603 case GL_INTERPOLATE: 604 { 605 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 606 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 607 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 608#if CHAN_TYPE != GL_FLOAT 609 const GLint shift = CHAN_BITS - Ashift; 610#endif 611 for (i=0; i<n; i++) { 612#if CHAN_TYPE == GL_FLOAT 613 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + 614 arg1[i][ACOMP] * (CHAN_MAXF - arg2[i][ACOMP])) 615 * Amult; 616#else 617 GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 618 + PROD(arg1[i][ACOMP], CHAN_MAX - arg2[i][ACOMP])) 619 >> shift; 620 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 621#endif 622 } 623 } 624 break; 625 case GL_SUBTRACT: 626 { 627 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 628 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 629 for (i = 0; i < n; i++) { 630#if CHAN_TYPE == GL_FLOAT 631 rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * Amult; 632#else 633 GLint a = ((GLint) arg0[i][ACOMP] - (GLint) arg1[i][ACOMP]) << Ashift; 634 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 635#endif 636 } 637 } 638 break; 639 case GL_MODULATE_ADD_ATI: 640 { 641 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 642 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 643 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 644#if CHAN_TYPE != GL_FLOAT 645 const GLint shift = CHAN_BITS - Ashift; 646#endif 647 for (i = 0; i < n; i++) { 648#if CHAN_TYPE == GL_FLOAT 649 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * Amult; 650#else 651 GLint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 652 + ((GLuint) arg1[i][ACOMP] << CHAN_BITS)) 653 >> shift; 654 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 655#endif 656 } 657 } 658 break; 659 case GL_MODULATE_SIGNED_ADD_ATI: 660 { 661 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 662 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 663 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 664#if CHAN_TYPE != GL_FLOAT 665 const GLint shift = CHAN_BITS - Ashift; 666#endif 667 for (i = 0; i < n; i++) { 668#if CHAN_TYPE == GL_FLOAT 669 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * Amult; 670#else 671 GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 672 + (((GLint) arg1[i][ACOMP] - half) << CHAN_BITS)) 673 >> shift; 674 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 675#endif 676 } 677 } 678 break; 679 case GL_MODULATE_SUBTRACT_ATI: 680 { 681 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 682 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 683 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 684#if CHAN_TYPE != GL_FLOAT 685 const GLint shift = CHAN_BITS - Ashift; 686#endif 687 for (i = 0; i < n; i++) { 688#if CHAN_TYPE == GL_FLOAT 689 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * Amult; 690#else 691 GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 692 - ((GLint) arg1[i][ACOMP] << CHAN_BITS)) 693 >> shift; 694 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 695#endif 696 } 697 } 698 break; 699 default: 700 _mesa_problem(ctx, "invalid combine mode"); 701 } 702 703 /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining. 704 * This is kind of a kludge. It would have been better if the spec 705 * were written such that the GL_COMBINE_ALPHA value could be set to 706 * GL_DOT3. 707 */ 708 if (textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT || 709 textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) { 710 for (i = 0; i < n; i++) { 711 rgba[i][ACOMP] = rgba[i][RCOMP]; 712 } 713 } 714} 715#undef PROD 716 717 718/** 719 * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND, 720 * MODULATE, or DECAL) to an array of fragments. 721 * Input: textureUnit - pointer to texture unit to apply 722 * format - base internal texture format 723 * n - number of fragments 724 * primary_rgba - primary colors (may alias rgba for single texture) 725 * texels - array of texel colors 726 * InOut: rgba - incoming fragment colors modified by texel colors 727 * according to the texture environment mode. 728 */ 729static void 730texture_apply( const GLcontext *ctx, 731 const struct gl_texture_unit *texUnit, 732 GLuint n, 733 CONST GLchan primary_rgba[][4], CONST GLchan texel[][4], 734 GLchan rgba[][4] ) 735{ 736 GLint baseLevel; 737 GLuint i; 738 GLchan Rc, Gc, Bc, Ac; 739 GLenum format; 740 (void) primary_rgba; 741 742 ASSERT(texUnit); 743 ASSERT(texUnit->_Current); 744 745 baseLevel = texUnit->_Current->BaseLevel; 746 ASSERT(texUnit->_Current->Image[0][baseLevel]); 747 748 format = texUnit->_Current->Image[0][baseLevel]->_BaseFormat; 749 750 if (format == GL_COLOR_INDEX || format == GL_YCBCR_MESA) { 751 format = GL_RGBA; /* a bit of a hack */ 752 } 753 else if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { 754 format = texUnit->_Current->DepthMode; 755 } 756 757 switch (texUnit->EnvMode) { 758 case GL_REPLACE: 759 switch (format) { 760 case GL_ALPHA: 761 for (i=0;i<n;i++) { 762 /* Cv = Cf */ 763 /* Av = At */ 764 rgba[i][ACOMP] = texel[i][ACOMP]; 765 } 766 break; 767 case GL_LUMINANCE: 768 for (i=0;i<n;i++) { 769 /* Cv = Lt */ 770 GLchan Lt = texel[i][RCOMP]; 771 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt; 772 /* Av = Af */ 773 } 774 break; 775 case GL_LUMINANCE_ALPHA: 776 for (i=0;i<n;i++) { 777 GLchan Lt = texel[i][RCOMP]; 778 /* Cv = Lt */ 779 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt; 780 /* Av = At */ 781 rgba[i][ACOMP] = texel[i][ACOMP]; 782 } 783 break; 784 case GL_INTENSITY: 785 for (i=0;i<n;i++) { 786 /* Cv = It */ 787 GLchan It = texel[i][RCOMP]; 788 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It; 789 /* Av = It */ 790 rgba[i][ACOMP] = It; 791 } 792 break; 793 case GL_RGB: 794 for (i=0;i<n;i++) { 795 /* Cv = Ct */ 796 rgba[i][RCOMP] = texel[i][RCOMP]; 797 rgba[i][GCOMP] = texel[i][GCOMP]; 798 rgba[i][BCOMP] = texel[i][BCOMP]; 799 /* Av = Af */ 800 } 801 break; 802 case GL_RGBA: 803 for (i=0;i<n;i++) { 804 /* Cv = Ct */ 805 rgba[i][RCOMP] = texel[i][RCOMP]; 806 rgba[i][GCOMP] = texel[i][GCOMP]; 807 rgba[i][BCOMP] = texel[i][BCOMP]; 808 /* Av = At */ 809 rgba[i][ACOMP] = texel[i][ACOMP]; 810 } 811 break; 812 default: 813 _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply"); 814 return; 815 } 816 break; 817 818 case GL_MODULATE: 819 switch (format) { 820 case GL_ALPHA: 821 for (i=0;i<n;i++) { 822 /* Cv = Cf */ 823 /* Av = AfAt */ 824 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); 825 } 826 break; 827 case GL_LUMINANCE: 828 for (i=0;i<n;i++) { 829 /* Cv = LtCf */ 830 GLchan Lt = texel[i][RCOMP]; 831 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt ); 832 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt ); 833 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt ); 834 /* Av = Af */ 835 } 836 break; 837 case GL_LUMINANCE_ALPHA: 838 for (i=0;i<n;i++) { 839 /* Cv = CfLt */ 840 GLchan Lt = texel[i][RCOMP]; 841 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt ); 842 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt ); 843 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt ); 844 /* Av = AfAt */ 845 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); 846 } 847 break; 848 case GL_INTENSITY: 849 for (i=0;i<n;i++) { 850 /* Cv = CfIt */ 851 GLchan It = texel[i][RCOMP]; 852 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], It ); 853 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], It ); 854 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], It ); 855 /* Av = AfIt */ 856 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], It ); 857 } 858 break; 859 case GL_RGB: 860 for (i=0;i<n;i++) { 861 /* Cv = CfCt */ 862 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] ); 863 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] ); 864 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] ); 865 /* Av = Af */ 866 } 867 break; 868 case GL_RGBA: 869 for (i=0;i<n;i++) { 870 /* Cv = CfCt */ 871 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] ); 872 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] ); 873 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] ); 874 /* Av = AfAt */ 875 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); 876 } 877 break; 878 default: 879 _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply"); 880 return; 881 } 882 break; 883 884 case GL_DECAL: 885 switch (format) { 886 case GL_ALPHA: 887 case GL_LUMINANCE: 888 case GL_LUMINANCE_ALPHA: 889 case GL_INTENSITY: 890 /* undefined */ 891 break; 892 case GL_RGB: 893 for (i=0;i<n;i++) { 894 /* Cv = Ct */ 895 rgba[i][RCOMP] = texel[i][RCOMP]; 896 rgba[i][GCOMP] = texel[i][GCOMP]; 897 rgba[i][BCOMP] = texel[i][BCOMP]; 898 /* Av = Af */ 899 } 900 break; 901 case GL_RGBA: 902 for (i=0;i<n;i++) { 903 /* Cv = Cf(1-At) + CtAt */ 904 GLchan t = texel[i][ACOMP], s = CHAN_MAX - t; 905 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(texel[i][RCOMP],t); 906 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(texel[i][GCOMP],t); 907 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(texel[i][BCOMP],t); 908 /* Av = Af */ 909 } 910 break; 911 default: 912 _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply"); 913 return; 914 } 915 break; 916 917 case GL_BLEND: 918 UNCLAMPED_FLOAT_TO_CHAN(Rc, texUnit->EnvColor[0]); 919 UNCLAMPED_FLOAT_TO_CHAN(Gc, texUnit->EnvColor[1]); 920 UNCLAMPED_FLOAT_TO_CHAN(Bc, texUnit->EnvColor[2]); 921 UNCLAMPED_FLOAT_TO_CHAN(Ac, texUnit->EnvColor[3]); 922 switch (format) { 923 case GL_ALPHA: 924 for (i=0;i<n;i++) { 925 /* Cv = Cf */ 926 /* Av = AfAt */ 927 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 928 } 929 break; 930 case GL_LUMINANCE: 931 for (i=0;i<n;i++) { 932 /* Cv = Cf(1-Lt) + CcLt */ 933 GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt; 934 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt); 935 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt); 936 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt); 937 /* Av = Af */ 938 } 939 break; 940 case GL_LUMINANCE_ALPHA: 941 for (i=0;i<n;i++) { 942 /* Cv = Cf(1-Lt) + CcLt */ 943 GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt; 944 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt); 945 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt); 946 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt); 947 /* Av = AfAt */ 948 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]); 949 } 950 break; 951 case GL_INTENSITY: 952 for (i=0;i<n;i++) { 953 /* Cv = Cf(1-It) + CcIt */ 954 GLchan It = texel[i][RCOMP], s = CHAN_MAX - It; 955 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, It); 956 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, It); 957 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, It); 958 /* Av = Af(1-It) + Ac*It */ 959 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], s) + CHAN_PRODUCT(Ac, It); 960 } 961 break; 962 case GL_RGB: 963 for (i=0;i<n;i++) { 964 /* Cv = Cf(1-Ct) + CcCt */ 965 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]); 966 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]); 967 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]); 968 /* Av = Af */ 969 } 970 break; 971 case GL_RGBA: 972 for (i=0;i<n;i++) { 973 /* Cv = Cf(1-Ct) + CcCt */ 974 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]); 975 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]); 976 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]); 977 /* Av = AfAt */ 978 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]); 979 } 980 break; 981 default: 982 _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply"); 983 return; 984 } 985 break; 986 987 /* XXX don't clamp results if GLchan is float??? */ 988 989 case GL_ADD: /* GL_EXT_texture_add_env */ 990 switch (format) { 991 case GL_ALPHA: 992 for (i=0;i<n;i++) { 993 /* Rv = Rf */ 994 /* Gv = Gf */ 995 /* Bv = Bf */ 996 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 997 } 998 break; 999 case GL_LUMINANCE: 1000 for (i=0;i<n;i++) { 1001 ChanTemp Lt = texel[i][RCOMP]; 1002 ChanTemp r = rgba[i][RCOMP] + Lt; 1003 ChanTemp g = rgba[i][GCOMP] + Lt; 1004 ChanTemp b = rgba[i][BCOMP] + Lt; 1005 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1006 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1007 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1008 /* Av = Af */ 1009 } 1010 break; 1011 case GL_LUMINANCE_ALPHA: 1012 for (i=0;i<n;i++) { 1013 ChanTemp Lt = texel[i][RCOMP]; 1014 ChanTemp r = rgba[i][RCOMP] + Lt; 1015 ChanTemp g = rgba[i][GCOMP] + Lt; 1016 ChanTemp b = rgba[i][BCOMP] + Lt; 1017 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1018 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1019 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1020 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 1021 } 1022 break; 1023 case GL_INTENSITY: 1024 for (i=0;i<n;i++) { 1025 GLchan It = texel[i][RCOMP]; 1026 ChanTemp r = rgba[i][RCOMP] + It; 1027 ChanTemp g = rgba[i][GCOMP] + It; 1028 ChanTemp b = rgba[i][BCOMP] + It; 1029 ChanTemp a = rgba[i][ACOMP] + It; 1030 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1031 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1032 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1033 rgba[i][ACOMP] = MIN2(a, CHAN_MAX); 1034 } 1035 break; 1036 case GL_RGB: 1037 for (i=0;i<n;i++) { 1038 ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP]; 1039 ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP]; 1040 ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP]; 1041 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1042 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1043 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1044 /* Av = Af */ 1045 } 1046 break; 1047 case GL_RGBA: 1048 for (i=0;i<n;i++) { 1049 ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP]; 1050 ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP]; 1051 ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP]; 1052 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1053 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1054 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1055 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 1056 } 1057 break; 1058 default: 1059 _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply"); 1060 return; 1061 } 1062 break; 1063 1064 default: 1065 _mesa_problem(ctx, "Bad env mode in texture_apply"); 1066 return; 1067 } 1068} 1069 1070 1071 1072/** 1073 * Apply texture mapping to a span of fragments. 1074 */ 1075void 1076_swrast_texture_span( GLcontext *ctx, SWspan *span ) 1077{ 1078 SWcontext *swrast = SWRAST_CONTEXT(ctx); 1079 GLchan primary_rgba[MAX_WIDTH][4]; 1080 GLuint unit; 1081 1082 ASSERT(span->end < MAX_WIDTH); 1083 ASSERT(span->arrayMask & SPAN_TEXTURE); 1084 1085 /* 1086 * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) 1087 */ 1088 if (swrast->_AnyTextureCombine) 1089 MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); 1090 1091 /* 1092 * Must do all texture sampling before combining in order to 1093 * accomodate GL_ARB_texture_env_crossbar. 1094 */ 1095 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 1096 if (ctx->Texture.Unit[unit]._ReallyEnabled) { 1097 const GLfloat (*texcoords)[4] 1098 = (const GLfloat (*)[4]) 1099 span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; 1100 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1101 const struct gl_texture_object *curObj = texUnit->_Current; 1102 GLfloat *lambda = span->array->lambda[unit]; 1103 GLchan (*texels)[4] = (GLchan (*)[4]) 1104 (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan))); 1105 1106 /* adjust texture lod (lambda) */ 1107 if (span->arrayMask & SPAN_LAMBDA) { 1108 if (texUnit->LodBias + curObj->LodBias != 0.0F) { 1109 /* apply LOD bias, but don't clamp yet */ 1110 const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias, 1111 -ctx->Const.MaxTextureLodBias, 1112 ctx->Const.MaxTextureLodBias); 1113 GLuint i; 1114 for (i = 0; i < span->end; i++) { 1115 lambda[i] += bias; 1116 } 1117 } 1118 1119 if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) { 1120 /* apply LOD clamping to lambda */ 1121 const GLfloat min = curObj->MinLod; 1122 const GLfloat max = curObj->MaxLod; 1123 GLuint i; 1124 for (i = 0; i < span->end; i++) { 1125 GLfloat l = lambda[i]; 1126 lambda[i] = CLAMP(l, min, max); 1127 } 1128 } 1129 } 1130 1131 /* Sample the texture (span->end = number of fragments) */ 1132 swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end, 1133 texcoords, lambda, texels ); 1134 1135 /* GL_SGI_texture_color_table */ 1136 if (texUnit->ColorTableEnabled) { 1137#if CHAN_TYPE == GL_UNSIGNED_BYTE 1138 _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels); 1139#elif CHAN_TYPE == GL_UNSIGNED_SHORT 1140 _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels); 1141#else 1142 _mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels); 1143#endif 1144 } 1145 } 1146 } 1147 1148 /* 1149 * OK, now apply the texture (aka texture combine/blend). 1150 * We modify the span->color.rgba values. 1151 */ 1152 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 1153 if (ctx->Texture.Unit[unit]._ReallyEnabled) { 1154 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1155 if (texUnit->_CurrentCombine != &texUnit->_EnvMode ) { 1156 texture_combine( ctx, unit, span->end, 1157 (CONST GLchan (*)[4]) primary_rgba, 1158 swrast->TexelBuffer, 1159 span->array->rgba ); 1160 } 1161 else { 1162 /* conventional texture blend */ 1163 const GLchan (*texels)[4] = (const GLchan (*)[4]) 1164 (swrast->TexelBuffer + unit * 1165 (span->end * 4 * sizeof(GLchan))); 1166 texture_apply( ctx, texUnit, span->end, 1167 (CONST GLchan (*)[4]) primary_rgba, texels, 1168 span->array->rgba ); 1169 } 1170 } 1171 } 1172} 1173