00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <texture/texState.h>
00021 #include <iostream>
00022
00023 using namespace std;
00024 using namespace gutz;
00025
00026 using namespace glift;
00027
00028 namespace glift {
00029
00030
00031
00032
00033 const EdgeModeTex* TS_S_CLAMP = new EdgeModeTex(GL_S, GL_CLAMP);
00034 const EdgeModeTex* TS_T_CLAMP = new EdgeModeTex(GL_T, GL_CLAMP);
00035 const EdgeModeTex* TS_R_CLAMP = new EdgeModeTex(GL_R, GL_CLAMP);
00036 const EdgeModeTex* TS_S_CLAMP_TO_EDGE = new EdgeModeTex(GL_S, GL_CLAMP_TO_EDGE);
00037 const EdgeModeTex* TS_T_CLAMP_TO_EDGE = new EdgeModeTex(GL_T, GL_CLAMP_TO_EDGE);
00038 const EdgeModeTex* TS_R_CLAMP_TO_EDGE = new EdgeModeTex(GL_R, GL_CLAMP_TO_EDGE);
00039 const EdgeModeTex* TS_S_REPEAT = new EdgeModeTex(GL_S, GL_REPEAT);
00040 const EdgeModeTex* TS_T_REPEAT = new EdgeModeTex(GL_T, GL_REPEAT);
00041 const EdgeModeTex* TS_R_REPEAT = new EdgeModeTex(GL_R, GL_REPEAT);
00042
00043 const FilterTex* TS_NEAREST = new FilterTex( GL_NEAREST, GL_NEAREST );
00044 const FilterTex* TS_LINEAR = new FilterTex( GL_LINEAR, GL_LINEAR );
00045
00046 const MipMapTex* TS_NEAREST_MIPMAP_NEAREST = new MipMapTex( GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST );
00047 const MipMapTex* TS_LINEAR_MIPMAP_NEAREST = new MipMapTex( GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR );
00048 const MipMapTex* TS_LINEAR_MIPMAP_LINEAR = new MipMapTex( GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR );
00049
00050 const FuncTex* TS_MODULATE = new FuncTex( GL_MODULATE );
00051 const FuncTex* TS_REPLACE = new FuncTex( GL_REPLACE );
00052 const FuncTex* TS_DECAL = new FuncTex( GL_DECAL );
00053 }
00054
00055
00056
00057
00058 EdgeModeTex::EdgeModeTex( GLenum coord, GLenum edgeMode )
00059 : m_coord(coord), m_edgeMode(edgeMode)
00060 {
00061 checkInput();
00062
00063
00064 switch(m_coord) {
00065 case GL_S: m_coord = GL_TEXTURE_WRAP_S; break;
00066 case GL_T: m_coord = GL_TEXTURE_WRAP_T; break;
00067 case GL_R: m_coord = GL_TEXTURE_WRAP_R; break;
00068 }
00069 }
00070
00071 void EdgeModeTex::checkInput()
00072 {
00073 if( m_coord != GL_S &&
00074 m_coord != GL_T &&
00075 m_coord != GL_R ) {
00076 err() << "checkInput() Error:\n"
00077 << "\tCoord must be GL_S, GL_T, or GL_R\n";
00078 exit(1);
00079 }
00080
00081
00082 if( m_edgeMode != GL_REPEAT &&
00083 m_edgeMode != GL_CLAMP &&
00084 m_edgeMode != GL_CLAMP_TO_EDGE )
00085
00086
00087
00088 {
00089 err() << "checkInput() Error:\n"
00090 << "\tedgeMode not supported\n";
00091 }
00092 }
00093
00094 void EdgeModeTex::bind( GLenum texType ) const
00095 {
00096 glTexParameteri( texType, m_coord, m_edgeMode );
00097 }
00098
00099
00100
00101
00102
00103 FilterTex::FilterTex( GLenum minFilter, GLenum magFilter )
00104 : m_minFilter(minFilter), m_magFilter(magFilter)
00105 {
00106 checkInput( m_minFilter, m_magFilter );
00107 }
00108
00109 void FilterTex::bind( GLenum texType ) const
00110 {
00111 glTexParameteri( texType, GL_TEXTURE_MIN_FILTER, m_minFilter );
00112 glTexParameteri( texType, GL_TEXTURE_MAG_FILTER, m_magFilter );
00113 }
00114
00115 void FilterTex::checkInput( GLenum minFilter, GLenum magFilter )
00116 {
00117 if( minFilter != GL_NEAREST &&
00118 minFilter != GL_LINEAR ) {
00119 err() << "checkInput() Error:\n"
00120 << "\tminFilter must be GL_NEAREST or GL_LINEAR. Use MipMapTex for mipmapping filters.\n";
00121 exit(1);
00122 }
00123
00124 if( magFilter != GL_NEAREST &&
00125 magFilter != GL_LINEAR ) {
00126 err() << "FilterTex::checkInput() Error:\n"
00127 << "\tmagFilter must be GL_NEAREST or GL_LINEAR.\n";
00128 exit(1);
00129 }
00130 }
00131
00132
00133
00134
00135 MipMapTex::MipMapTex( GLenum minFilter, GLenum magFilter, bool autoMipGen )
00136 : m_MIN_LEVEL( 0 ),
00137 m_MAX_LEVEL( 1000 ),
00138 m_MIN_LOD( -1000.0f ),
00139 m_MAX_LOD( 1000.0f ),
00140 m_minFilter( minFilter ),
00141 m_magFilter( magFilter ),
00142 m_autoMipGen( autoMipGen ),
00143 m_minLevel( m_MIN_LEVEL ),
00144 m_maxLevel( m_MAX_LEVEL ),
00145 m_minLOD( m_MIN_LOD ),
00146 m_maxLOD( m_MAX_LOD )
00147 {
00148 checkInput( minFilter, magFilter );
00149 }
00150
00151 MipMapTex::MipMapTex( GLenum minFilter, GLenum magFilter, bool autoMipGen,
00152 int minLevel, int maxLevel, float minLOD, float maxLOD )
00153 : m_MIN_LEVEL( 0 ),
00154 m_MAX_LEVEL( 1000 ),
00155 m_MIN_LOD( -1000.0f ),
00156 m_MAX_LOD( 1000.0f ),
00157 m_minFilter( minFilter ),
00158 m_magFilter( magFilter ),
00159 m_autoMipGen( autoMipGen ),
00160 m_minLevel( minLevel ),
00161 m_maxLevel( maxLevel ),
00162 m_minLOD( minLOD ),
00163 m_maxLOD( maxLOD )
00164 {
00165 checkInput( minFilter, magFilter );
00166 }
00167
00168 void MipMapTex::bind( GLenum texType ) const
00169 {
00170 glTexParameteri( texType, GL_TEXTURE_MIN_FILTER, m_minFilter );
00171 glTexParameteri( texType, GL_TEXTURE_MAG_FILTER, m_magFilter );
00172
00173 if( m_autoMipGen ) {
00174 glTexParameteri( texType, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00175 }
00176
00177 if( m_minLevel != m_MIN_LEVEL ) {
00178 glTexParameteri( texType, GL_TEXTURE_BASE_LEVEL, m_minLevel );
00179 }
00180
00181 if( m_maxLevel != m_MAX_LEVEL ) {
00182 glTexParameteri( texType, GL_TEXTURE_MAX_LEVEL, m_maxLevel );
00183 }
00184
00185 if( m_minLOD != m_MIN_LOD ) {
00186 glTexParameterf( texType, GL_TEXTURE_MIN_LOD, m_minLOD );
00187 }
00188
00189 if( m_minLOD != m_MAX_LOD ) {
00190 glTexParameterf( texType, GL_TEXTURE_MAX_LOD, m_maxLOD );
00191 }
00192 }
00193
00194 void MipMapTex::release() const
00195 {
00196
00197
00198
00199
00200
00201
00202 }
00203
00204 void MipMapTex::checkInput( GLenum minFilter, GLenum magFilter )
00205 {
00206 if( minFilter != GL_NEAREST_MIPMAP_NEAREST &&
00207 minFilter != GL_LINEAR_MIPMAP_NEAREST &&
00208 minFilter != GL_NEAREST_MIPMAP_LINEAR &&
00209 minFilter != GL_LINEAR_MIPMAP_LINEAR ) {
00210 err() << "MipMapTex::checkInput() Error:\n"
00211 << "\tminFilter must be GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST,\n"
00212 << "\tGL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR\n";
00213 exit(1);
00214 }
00215
00216 if( magFilter != GL_NEAREST &&
00217 magFilter != GL_LINEAR ) {
00218 err() << "MipMapTex::checkInput() Error:\n"
00219 << "\tmagFilter must be GL_NEAREST or GL_LINEAR.\n";
00220 exit(1);
00221 }
00222 }
00223
00224
00225
00226
00227 FuncTex::FuncTex( GLenum texFunc )
00228 : m_texFunc( texFunc ),
00229 m_blendColor( vec4f(0.0f) )
00230 {
00231 if( m_texFunc != GL_MODULATE &&
00232 m_texFunc != GL_REPLACE &&
00233 m_texFunc != GL_DECAL ) {
00234 err() << "FuncTex::FuncTex(...) Error:\n"
00235 << "\ttexFunc must be GL_MODULATE, GL_REPEAT, or GL_DECAL.\n"
00236 << "\tUse the 'blendColor' constructor if GL_BLEND is required.\n";
00237 exit(1);
00238 }
00239 }
00240
00241 FuncTex::FuncTex( const vec4f& blendColor )
00242 : m_texFunc( GL_BLEND ),
00243 m_blendColor( blendColor )
00244 {}
00245
00246 void FuncTex::bind( GLenum texType ) const
00247 {
00248 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_texFunc );
00249
00250 if( m_texFunc ) {
00251 glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, m_blendColor.v() );
00252 }
00253 }
00254
00255
00256
00257
00258
00259 PriorityTex::PriorityTex( GLfloat priority )
00260 {
00261 if( priority >= 0.0f &&
00262 priority <= 1.0f ) {
00263 m_priority = priority;
00264 }
00265 else {
00266 err() << "PriorityTex::PriorityTex(...) Error:\n"
00267 << "\tpriority must be in [0,1].\n";
00268 exit(1);
00269 }
00270 }
00271
00272 void PriorityTex::bind( GLenum texType ) const
00273 {
00274 glTexParameterf( texType, GL_TEXTURE_PRIORITY, m_priority );
00275 }
00276
00277
00278
00279
00280
00281 BorderTex::BorderTex( const vec4f& color )
00282 : m_color( color )
00283 {}
00284
00285 void BorderTex::bind( GLenum texType ) const
00286 {
00287 glTexParameterfv( texType, GL_TEXTURE_BORDER_COLOR, m_color.v() );
00288 }
00289
00290
00291
00292
00293 CoordGenTex::CoordGenTex( GLenum coord, GLenum genMode )
00294 : m_coord( coord ), m_genMode( genMode ), m_plane( vec4f(0.0f) ), m_state( VecStateP() )
00295 {
00296 checkInput();
00297 }
00298
00299 CoordGenTex::CoordGenTex( GLenum coord, GLenum genMode, const vec4f& planeCoeff, const VecStateP& state )
00300 : m_coord( coord ), m_genMode( genMode ), m_plane( planeCoeff ), m_state( state )
00301 {
00302 checkInput();
00303 }
00304
00305 void CoordGenTex::checkInput()
00306 {
00307 if( m_coord != GL_S &&
00308 m_coord != GL_T &&
00309 m_coord != GL_R &&
00310 m_coord != GL_Q ) {
00311 err() << "CoordGenTex::checkInput() Error:\n"
00312 << "\tcoord must be GL_S, GL_T, GL_R, or GL_S.\n";
00313 exit(1);
00314 }
00315
00316 if( m_genMode != GL_OBJECT_LINEAR &&
00317 m_genMode != GL_EYE_LINEAR &&
00318 m_genMode != GL_EYE_LINEAR &&
00319 m_genMode != GL_REFLECTION_MAP_ARB &&
00320 m_genMode != GL_NORMAL_MAP_ARB ) {
00321 err() << "CoordGenTex::checkInput() Error:\n"
00322 << "\tgenMode must be GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP,\n"
00323 << "\tGL_REFLECTION_MAP_ARB or GL_NORMAL_MAP_ARB.\n";
00324 exit(1);
00325 }
00326
00327 switch( m_coord ) {
00328 case GL_S: m_coordGen = GL_TEXTURE_GEN_S; break;
00329 case GL_T: m_coordGen = GL_TEXTURE_GEN_T; break;
00330 case GL_R: m_coordGen = GL_TEXTURE_GEN_R; break;
00331 case GL_Q: m_coordGen = GL_TEXTURE_GEN_Q; break;
00332 }
00333 }
00334
00335 void CoordGenTex::bind( GLenum texType ) const
00336 {
00337 glEnable( m_coordGen );
00338 glTexGeni( m_coord, GL_TEXTURE_GEN_MODE, m_genMode );
00339
00340 if( m_genMode == GL_OBJECT_LINEAR ) {
00341 glTexGenfv(m_coord, GL_OBJECT_PLANE, m_plane.v() );
00342 }
00343 else if( m_genMode == GL_EYE_LINEAR ) {
00344 int i;
00345 for(i=0; i < (int)m_state.size(); i++) {
00346 m_state[i]->bind();
00347 }
00348
00349 glTexGenfv(m_coord, GL_EYE_PLANE, m_plane.v() );
00350
00351 for(i=m_state.size()-1; i >= 0; i--) {
00352 m_state[i]->release();
00353 }
00354 }
00355 }
00356
00357 void CoordGenTex::release() const
00358 {
00359 glDisable( m_coordGen );
00360 }
00361
00362