Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentexstate.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00031 #include "glheader.h" 00032 #include "colormac.h" 00033 #if FEATURE_colortable 00034 #include "colortab.h" 00035 #endif 00036 #include "context.h" 00037 #include "enums.h" 00038 #include "macros.h" 00039 #include "texcompress.h" 00040 #include "texobj.h" 00041 #include "teximage.h" 00042 #include "texstate.h" 00043 #include "texenvprogram.h" 00044 #include "mtypes.h" 00045 #include "math/m_xform.h" 00046 00047 00048 00054 static const struct gl_tex_env_combine_state default_combine_state = { 00055 GL_MODULATE, GL_MODULATE, 00056 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }, 00057 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }, 00058 { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA }, 00059 { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }, 00060 0, 0, 00061 2, 2 00062 }; 00063 00064 00065 00069 void 00070 _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) 00071 { 00072 GLuint i, tex; 00073 00074 ASSERT(src); 00075 ASSERT(dst); 00076 00077 dst->Texture.CurrentUnit = src->Texture.CurrentUnit; 00078 dst->Texture._GenFlags = src->Texture._GenFlags; 00079 dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled; 00080 dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled; 00081 dst->Texture.SharedPalette = src->Texture.SharedPalette; 00082 00083 /* per-unit state */ 00084 for (i = 0; i < src->Const.MaxTextureImageUnits; i++) { 00085 dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled; 00086 dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode; 00087 COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor); 00088 dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled; 00089 dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS; 00090 dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT; 00091 dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR; 00092 dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ; 00093 dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS; 00094 dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT; 00095 dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR; 00096 dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ; 00097 dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags; 00098 COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS); 00099 COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT); 00100 COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR); 00101 COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ); 00102 COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS); 00103 COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT); 00104 COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR); 00105 COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ); 00106 dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias; 00107 00108 /* GL_EXT_texture_env_combine */ 00109 dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB; 00110 dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA; 00111 COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB); 00112 COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA); 00113 COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB); 00114 COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA); 00115 dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB; 00116 dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA; 00117 00118 /* copy texture object bindings, not contents of texture objects */ 00119 _mesa_lock_context_textures(dst); 00120 00121 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 00122 _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentTex[tex], 00123 src->Texture.Unit[i].CurrentTex[tex]); 00124 } 00125 00126 _mesa_unlock_context_textures(dst); 00127 } 00128 } 00129 00130 00131 /* 00132 * For debugging 00133 */ 00134 void 00135 _mesa_print_texunit_state( GLcontext *ctx, GLuint unit ) 00136 { 00137 const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit; 00138 _mesa_printf("Texture Unit %d\n", unit); 00139 _mesa_printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode)); 00140 _mesa_printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB)); 00141 _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); 00142 _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0])); 00143 _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1])); 00144 _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2])); 00145 _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0])); 00146 _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1])); 00147 _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2])); 00148 _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0])); 00149 _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1])); 00150 _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2])); 00151 _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0])); 00152 _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1])); 00153 _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2])); 00154 _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB); 00155 _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA); 00156 _mesa_printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]); 00157 } 00158 00159 00160 00161 /**********************************************************************/ 00162 /* Texture Environment */ 00163 /**********************************************************************/ 00164 00175 static void 00176 calculate_derived_texenv( struct gl_tex_env_combine_state *state, 00177 GLenum mode, GLenum texBaseFormat ) 00178 { 00179 GLenum mode_rgb; 00180 GLenum mode_a; 00181 00182 *state = default_combine_state; 00183 00184 switch (texBaseFormat) { 00185 case GL_ALPHA: 00186 state->SourceRGB[0] = GL_PREVIOUS; 00187 break; 00188 00189 case GL_LUMINANCE_ALPHA: 00190 case GL_INTENSITY: 00191 case GL_RGBA: 00192 break; 00193 00194 case GL_LUMINANCE: 00195 case GL_RGB: 00196 case GL_YCBCR_MESA: 00197 state->SourceA[0] = GL_PREVIOUS; 00198 break; 00199 00200 default: 00201 _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv"); 00202 return; 00203 } 00204 00205 if (mode == GL_REPLACE_EXT) 00206 mode = GL_REPLACE; 00207 00208 switch (mode) { 00209 case GL_REPLACE: 00210 case GL_MODULATE: 00211 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode; 00212 mode_a = mode; 00213 break; 00214 00215 case GL_DECAL: 00216 mode_rgb = GL_INTERPOLATE; 00217 mode_a = GL_REPLACE; 00218 00219 state->SourceA[0] = GL_PREVIOUS; 00220 00221 /* Having alpha / luminance / intensity textures replace using the 00222 * incoming fragment color matches the definition in NV_texture_shader. 00223 * The 1.5 spec simply marks these as "undefined". 00224 */ 00225 switch (texBaseFormat) { 00226 case GL_ALPHA: 00227 case GL_LUMINANCE: 00228 case GL_LUMINANCE_ALPHA: 00229 case GL_INTENSITY: 00230 state->SourceRGB[0] = GL_PREVIOUS; 00231 break; 00232 case GL_RGB: 00233 case GL_YCBCR_MESA: 00234 mode_rgb = GL_REPLACE; 00235 break; 00236 case GL_RGBA: 00237 state->SourceRGB[2] = GL_TEXTURE; 00238 break; 00239 } 00240 break; 00241 00242 case GL_BLEND: 00243 mode_rgb = GL_INTERPOLATE; 00244 mode_a = GL_MODULATE; 00245 00246 switch (texBaseFormat) { 00247 case GL_ALPHA: 00248 mode_rgb = GL_REPLACE; 00249 break; 00250 case GL_INTENSITY: 00251 mode_a = GL_INTERPOLATE; 00252 state->SourceA[0] = GL_CONSTANT; 00253 state->OperandA[2] = GL_SRC_ALPHA; 00254 /* FALLTHROUGH */ 00255 case GL_LUMINANCE: 00256 case GL_RGB: 00257 case GL_LUMINANCE_ALPHA: 00258 case GL_RGBA: 00259 case GL_YCBCR_MESA: 00260 state->SourceRGB[2] = GL_TEXTURE; 00261 state->SourceA[2] = GL_TEXTURE; 00262 state->SourceRGB[0] = GL_CONSTANT; 00263 state->OperandRGB[2] = GL_SRC_COLOR; 00264 break; 00265 } 00266 break; 00267 00268 case GL_ADD: 00269 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD; 00270 mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE; 00271 break; 00272 00273 default: 00274 _mesa_problem(NULL, 00275 "Invalid texture env mode in calculate_derived_texenv"); 00276 return; 00277 } 00278 00279 state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS) 00280 ? mode_rgb : GL_REPLACE; 00281 state->ModeA = (state->SourceA[0] != GL_PREVIOUS) 00282 ? mode_a : GL_REPLACE; 00283 } 00284 00285 00286 00287 00288 /* GL_ARB_multitexture */ 00289 void GLAPIENTRY 00290 _mesa_ActiveTextureARB(GLenum texture) 00291 { 00292 GET_CURRENT_CONTEXT(ctx); 00293 const GLuint texUnit = texture - GL_TEXTURE0; 00294 ASSERT_OUTSIDE_BEGIN_END(ctx); 00295 00296 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 00297 _mesa_debug(ctx, "glActiveTexture %s\n", 00298 _mesa_lookup_enum_by_nr(texture)); 00299 00300 if (texUnit >= ctx->Const.MaxTextureImageUnits) { 00301 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)"); 00302 return; 00303 } 00304 00305 if (ctx->Texture.CurrentUnit == texUnit) 00306 return; 00307 00308 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 00309 00310 ctx->Texture.CurrentUnit = texUnit; 00311 if (ctx->Transform.MatrixMode == GL_TEXTURE) { 00312 /* update current stack pointer */ 00313 ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit]; 00314 } 00315 00316 if (ctx->Driver.ActiveTexture) { 00317 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit ); 00318 } 00319 } 00320 00321 00322 /* GL_ARB_multitexture */ 00323 void GLAPIENTRY 00324 _mesa_ClientActiveTextureARB(GLenum texture) 00325 { 00326 GET_CURRENT_CONTEXT(ctx); 00327 GLuint texUnit = texture - GL_TEXTURE0; 00328 ASSERT_OUTSIDE_BEGIN_END(ctx); 00329 00330 if (texUnit >= ctx->Const.MaxTextureCoordUnits) { 00331 _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)"); 00332 return; 00333 } 00334 00335 FLUSH_VERTICES(ctx, _NEW_ARRAY); 00336 ctx->Array.ActiveTexture = texUnit; 00337 } 00338 00339 00340 00341 /**********************************************************************/ 00342 /***** State management *****/ 00343 /**********************************************************************/ 00344 00345 00354 static void 00355 update_texture_matrices( GLcontext *ctx ) 00356 { 00357 GLuint i; 00358 00359 ctx->Texture._TexMatEnabled = 0; 00360 00361 for (i=0; i < ctx->Const.MaxTextureCoordUnits; i++) { 00362 if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) { 00363 _math_matrix_analyse( ctx->TextureMatrixStack[i].Top ); 00364 00365 if (ctx->Texture.Unit[i]._ReallyEnabled && 00366 ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY) 00367 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i); 00368 00369 if (ctx->Driver.TextureMatrix) 00370 ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top); 00371 } 00372 } 00373 } 00374 00375 00384 static void 00385 update_texture_compare_function(GLcontext *ctx, 00386 struct gl_texture_object *tObj) 00387 { 00388 /* XXX temporarily disable this test since it breaks the GLSL 00389 * shadow2D(), etc. functions. 00390 */ 00391 if (0 /*ctx->FragmentProgram._Current*/) { 00392 /* Texel/coordinate comparison is ignored for programs. 00393 * See GL_ARB_fragment_program/shader spec for details. 00394 */ 00395 tObj->_Function = GL_NONE; 00396 } 00397 else if (tObj->CompareFlag) { 00398 /* GL_SGIX_shadow */ 00399 if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) { 00400 tObj->_Function = GL_LEQUAL; 00401 } 00402 else { 00403 ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX); 00404 tObj->_Function = GL_GEQUAL; 00405 } 00406 } 00407 else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { 00408 /* GL_ARB_shadow */ 00409 tObj->_Function = tObj->CompareFunc; 00410 } 00411 else { 00412 tObj->_Function = GL_NONE; /* pass depth through as grayscale */ 00413 } 00414 } 00415 00416 00421 static void 00422 texture_override(GLcontext *ctx, 00423 struct gl_texture_unit *texUnit, GLbitfield enableBits, 00424 struct gl_texture_object *texObj, GLuint textureBit) 00425 { 00426 if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) { 00427 if (!texObj->_Complete) { 00428 _mesa_test_texobj_completeness(ctx, texObj); 00429 } 00430 if (texObj->_Complete) { 00431 texUnit->_ReallyEnabled = textureBit; 00432 texUnit->_Current = texObj; 00433 update_texture_compare_function(ctx, texObj); 00434 } 00435 } 00436 } 00437 00438 00447 static void 00448 update_texture_state( GLcontext *ctx ) 00449 { 00450 GLuint unit; 00451 struct gl_fragment_program *fprog = NULL; 00452 struct gl_vertex_program *vprog = NULL; 00453 00454 if (ctx->Shader.CurrentProgram && 00455 ctx->Shader.CurrentProgram->LinkStatus) { 00456 fprog = ctx->Shader.CurrentProgram->FragmentProgram; 00457 vprog = ctx->Shader.CurrentProgram->VertexProgram; 00458 } 00459 else { 00460 if (ctx->FragmentProgram._Enabled) { 00461 fprog = ctx->FragmentProgram.Current; 00462 } 00463 if (ctx->VertexProgram._Enabled) { 00464 /* XXX enable this if/when non-shader vertex programs get 00465 * texture fetches: 00466 vprog = ctx->VertexProgram.Current; 00467 */ 00468 } 00469 } 00470 00471 ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 00472 * actual changes. 00473 */ 00474 00475 ctx->Texture._EnabledUnits = 0; 00476 ctx->Texture._GenFlags = 0; 00477 ctx->Texture._TexMatEnabled = 0; 00478 ctx->Texture._TexGenEnabled = 0; 00479 00480 /* 00481 * Update texture unit state. 00482 */ 00483 for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) { 00484 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 00485 GLbitfield enableBits; 00486 GLuint tex; 00487 00488 texUnit->_Current = NULL; 00489 texUnit->_ReallyEnabled = 0; 00490 texUnit->_GenFlags = 0; 00491 00492 /* Get the bitmask of texture target enables. 00493 * enableBits will be a mask of the TEXTURE_*_BIT flags indicating 00494 * which texture targets are enabled (fixed function) or referenced 00495 * by a fragment shader/program. When multiple flags are set, we'll 00496 * settle on the one with highest priority (see texture_override below). 00497 */ 00498 enableBits = 0x0; 00499 if (vprog) { 00500 enableBits |= vprog->Base.TexturesUsed[unit]; 00501 } 00502 if (fprog) { 00503 enableBits |= fprog->Base.TexturesUsed[unit]; 00504 } 00505 else { 00506 /* fixed-function fragment program */ 00507 enableBits |= texUnit->Enabled; 00508 } 00509 00510 if (enableBits == 0x0) 00511 continue; 00512 00513 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 00514 ASSERT(texUnit->CurrentTex[tex]); 00515 } 00516 00517 /* Look for the highest-priority texture target that's enabled and 00518 * complete. That's the one we'll use for texturing. If we're using 00519 * a fragment program we're guaranteed that bitcount(enabledBits) <= 1. 00520 */ 00521 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 00522 /* texture indexes from highest to lowest priority */ 00523 static const GLuint targets[NUM_TEXTURE_TARGETS] = { 00524 TEXTURE_2D_ARRAY_INDEX, 00525 TEXTURE_1D_ARRAY_INDEX, 00526 TEXTURE_CUBE_INDEX, 00527 TEXTURE_3D_INDEX, 00528 TEXTURE_RECT_INDEX, 00529 TEXTURE_2D_INDEX, 00530 TEXTURE_1D_INDEX 00531 }; 00532 GLuint texIndex = targets[tex]; 00533 texture_override(ctx, texUnit, enableBits, 00534 texUnit->CurrentTex[texIndex], 1 << texIndex); 00535 } 00536 00537 if (!texUnit->_ReallyEnabled) { 00538 continue; 00539 } 00540 00541 if (texUnit->_ReallyEnabled) 00542 ctx->Texture._EnabledUnits |= (1 << unit); 00543 00544 if (texUnit->EnvMode == GL_COMBINE) { 00545 texUnit->_CurrentCombine = & texUnit->Combine; 00546 } 00547 else { 00548 const struct gl_texture_object *texObj = texUnit->_Current; 00549 GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; 00550 if (format == GL_COLOR_INDEX) { 00551 format = GL_RGBA; /* a bit of a hack */ 00552 } 00553 else if (format == GL_DEPTH_COMPONENT 00554 || format == GL_DEPTH_STENCIL_EXT) { 00555 format = texObj->DepthMode; 00556 } 00557 calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format); 00558 texUnit->_CurrentCombine = & texUnit->_EnvMode; 00559 } 00560 00561 switch (texUnit->_CurrentCombine->ModeRGB) { 00562 case GL_REPLACE: 00563 texUnit->_CurrentCombine->_NumArgsRGB = 1; 00564 break; 00565 case GL_MODULATE: 00566 case GL_ADD: 00567 case GL_ADD_SIGNED: 00568 case GL_SUBTRACT: 00569 case GL_DOT3_RGB: 00570 case GL_DOT3_RGBA: 00571 case GL_DOT3_RGB_EXT: 00572 case GL_DOT3_RGBA_EXT: 00573 texUnit->_CurrentCombine->_NumArgsRGB = 2; 00574 break; 00575 case GL_INTERPOLATE: 00576 case GL_MODULATE_ADD_ATI: 00577 case GL_MODULATE_SIGNED_ADD_ATI: 00578 case GL_MODULATE_SUBTRACT_ATI: 00579 texUnit->_CurrentCombine->_NumArgsRGB = 3; 00580 break; 00581 default: 00582 texUnit->_CurrentCombine->_NumArgsRGB = 0; 00583 _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state"); 00584 return; 00585 } 00586 00587 switch (texUnit->_CurrentCombine->ModeA) { 00588 case GL_REPLACE: 00589 texUnit->_CurrentCombine->_NumArgsA = 1; 00590 break; 00591 case GL_MODULATE: 00592 case GL_ADD: 00593 case GL_ADD_SIGNED: 00594 case GL_SUBTRACT: 00595 texUnit->_CurrentCombine->_NumArgsA = 2; 00596 break; 00597 case GL_INTERPOLATE: 00598 case GL_MODULATE_ADD_ATI: 00599 case GL_MODULATE_SIGNED_ADD_ATI: 00600 case GL_MODULATE_SUBTRACT_ATI: 00601 texUnit->_CurrentCombine->_NumArgsA = 3; 00602 break; 00603 default: 00604 texUnit->_CurrentCombine->_NumArgsA = 0; 00605 _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state"); 00606 break; 00607 } 00608 } 00609 00610 /* Determine which texture coordinate sets are actually needed */ 00611 if (fprog) { 00612 const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1; 00613 ctx->Texture._EnabledCoordUnits 00614 = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask; 00615 } 00616 else { 00617 ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits; 00618 } 00619 00620 /* Setup texgen for those texture coordinate sets that are in use */ 00621 for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) { 00622 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 00623 00624 if (!(ctx->Texture._EnabledCoordUnits & (1 << unit))) 00625 continue; 00626 00627 if (texUnit->TexGenEnabled) { 00628 if (texUnit->TexGenEnabled & S_BIT) { 00629 texUnit->_GenFlags |= texUnit->_GenBitS; 00630 } 00631 if (texUnit->TexGenEnabled & T_BIT) { 00632 texUnit->_GenFlags |= texUnit->_GenBitT; 00633 } 00634 if (texUnit->TexGenEnabled & Q_BIT) { 00635 texUnit->_GenFlags |= texUnit->_GenBitQ; 00636 } 00637 if (texUnit->TexGenEnabled & R_BIT) { 00638 texUnit->_GenFlags |= texUnit->_GenBitR; 00639 } 00640 00641 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit); 00642 ctx->Texture._GenFlags |= texUnit->_GenFlags; 00643 } 00644 00645 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) 00646 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit); 00647 } 00648 } 00649 00650 00654 void 00655 _mesa_update_texture( GLcontext *ctx, GLuint new_state ) 00656 { 00657 if (new_state & _NEW_TEXTURE_MATRIX) 00658 update_texture_matrices( ctx ); 00659 00660 if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) 00661 update_texture_state( ctx ); 00662 } 00663 00664 00665 /**********************************************************************/ 00666 /***** Initialization *****/ 00667 /**********************************************************************/ 00668 00679 static GLboolean 00680 alloc_proxy_textures( GLcontext *ctx ) 00681 { 00682 static const GLenum targets[] = { 00683 GL_TEXTURE_1D, 00684 GL_TEXTURE_2D, 00685 GL_TEXTURE_3D, 00686 GL_TEXTURE_CUBE_MAP_ARB, 00687 GL_TEXTURE_RECTANGLE_NV, 00688 GL_TEXTURE_1D_ARRAY_EXT, 00689 GL_TEXTURE_2D_ARRAY_EXT 00690 }; 00691 GLint tgt; 00692 00693 ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); 00694 00695 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 00696 if (!(ctx->Texture.ProxyTex[tgt] 00697 = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) { 00698 /* out of memory, free what we did allocate */ 00699 while (--tgt >= 0) { 00700 ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); 00701 } 00702 return GL_FALSE; 00703 } 00704 } 00705 00706 assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */ 00707 return GL_TRUE; 00708 } 00709 00710 00717 static void 00718 init_texture_unit( GLcontext *ctx, GLuint unit ) 00719 { 00720 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 00721 GLuint tex; 00722 00723 texUnit->EnvMode = GL_MODULATE; 00724 ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 ); 00725 00726 texUnit->Combine = default_combine_state; 00727 texUnit->_EnvMode = default_combine_state; 00728 texUnit->_CurrentCombine = & texUnit->_EnvMode; 00729 00730 texUnit->TexGenEnabled = 0; 00731 texUnit->GenModeS = GL_EYE_LINEAR; 00732 texUnit->GenModeT = GL_EYE_LINEAR; 00733 texUnit->GenModeR = GL_EYE_LINEAR; 00734 texUnit->GenModeQ = GL_EYE_LINEAR; 00735 texUnit->_GenBitS = TEXGEN_EYE_LINEAR; 00736 texUnit->_GenBitT = TEXGEN_EYE_LINEAR; 00737 texUnit->_GenBitR = TEXGEN_EYE_LINEAR; 00738 texUnit->_GenBitQ = TEXGEN_EYE_LINEAR; 00739 00740 /* Yes, these plane coefficients are correct! */ 00741 ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 ); 00742 ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 ); 00743 ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 ); 00744 ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 ); 00745 ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 ); 00746 ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 ); 00747 ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 ); 00748 ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 ); 00749 00750 /* initialize current texture object ptrs to the shared default objects */ 00751 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 00752 _mesa_reference_texobj(&texUnit->CurrentTex[tex], 00753 ctx->Shared->DefaultTex[tex]); 00754 } 00755 } 00756 00757 00761 GLboolean 00762 _mesa_init_texture(GLcontext *ctx) 00763 { 00764 GLuint i; 00765 00766 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); 00767 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); 00768 00769 /* Texture group */ 00770 ctx->Texture.CurrentUnit = 0; /* multitexture */ 00771 ctx->Texture._EnabledUnits = 0; 00772 ctx->Texture.SharedPalette = GL_FALSE; 00773 #if FEATURE_colortable 00774 _mesa_init_colortable(&ctx->Texture.Palette); 00775 #endif 00776 00777 for (i = 0; i < MAX_TEXTURE_UNITS; i++) 00778 init_texture_unit( ctx, i ); 00779 00780 /* After we're done initializing the context's texture state the default 00781 * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1. 00782 */ 00783 assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount 00784 >= MAX_TEXTURE_UNITS + 1); 00785 00786 /* Allocate proxy textures */ 00787 if (!alloc_proxy_textures( ctx )) 00788 return GL_FALSE; 00789 00790 return GL_TRUE; 00791 } 00792 00793 00797 void 00798 _mesa_free_texture_data(GLcontext *ctx) 00799 { 00800 GLuint u, tgt; 00801 00802 /* unreference current textures */ 00803 for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { 00804 struct gl_texture_unit *unit = ctx->Texture.Unit + u; 00805 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 00806 _mesa_reference_texobj(&unit->CurrentTex[tgt], NULL); 00807 } 00808 } 00809 00810 /* Free proxy texture objects */ 00811 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) 00812 ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); 00813 00814 #if FEATURE_colortable 00815 { 00816 GLuint i; 00817 for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) 00818 _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable ); 00819 } 00820 #endif 00821 } 00822 00823 00829 void 00830 _mesa_update_default_objects_texture(GLcontext *ctx) 00831 { 00832 GLuint i, tex; 00833 00834 for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 00835 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 00836 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 00837 _mesa_reference_texobj(&texUnit->CurrentTex[tex], 00838 ctx->Shared->DefaultTex[tex]); 00839 } 00840 } 00841 } Generated on Sat May 26 2012 04:19:15 for ReactOS by
1.7.6.1
|