nux-1.16.0
GLTextureStates.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "GLResource.h"
00024 #include "GLTextureStates.h"
00025 
00026 namespace nux
00027 {
00028 
00029   const struct TextureStateLookUpTable
00030   {
00031     TextureStateLookUpTable()
00032     {
00033       // setup render state map
00034 #define UL_MAP(state__, default_value__, checked__)                          \
00035         default_texture_state[GFXTS_##state__].iValue     = default_value__;  \
00036         default_texture_state[GFXTS_##state__].Checked   = checked__;
00037 
00038 #define UL_MAP_FLOAT(state__, default_value__, checked__)                    \
00039     default_texture_state[GFXTS_##state__].fValue     = default_value__;      \
00040     default_texture_state[GFXTS_##state__].Checked   = checked__;
00041 
00042       UL_MAP (ADDRESSU               ,           GL_REPEAT       ,       1);
00043       UL_MAP (ADDRESSV               ,           GL_REPEAT       ,       1);
00044       UL_MAP (ADDRESSW               ,           GL_REPEAT       ,       1);
00045 
00046       UL_MAP (MINFILTER              ,           GL_NEAREST      ,       1);
00047       UL_MAP (MAGFILTER              ,           GL_NEAREST      ,       1);
00048       UL_MAP (MIPFILTER              ,           GL_NEAREST      ,       1);
00049 
00050       UL_MAP (MIP_BASE_LEVEL         ,           0               ,       1);
00051       UL_MAP (MIP_MAX_LEVEL          ,           1000            ,       1);
00052       UL_MAP_FLOAT (MIN_LOD          ,           -1000           ,       1);
00053       UL_MAP_FLOAT (MAX_LOD          ,           +1000           ,       1);
00054 
00055       UL_MAP (BORDERCOLOR            ,           0x0             ,       1);
00056 
00057 #undef UL_MAP
00058 #undef UL_MAP_FLOAT
00059     };
00060 
00061     TextureStateMap default_texture_state[GFXTS_MAX_TEXTURESTATES];
00062   } s_TextureStateLUT;
00063 
00064 
00065   GLTextureStates::GLTextureStates (GLuint Type)
00066   {
00067     SetType (Type);
00068     Memcpy (&m_TextureStateChanges, &s_TextureStateLUT.default_texture_state, sizeof (m_TextureStateChanges) );
00069   }
00070 
00071   GLTextureStates::~GLTextureStates()
00072   {
00073 
00074   }
00075 
00076   void GLTextureStates::SetType (GLuint Type)
00077   {
00078     nuxAssertMsg (
00079       (Type == GL_TEXTURE_1D) ||
00080       (Type == GL_TEXTURE_2D) ||
00081       (Type == GL_TEXTURE_RECTANGLE_ARB) ||
00082       (Type == GL_TEXTURE_3D) ||
00083       (Type == GL_TEXTURE_CUBE_MAP_ARB),
00084       TEXT ("Error[GLTextureStates::GLTextureStates]: Invalid texture type.") );
00085 
00086     m_Type = Type;
00087   }
00088 
00089   void GLTextureStates::ResetDefault()
00090   {
00091 
00092   }
00093 
00094   void GLTextureStates::ResetStateChangeToDefault()
00095   {
00096 
00097   }
00098 
00099   void GLTextureStates::SetRenderStates()
00100   {
00101     HW_SetFiltering();
00102     HW_SetWrap();
00103     HW_SetLOD();
00104     HW_SetMipLevel();
00105   }
00106 
00107 #define SET_TS_VALUE(a, b)  if(a.iValue != b){(a).iValue = (b); (a).Dirty = true;}
00108 #define TS_VALUE(a, b)      (a).iValue
00109 
00110 #define SET_TS_VALUE_FLOAT(a, b)  if(a.fValue != b){(a).fValue = (b); (a).Dirty = true;}
00111 #define TS_VALUE_FLOAT(a, b)      (a).fValue
00112 
00113 
00114   void GLTextureStates::HW_SetFiltering()
00115   {
00116     if (m_TextureStateChanges[GFXTS_MINFILTER].Dirty || m_TextureStateChanges[GFXTS_MAGFILTER].Dirty)
00117     {
00118       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_MIN_FILTER,   m_TextureStateChanges[GFXTS_MINFILTER].iValue ) );
00119       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_MAG_FILTER,   m_TextureStateChanges[GFXTS_MAGFILTER].iValue) );
00120       m_TextureStateChanges[GFXTS_MINFILTER].Dirty = false;
00121       m_TextureStateChanges[GFXTS_MAGFILTER].Dirty = false;
00122     }
00123   }
00124 
00125   void GLTextureStates::HW_SetWrap()
00126   {
00127     if (m_TextureStateChanges[GFXTS_ADDRESSU].Dirty ||
00128         m_TextureStateChanges[GFXTS_ADDRESSV].Dirty ||
00129         m_TextureStateChanges[GFXTS_ADDRESSW].Dirty)
00130     {
00131       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_WRAP_S,       m_TextureStateChanges[GFXTS_ADDRESSU].iValue) );
00132       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_WRAP_T,       m_TextureStateChanges[GFXTS_ADDRESSV].iValue) );
00133       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_WRAP_R,       m_TextureStateChanges[GFXTS_ADDRESSW].iValue) );
00134       m_TextureStateChanges[GFXTS_ADDRESSU].Dirty = false;
00135       m_TextureStateChanges[GFXTS_ADDRESSV].Dirty = false;
00136       m_TextureStateChanges[GFXTS_ADDRESSW].Dirty = false;
00137     }
00138   }
00139 
00140   void GLTextureStates::HW_SetLOD()
00141   {
00142     if (m_Type == GL_TEXTURE_RECTANGLE_ARB)
00143     {
00144       // No support for mip LOP on rectangle texture.
00145       // ATI seems to not generate and Error.
00146       // Nvidia generates an error
00147       m_TextureStateChanges[GFXTS_MIN_LOD].Dirty = false;
00148       m_TextureStateChanges[GFXTS_MAX_LOD].Dirty = false;
00149       return;
00150     }
00151 
00152     if (m_TextureStateChanges[GFXTS_MIN_LOD].Dirty || m_TextureStateChanges[GFXTS_MAX_LOD].Dirty)
00153     {
00154       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_MIN_LOD,  m_TextureStateChanges[GFXTS_MIN_LOD].fValue) );
00155       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_MAX_LOD,  m_TextureStateChanges[GFXTS_MAX_LOD].fValue) );
00156       m_TextureStateChanges[GFXTS_MIN_LOD].Dirty = false;
00157       m_TextureStateChanges[GFXTS_MAX_LOD].Dirty = false;
00158     }
00159   }
00160 
00161   void GLTextureStates::HW_SetMipLevel()
00162   {
00163     if (m_TextureStateChanges[GFXTS_MIN_LOD].Dirty || m_TextureStateChanges[GFXTS_MAX_LOD].Dirty)
00164     {
00165       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_MIN_LOD,  m_TextureStateChanges[GFXTS_MIN_LOD].fValue) );
00166       CHECKGL ( glTexParameteri (m_Type, GL_TEXTURE_MAX_LOD,  m_TextureStateChanges[GFXTS_MAX_LOD].fValue) );
00167       m_TextureStateChanges[GFXTS_MIN_LOD].Dirty = false;
00168       m_TextureStateChanges[GFXTS_MAX_LOD].Dirty = false;
00169     }
00170   }
00171 
00172   void GLTextureStates::HW_SetBorderColor()
00173   {
00174 
00175   }
00176 
00177   void GLTextureStates::SetFiltering (
00178     unsigned int MinFilter,
00179     unsigned int MagFilter
00180     /*,unsigned int MIP*/)
00181   {
00182     nuxAssertMsg (
00183       (MinFilter == GL_LINEAR) ||
00184       (MinFilter == GL_NEAREST) ||
00185       (MinFilter == GL_NEAREST_MIPMAP_NEAREST) ||
00186       (MinFilter == GL_LINEAR_MIPMAP_NEAREST) ||
00187       (MinFilter == GL_NEAREST_MIPMAP_LINEAR) ||
00188       (MinFilter == GL_LINEAR_MIPMAP_LINEAR),
00189       TEXT ("Error[GLTextureStates::SetFiltering]: Invalid MinFilter state") );
00190 
00191     nuxAssertMsg (
00192       (MagFilter == GL_LINEAR) ||
00193       (MagFilter == GL_NEAREST),
00194       TEXT ("Error[GLTextureStates::SetFiltering]: Invalid MagFilter state") );
00195 
00196     //    nuxAssertMsg(
00197     //        (MIP == GL_LINEAR) ||
00198     //        (MIP == GL_NEAREST),
00199     //        TEXT("Error[GLTextureStates::SetFiltering]: Invalid Mipmap Filter State"));
00200 
00201     if (m_Type == GL_TEXTURE_RECTANGLE_ARB)
00202     {
00203       if ( (MinFilter != GL_NEAREST) && (MinFilter != GL_LINEAR) )
00204       {
00205         nuxError (TEXT ("[GLTextureStates::SetFiltering] Incorrect MinFilter for rectangle texture.") );
00206         SET_TS_VALUE (m_TextureStateChanges[GFXTS_MINFILTER], GL_LINEAR);
00207       }
00208       else
00209       {
00210         SET_TS_VALUE (m_TextureStateChanges[GFXTS_MINFILTER], MinFilter);
00211       }
00212 
00213       if ( (MagFilter != GL_NEAREST) && (MagFilter != GL_LINEAR) )
00214       {
00215         nuxError (TEXT ("[GLTextureStates::SetFiltering] Incorrect MagFilter for rectangle texture.") );
00216         SET_TS_VALUE (m_TextureStateChanges[GFXTS_MAGFILTER], GL_LINEAR);
00217       }
00218       else
00219       {
00220         SET_TS_VALUE (m_TextureStateChanges[GFXTS_MAGFILTER], MagFilter);
00221       }
00222     }
00223     else
00224     {
00225       SET_TS_VALUE (m_TextureStateChanges[GFXTS_MINFILTER], MinFilter);
00226       SET_TS_VALUE (m_TextureStateChanges[GFXTS_MAGFILTER], MagFilter);
00227     }
00228 
00229     //SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIPFILTER], MIP);
00230   }
00231 
00232   void GLTextureStates::SetWrap (
00233     unsigned int U,
00234     unsigned int V,
00235     unsigned int W)
00236   {
00237     nuxAssertMsg (
00238       (U == GL_CLAMP) ||
00239       (U == GL_CLAMP_TO_EDGE) ||
00240       (U == GL_CLAMP_TO_BORDER) ||
00241       (U == GL_MIRRORED_REPEAT) ||
00242       (U == GL_MIRROR_CLAMP_EXT) ||
00243       (U == GL_MIRROR_CLAMP_TO_EDGE_EXT) ||
00244       (U == GL_MIRROR_CLAMP_TO_BORDER_EXT) ||
00245       (U == GL_REPEAT),
00246       TEXT ("Error[GLTextureStates::SetWrap]: Invalid U Wrap State") );
00247 
00248     nuxAssertMsg (
00249       (V == GL_CLAMP) ||
00250       (V == GL_CLAMP_TO_EDGE) ||
00251       (V == GL_CLAMP_TO_BORDER) ||
00252       (V == GL_MIRRORED_REPEAT) ||
00253       (V == GL_MIRROR_CLAMP_EXT) ||
00254       (V == GL_MIRROR_CLAMP_TO_EDGE_EXT) ||
00255       (V == GL_MIRROR_CLAMP_TO_BORDER_EXT) ||
00256       (V == GL_REPEAT),
00257       TEXT ("Error[GLTextureStates::SetWrap]: Invalid V Wrap State") );
00258     nuxAssertMsg (
00259       (W == GL_CLAMP) ||
00260       (W == GL_CLAMP_TO_EDGE) ||
00261       (W == GL_CLAMP_TO_BORDER) ||
00262       (W == GL_MIRRORED_REPEAT) ||
00263       (W == GL_MIRROR_CLAMP_EXT) ||
00264       (W == GL_MIRROR_CLAMP_TO_EDGE_EXT) ||
00265       (W == GL_MIRROR_CLAMP_TO_BORDER_EXT) ||
00266       (W == GL_REPEAT),
00267       TEXT ("Error[GLTextureStates::SetWrap]: Invalid W Wrap State") );
00268 
00269     if (m_Type == GL_TEXTURE_RECTANGLE_ARB)
00270     {
00271       if ( (U != GL_CLAMP) && (U != GL_CLAMP_TO_BORDER) && (U != GL_CLAMP_TO_EDGE) )
00272       {
00273         nuxError (TEXT ("[GLTextureStates::SetFiltering] Incorrect warp for rectangle texture.") );
00274         SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSU], GL_CLAMP_TO_EDGE);
00275       }
00276       else
00277       {
00278         SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSU], U);
00279       }
00280 
00281       if ( (V != GL_CLAMP) && (V != GL_CLAMP_TO_BORDER) && (V != GL_CLAMP_TO_EDGE) )
00282       {
00283         nuxError (TEXT ("[GLTextureStates::SetFiltering] Incorrect warp for rectangle texture.") );
00284         SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSV], GL_CLAMP_TO_EDGE);
00285       }
00286       else
00287       {
00288         SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSV], V);
00289       }
00290 
00291       if ( (W != GL_CLAMP) && (W != GL_CLAMP_TO_BORDER) && (W != GL_CLAMP_TO_EDGE) )
00292       {
00293         nuxError (TEXT ("[GLTextureStates::SetFiltering] Incorrect warp for rectangle texture.") );
00294         SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSW], GL_CLAMP_TO_EDGE);
00295       }
00296       else
00297       {
00298         SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSW], W);
00299       }
00300     }
00301     else
00302     {
00303       SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSU], U);
00304       SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSV], V);
00305       SET_TS_VALUE (m_TextureStateChanges[GFXTS_ADDRESSW], W);
00306     }
00307   }
00308 
00309   void GLTextureStates::SetLOD (float MinLod,
00310                                 float MaxLod)
00311   {
00312     SET_TS_VALUE_FLOAT (m_TextureStateChanges[GFXTS_MIN_LOD], MinLod);
00313     SET_TS_VALUE_FLOAT (m_TextureStateChanges[GFXTS_MAX_LOD], MaxLod);
00314   }
00315 
00316   void GLTextureStates::SetMipLevel (
00317     unsigned int MinMip,
00318     unsigned int MaxMip)
00319   {
00320     SET_TS_VALUE (m_TextureStateChanges[GFXTS_MIP_BASE_LEVEL], MinMip);
00321     SET_TS_VALUE (m_TextureStateChanges[GFXTS_MIP_MAX_LEVEL], MaxMip);
00322   }
00323 
00324   void GLTextureStates::SetBorderColor (
00325     float R,
00326     float G,
00327     float B,
00328     float A)
00329   {
00330     unsigned int r, g, b, a;
00331     r = 255 * Clamp (R, 0.0f, 1.0f);
00332     g = 255 * Clamp (G, 0.0f, 1.0f);
00333     b = 255 * Clamp (B, 0.0f, 1.0f);
00334     a = 255 * Clamp (A, 0.0f, 1.0f);
00335     unsigned int color = (unsigned int) ( ( (a) << 24) | ( (r) << 16) | ( (g) << 8) | (b) );
00336 
00337     SET_TS_VALUE (m_TextureStateChanges[GFXTS_BORDERCOLOR], color);
00338   }
00339 
00340 #undef SET_TS_VALUE
00341 #undef TS_VALUE
00342 
00343 #undef SET_TS_VALUE_FLOAT
00344 #undef TS_VALUE_FLOAT
00345 
00346 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends