nux-1.14.0
|
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 }