arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

texState.cpp

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////
00002 // 9/6/02       Aaron Lefohn    Scientific Computing and Imaging Institute
00003 // School of Computing          University of Utah
00004 //
00005 //  This library is free software; you can redistribute it and/or
00006 //  modify it under the terms of the GNU Lesser General Public
00007 //  License as published by the Free Software Foundation; either
00008 //  version 2.1 of the License, or (at your option) any later version.
00009 //
00010 //  This library is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 //  Lesser General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU Lesser General Public
00016 //  License along with this library; if not, write to the Free Software
00017 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 /// Global, pre-defined TexState pointers
00031 /// - These are here for conveniently pre-defined states that are common
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 /// EdgeModeTex
00057 ///////////////////////////////////////////////////////
00058 EdgeModeTex::EdgeModeTex( GLenum coord, GLenum edgeMode )
00059 : m_coord(coord), m_edgeMode(edgeMode)
00060 {
00061    checkInput();
00062 
00063    /// Set the m_coord to the real value. No reason for default b/c checkInput() took care of it.
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       /// TODO: Add arch-dependent extensions here
00082       if( m_edgeMode != GL_REPEAT &&
00083          m_edgeMode != GL_CLAMP &&
00084          m_edgeMode != GL_CLAMP_TO_EDGE ) //&&
00085          /*m_edgeMode != GL_CLAMP_TO_BORDER_ARB &&
00086          m_edgeMode != GL_MIRROR_CLAMP_ATI &&
00087          m_edgeMode != GL_MIRROR_CLAMP_TO_EDGE_ATI &&*/
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 /// FilterTex 
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 /// MipMapTex
00134 ///////////////////////////////////////////////////////
00135 MipMapTex::MipMapTex( GLenum minFilter, GLenum magFilter, bool autoMipGen )
00136 : m_MIN_LEVEL( 0 ),                     /// OpenGL defaults (according to RedBook 1.2)
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 ),                        /// OpenGL defaults (according to RedBook 1.2)
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    /*   glTexParameteri( texType, GL_GENERATE_MIPMAP_SGIS, GL_FALSE      );
00197    glTexParameteri( texType, GL_TEXTURE_BASE_LEVEL, m_MIN_LEVEL );
00198    glTexParameteri( texType, GL_TEXTURE_MAX_LEVEL,  m_MAX_LEVEL );
00199    glTexParameteri( texType, GL_TEXTURE_MIN_LOD,         m_MIN_LOD   );
00200    glTexParameteri( texType, GL_TEXTURE_MAX_LOD,         m_MAX_LOD   );
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 /// FuncTex
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 /// PriorityTex - 'priority' is in [0,1] and sets the texture object's priority
00257 ///                        - 0.0 is lowest, 1.0 is highest priority
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 /// BorderTex
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 /// CoordGenTex 
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       /// Default: Disable automatic coordGen
00358 {
00359    glDisable( m_coordGen );
00360 }
00361 
00362 

Send questions, comments, and bug reports to:
jmk