ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

texstate.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.