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