Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/Shader.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlGraphics/Shader.hpp>
00033 #include <vlGraphics/GLSL.hpp>
00034 #include <vlGraphics/Light.hpp>
00035 #include <vlGraphics/ClipPlane.hpp>
00036 #include <vlGraphics/OpenGLContext.hpp>
00037 #include <vlCore/Log.hpp>
00038 #include <vlCore/Say.hpp>
00039 
00040 using namespace vl;
00041 
00042 //------------------------------------------------------------------------------
00043 // Shader
00044 //------------------------------------------------------------------------------
00045 Shader::Shader()
00046 {
00047   VL_DEBUG_SET_OBJECT_NAME()
00048   mLastUpdateTime = 0;
00049   // shader user data
00050   #if VL_SHADER_USER_DATA
00051     mShaderUserData = NULL;
00052   #endif
00053 }
00054 //------------------------------------------------------------------------------
00055 Shader::~Shader()
00056 {
00057 }
00058 //------------------------------------------------------------------------------
00059 const GLSLProgram* Shader::getGLSLProgram() const 
00060 { 
00061   return static_cast<const GLSLProgram*>( getRenderStateSet()->renderState( RS_GLSLProgram ) ); 
00062 }
00063 //------------------------------------------------------------------------------
00064 GLSLProgram* Shader::getGLSLProgram() 
00065 { 
00066   return static_cast<GLSLProgram*>( getRenderStateSet()->renderState( RS_GLSLProgram ) ); 
00067 }
00068 //------------------------------------------------------------------------------
00069 // state getters
00070 //------------------------------------------------------------------------------
00071 #define GET_OR_CREATE(RS)\
00072   RS* rs = static_cast<RS*>( gocRenderStateSet()->renderState( RS_##RS ) ); \
00073   if ( rs == NULL ) \
00074   { \
00075     rs = new RS; \
00076     gocRenderStateSet()->setRenderState( rs, -1 ); \
00077   } \
00078   return rs;
00079 //------------------------------------------------------------------------------
00080 #define GET_OR_CREATE_IDX(RS, index)\
00081   RS* rs = static_cast<RS*>( gocRenderStateSet()->renderState( RS_##RS, index ) ); \
00082   if ( rs == NULL ) \
00083   { \
00084     rs = new RS; \
00085     gocRenderStateSet()->setRenderState( rs, index ); \
00086   } \
00087   return rs;
00088 //------------------------------------------------------------------------------
00089 GLSLProgram* Shader::gocGLSLProgram() { GET_OR_CREATE(GLSLProgram); }
00090 //------------------------------------------------------------------------------
00091 PixelTransfer* Shader::gocPixelTransfer() { GET_OR_CREATE(PixelTransfer) }
00092 //------------------------------------------------------------------------------
00093 Hint* Shader::gocHint() { GET_OR_CREATE(Hint) }
00094 //------------------------------------------------------------------------------
00095 CullFace* Shader::gocCullFace() { GET_OR_CREATE(CullFace) }
00096 //------------------------------------------------------------------------------
00097 FrontFace* Shader::gocFrontFace() { GET_OR_CREATE(FrontFace) }
00098 //------------------------------------------------------------------------------
00099 DepthFunc* Shader::gocDepthFunc() { GET_OR_CREATE(DepthFunc) }
00100 //------------------------------------------------------------------------------
00101 DepthMask* Shader::gocDepthMask() { GET_OR_CREATE(DepthMask) }
00102 //------------------------------------------------------------------------------
00103 Color* Shader::gocColor() { GET_OR_CREATE(Color) }
00104 //------------------------------------------------------------------------------
00105 SecondaryColor* Shader::gocSecondaryColor() { GET_OR_CREATE(SecondaryColor) }
00106 //------------------------------------------------------------------------------
00107 Normal* Shader::gocNormal() { GET_OR_CREATE(Normal) }
00108 //------------------------------------------------------------------------------
00109 ColorMask* Shader::gocColorMask() { GET_OR_CREATE(ColorMask) }
00110 //------------------------------------------------------------------------------
00111 PolygonMode* Shader::gocPolygonMode() { GET_OR_CREATE(PolygonMode) }
00112 //------------------------------------------------------------------------------
00113 ShadeModel* Shader::gocShadeModel() { GET_OR_CREATE(ShadeModel) }
00114 //------------------------------------------------------------------------------
00115 BlendEquation* Shader::gocBlendEquation() { GET_OR_CREATE(BlendEquation) }
00116 //------------------------------------------------------------------------------
00117 AlphaFunc* Shader::gocAlphaFunc() { GET_OR_CREATE(AlphaFunc) }
00118 //------------------------------------------------------------------------------
00119 Material* Shader::gocMaterial() { GET_OR_CREATE(Material) }
00120 //------------------------------------------------------------------------------
00121 LightModel* Shader::gocLightModel() { GET_OR_CREATE(LightModel) }
00122 //------------------------------------------------------------------------------
00123 Fog* Shader::gocFog() { GET_OR_CREATE(Fog) }
00124 //------------------------------------------------------------------------------
00125 PolygonOffset* Shader::gocPolygonOffset() { GET_OR_CREATE(PolygonOffset) }
00126 //------------------------------------------------------------------------------
00127 LogicOp* Shader::gocLogicOp() { GET_OR_CREATE(LogicOp) }
00128 //------------------------------------------------------------------------------
00129 DepthRange* Shader::gocDepthRange() { GET_OR_CREATE(DepthRange) }
00130 //------------------------------------------------------------------------------
00131 LineWidth* Shader::gocLineWidth() { GET_OR_CREATE(LineWidth) }
00132 //------------------------------------------------------------------------------
00133 PointSize* Shader::gocPointSize() { GET_OR_CREATE(PointSize) }
00134 //------------------------------------------------------------------------------
00135 LineStipple* Shader::gocLineStipple() { GET_OR_CREATE(LineStipple) }
00136 //------------------------------------------------------------------------------
00137 PolygonStipple* Shader::gocPolygonStipple() { GET_OR_CREATE(PolygonStipple) }
00138 //------------------------------------------------------------------------------
00139 PointParameter* Shader::gocPointParameter() { GET_OR_CREATE(PointParameter) }
00140 //------------------------------------------------------------------------------
00141 StencilFunc* Shader::gocStencilFunc() { GET_OR_CREATE(StencilFunc) }
00142 //------------------------------------------------------------------------------
00143 StencilOp* Shader::gocStencilOp() { GET_OR_CREATE(StencilOp) }
00144 //------------------------------------------------------------------------------
00145 StencilMask* Shader::gocStencilMask() { GET_OR_CREATE(StencilMask) }
00146 //------------------------------------------------------------------------------
00147 BlendColor* Shader::gocBlendColor() { GET_OR_CREATE(BlendColor) }
00148 //------------------------------------------------------------------------------
00149 BlendFunc* Shader::gocBlendFunc() { GET_OR_CREATE(BlendFunc) }
00150 //------------------------------------------------------------------------------
00151 SampleCoverage* Shader::gocSampleCoverage() { GET_OR_CREATE(SampleCoverage) }
00152 //------------------------------------------------------------------------------
00153 VertexAttrib* Shader::gocVertexAttrib(int attr_index) { GET_OR_CREATE_IDX(VertexAttrib, attr_index) }
00154 //------------------------------------------------------------------------------
00155 const VertexAttrib* Shader::getVertexAttrib(int attr_index) const { if (!getRenderStateSet()) return NULL; else return static_cast<const VertexAttrib*>( getRenderStateSet()->renderState( RS_VertexAttrib, attr_index ) ); }
00156 //------------------------------------------------------------------------------
00157 VertexAttrib* Shader::getVertexAttrib(int attr_index) { if (!getRenderStateSet()) return NULL; else return static_cast<VertexAttrib*>( getRenderStateSet()->renderState( RS_VertexAttrib, attr_index ) ); }
00158 //------------------------------------------------------------------------------
00159 Light* Shader::gocLight(int light_index) { GET_OR_CREATE_IDX(Light, light_index) }
00160 //------------------------------------------------------------------------------
00161 const Light* Shader::getLight(int light_index) const { if (!getRenderStateSet()) return NULL; else return static_cast<const Light*>( getRenderStateSet()->renderState( RS_Light, light_index ) ); }
00162 //------------------------------------------------------------------------------
00163 Light* Shader::getLight(int light_index) { if (!getRenderStateSet()) return NULL; else return static_cast<Light*>( getRenderStateSet()->renderState( RS_Light, light_index ) ); }
00164 //------------------------------------------------------------------------------
00165 ClipPlane* Shader::gocClipPlane(int plane_index) { GET_OR_CREATE_IDX(ClipPlane, plane_index) }
00166 //------------------------------------------------------------------------------
00167 const ClipPlane* Shader::getClipPlane(int plane_index) const { if (!getRenderStateSet()) return NULL; else return static_cast<const ClipPlane*>( getRenderStateSet()->renderState( RS_ClipPlane, plane_index) ); }
00168 //------------------------------------------------------------------------------
00169 ClipPlane* Shader::getClipPlane(int plane_index) { if (!getRenderStateSet()) return NULL; else return static_cast<ClipPlane*>( getRenderStateSet()->renderState( RS_ClipPlane, plane_index) ); }
00170 //------------------------------------------------------------------------------
00171 TextureSampler* Shader::gocTextureSampler(int unit_index) { GET_OR_CREATE_IDX(TextureSampler, unit_index) }
00172 //------------------------------------------------------------------------------
00173 TexGen* Shader::gocTexGen(int unit_index) { GET_OR_CREATE_IDX(TexGen, unit_index) }
00174 //------------------------------------------------------------------------------
00175 TexEnv* Shader::gocTexEnv(int unit_index) { GET_OR_CREATE_IDX(TexEnv, unit_index) }
00176 //------------------------------------------------------------------------------
00177 TextureMatrix* Shader::gocTextureMatrix(int unit_index) { GET_OR_CREATE_IDX(TextureMatrix, unit_index) }
00178 //------------------------------------------------------------------------------
00179 // PixelTransfer
00180 //------------------------------------------------------------------------------
00181 void PixelTransfer::apply(int, const Camera*, OpenGLContext*) const
00182 {
00183   glPixelTransferi(GL_MAP_COLOR, mapColor() ? GL_TRUE : GL_FALSE);
00184   glPixelTransferi(GL_MAP_STENCIL, mapStencil() ? GL_TRUE : GL_FALSE);
00185   glPixelTransferi(GL_INDEX_SHIFT, indexShift() );
00186   glPixelTransferi(GL_INDEX_OFFSET, indexOffset() );
00187   glPixelTransferf(GL_RED_SCALE, redScale() );  
00188   glPixelTransferf(GL_GREEN_SCALE, greenScale() ); 
00189   glPixelTransferf(GL_BLUE_SCALE, blueScale() ); 
00190   glPixelTransferf(GL_ALPHA_SCALE, alphaScale() );
00191   glPixelTransferf(GL_DEPTH_SCALE, depthScale() );
00192   glPixelTransferf(GL_RED_BIAS, redBias() );
00193   glPixelTransferf(GL_GREEN_BIAS, greenBias() );  
00194   glPixelTransferf(GL_BLUE_BIAS, blueBias() );
00195   glPixelTransferf(GL_ALPHA_BIAS, alphaBias() ); 
00196   glPixelTransferf(GL_DEPTH_BIAS, depthBias() );
00197   VL_CHECK_OGL()
00198   if (Has_GL_ARB_imaging)
00199   {
00200     glPixelTransferf(GL_POST_COLOR_MATRIX_RED_SCALE, postColorMatrixRedScale() );
00201     glPixelTransferf(GL_POST_COLOR_MATRIX_GREEN_SCALE, postColorMatrixGreenScale() );
00202     glPixelTransferf(GL_POST_COLOR_MATRIX_BLUE_SCALE, postColorMatrixBlueScale() );
00203     glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_SCALE, postColorMatrixAlphaScale() );
00204     glPixelTransferf(GL_POST_COLOR_MATRIX_RED_BIAS, postColorMatrixRedBias() );
00205     glPixelTransferf(GL_POST_COLOR_MATRIX_GREEN_BIAS, postColorMatrixGreenBias() ); 
00206     glPixelTransferf(GL_POST_COLOR_MATRIX_BLUE_BIAS, postColorMatrixBlueBias() );
00207     glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_BIAS, postColorMatrixAlphaBias() );
00208     glPixelTransferf(GL_POST_CONVOLUTION_RED_SCALE, postConvolutionRedScale() );
00209     glPixelTransferf(GL_POST_CONVOLUTION_GREEN_SCALE, postConvolutionGreenScale() ); 
00210     glPixelTransferf(GL_POST_CONVOLUTION_BLUE_SCALE, postConvolutionBlueScale() );
00211     glPixelTransferf(GL_POST_CONVOLUTION_ALPHA_SCALE, postConvolutionAlphaScale() );
00212     glPixelTransferf(GL_POST_CONVOLUTION_RED_BIAS, postConvolutionRedBias() );
00213     glPixelTransferf(GL_POST_CONVOLUTION_GREEN_BIAS, postConvolutionGreenBias() );  
00214     glPixelTransferf(GL_POST_CONVOLUTION_BLUE_BIAS, postConvolutionBlueBias() );
00215     glPixelTransferf(GL_POST_CONVOLUTION_ALPHA_BIAS, postConvolutionAlphaBias() ); 
00216     VL_CHECK_OGL()
00217   }
00218 }
00219 //------------------------------------------------------------------------------
00220 // Hint
00221 //------------------------------------------------------------------------------
00222 void Hint::apply(int, const Camera*, OpenGLContext*) const
00223 {
00224   VL_CHECK_OGL()
00225 
00226   if( Has_Fixed_Function_Pipeline )
00227   {
00228     glHint( GL_PERSPECTIVE_CORRECTION_HINT, mPerspectiveCorrectionHint ); VL_CHECK_OGL()
00229     
00230     glHint( GL_FOG_HINT, mFogHint ); VL_CHECK_OGL()
00231 
00232     if (Has_GL_GENERATE_MIPMAP)
00233     {
00234       glHint( GL_GENERATE_MIPMAP_HINT, mGenerateMipmapHint ); VL_CHECK_OGL()
00235     }
00236   }
00237 
00238   if ( !Has_GLES )
00239   {
00240     glHint( GL_POLYGON_SMOOTH_HINT, mPolygonSmoothHint ); VL_CHECK_OGL()
00241   }
00242   if ( !Has_GLES_Version_2_0 )
00243   {
00244     glHint( GL_LINE_SMOOTH_HINT, mLineSmoothHint ); VL_CHECK_OGL()
00245     glHint( GL_POINT_SMOOTH_HINT, mPointSmoothHint ); VL_CHECK_OGL()
00246   }  
00247 }
00248 //------------------------------------------------------------------------------
00249 // CullFace
00250 //------------------------------------------------------------------------------
00251 void CullFace::apply(int, const Camera*, OpenGLContext*) const
00252 {
00253   glCullFace(mFaceMode); VL_CHECK_OGL()
00254 }
00255 //------------------------------------------------------------------------------
00256 // FrontFace
00257 //------------------------------------------------------------------------------
00258 void FrontFace::apply(int, const Camera*, OpenGLContext*) const
00259 {
00260   glFrontFace(mFrontFace); VL_CHECK_OGL()
00261 }
00262 //------------------------------------------------------------------------------
00263 // DepthFunc
00264 //------------------------------------------------------------------------------
00265 void DepthFunc::apply(int, const Camera*, OpenGLContext*) const
00266 {
00267   glDepthFunc(mDepthFunc); VL_CHECK_OGL()
00268 }
00269 //------------------------------------------------------------------------------
00270 // DepthMask
00271 //------------------------------------------------------------------------------
00272 void DepthMask::apply(int, const Camera*, OpenGLContext*) const
00273 {
00274   glDepthMask(mDepthMask?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00275 }
00276 //------------------------------------------------------------------------------
00277 // PolygonMode
00278 //------------------------------------------------------------------------------
00279 void PolygonMode::apply(int, const Camera*, OpenGLContext*) const
00280 {
00281   // required by GL 3.1 CORE
00282   if ( mFrontFace == mBackFace )
00283   {
00284     glPolygonMode(GL_FRONT_AND_BACK, mFrontFace); VL_CHECK_OGL()
00285   }
00286   else
00287   {
00288     glPolygonMode(GL_FRONT, mFrontFace); VL_CHECK_OGL()
00289     glPolygonMode(GL_BACK, mBackFace); VL_CHECK_OGL()
00290   }
00291 }
00292 //------------------------------------------------------------------------------
00293 // ShadeModel
00294 //------------------------------------------------------------------------------
00295 void ShadeModel::apply(int, const Camera*, OpenGLContext*) const
00296 {
00297   glShadeModel(mShadeModel); VL_CHECK_OGL()
00298 }
00299 //------------------------------------------------------------------------------
00300 // BlendFunc
00301 //------------------------------------------------------------------------------
00302 void BlendFunc::apply(int, const Camera*, OpenGLContext*) const
00303 {
00304   if (Has_GL_EXT_blend_func_separate||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GL_OES_blend_func_separate||Has_GLES_Version_2_0)
00305   { 
00306     VL_glBlendFuncSeparate(mSrcRGB, mDstRGB, mSrcAlpha, mDstAlpha); VL_CHECK_OGL()
00307   }
00308   else
00309   { 
00310     glBlendFunc(mSrcRGB, mDstRGB); VL_CHECK_OGL() // modifies rgb and alpha
00311   }
00312 }
00313 //------------------------------------------------------------------------------
00314 // BlendEquation
00315 //------------------------------------------------------------------------------
00316 void BlendEquation::apply(int, const Camera*, OpenGLContext*) const
00317 {
00318   if (Has_GL_Version_2_0||Has_GL_EXT_blend_equation_separate)
00319     { VL_glBlendEquationSeparate(mModeRGB, mModeAlpha); VL_CHECK_OGL() }
00320   else
00321     { VL_glBlendEquation(mModeRGB); VL_CHECK_OGL() }
00322 }
00323 //------------------------------------------------------------------------------
00324 // AlphaFunc
00325 //------------------------------------------------------------------------------
00326 void AlphaFunc::apply(int, const Camera*, OpenGLContext*) const
00327 {
00328   glAlphaFunc(mAlphaFunc, mRefValue); VL_CHECK_OGL()
00329 }
00330 //------------------------------------------------------------------------------
00331 // Material
00332 //------------------------------------------------------------------------------
00333 Material::Material()
00334 {
00335   VL_DEBUG_SET_OBJECT_NAME()
00336   mFrontAmbient = fvec4(0.2f, 0.2f, 0.2f, 1.0f);
00337   mFrontDiffuse = fvec4(0.8f, 0.8f, 0.8f, 1.0f);
00338   mFrontSpecular = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00339   mFrontEmission = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00340   mFrontShininess = 0;
00341 
00342   mBackAmbient = fvec4(0.2f, 0.2f, 0.2f, 1.0f);
00343   mBackDiffuse = fvec4(0.8f, 0.8f, 0.8f, 1.0f);
00344   mBackSpecular = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00345   mBackEmission = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00346   mBackShininess = 0;
00347 
00348   mColorMaterialEnabled = false;
00349   mColorMaterialFace = PF_FRONT_AND_BACK;
00350   mColorMaterial = CM_AMBIENT_AND_DIFFUSE;
00351 }
00352 //------------------------------------------------------------------------------
00353 float Material::getMinimumAlpha() const
00354 {
00355   float min_alpha = std::min( mFrontAmbient.a(),  mBackAmbient.a() );
00356   min_alpha = std::min( min_alpha, mFrontDiffuse.a() );
00357   min_alpha = std::min( min_alpha, mBackDiffuse.a()  );
00358   min_alpha = std::min( min_alpha, mFrontSpecular.a());
00359   min_alpha = std::min( min_alpha, mBackSpecular.a() );
00360   min_alpha = std::min( min_alpha, mFrontEmission.a());
00361   min_alpha = std::min( min_alpha, mBackEmission.a() );
00362   return min_alpha;
00363 }
00364 //------------------------------------------------------------------------------
00365 void Material::multiplyTransparency(float alpha)
00366 {
00367   mFrontAmbient.a()  *= alpha;
00368   mBackAmbient.a()   *= alpha;
00369   mFrontDiffuse.a()  *= alpha;
00370   mBackDiffuse.a()   *= alpha;
00371   mFrontSpecular.a() *= alpha;
00372   mBackSpecular.a()  *= alpha;
00373   mFrontEmission.a() *= alpha;
00374   mBackEmission.a()  *= alpha;
00375 }
00376 //------------------------------------------------------------------------------
00377 void Material::setTransparency(float alpha)
00378 {
00379   mFrontAmbient.a()   = mBackAmbient.a()   = alpha;
00380   mFrontDiffuse.a()   = mBackDiffuse.a()   = alpha;
00381   mFrontSpecular.a()  = mBackSpecular.a()  = alpha;
00382   mFrontEmission.a()  = mBackEmission.a()  = alpha;
00383 }
00384 //------------------------------------------------------------------------------
00385 void Material::setFrontTransparency(float alpha)
00386 {
00387   mFrontAmbient.a()  = alpha;
00388   mFrontDiffuse.a()  = alpha;
00389   mFrontSpecular.a() = alpha;
00390   mFrontEmission.a() = alpha;
00391 }
00392 //------------------------------------------------------------------------------
00393 void Material::setBackTransparency(float alpha)
00394 {
00395   mBackAmbient.a()  = alpha;
00396   mBackDiffuse.a()  = alpha;
00397   mBackSpecular.a() = alpha;
00398   mBackEmission.a() = alpha;
00399 }
00400 //------------------------------------------------------------------------------
00401 void Material::setFrontFlatColor(const fvec4& color)
00402 {
00403   mFrontAmbient  = 0;
00404   mFrontDiffuse  = 0;
00405   mFrontSpecular = 0;
00406   mFrontEmission = color;
00407   mFrontShininess = 0;
00408   setFrontTransparency(color.a());
00409 }
00410 //------------------------------------------------------------------------------
00411 void Material::setBackFlatColor(const fvec4& color)
00412 {
00413   mBackAmbient  = 0;
00414   mBackDiffuse  = 0;
00415   mBackSpecular = 0;
00416   mBackEmission = color;
00417   mBackShininess = 0;
00418   setBackTransparency(color.a());
00419 }
00420 //------------------------------------------------------------------------------
00421 void Material::setFlatColor(const fvec4& color)
00422 {
00423   setFrontFlatColor(color);
00424   setBackFlatColor(color);
00425 }
00426 //------------------------------------------------------------------------------
00427 void Material::apply(int, const Camera*, OpenGLContext*) const
00428 {
00429   VL_CHECK_OGL();
00430 
00431 #if defined(VL_OPENGL)
00432 
00433   if (mColorMaterialEnabled)
00434   {
00435     glColorMaterial(colorMaterialFace(), colorMaterial()); VL_CHECK_OGL();
00436     glEnable(GL_COLOR_MATERIAL); VL_CHECK_OGL();
00437   }
00438   else
00439   {
00440     glDisable(GL_COLOR_MATERIAL); VL_CHECK_OGL();
00441   }
00442 
00443   if ( mFrontAmbient == mBackAmbient )
00444   {
00445     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mFrontAmbient.ptr()); 
00446   }
00447   else
00448   {
00449     glMaterialfv(GL_FRONT, GL_AMBIENT, mFrontAmbient.ptr()); 
00450     glMaterialfv(GL_BACK, GL_AMBIENT, mBackAmbient.ptr());
00451   }
00452 
00453   if ( mFrontDiffuse == mBackDiffuse )
00454   {
00455     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mFrontDiffuse.ptr()); 
00456   }
00457   else
00458   {
00459     glMaterialfv(GL_FRONT, GL_DIFFUSE, mFrontDiffuse.ptr()); 
00460     glMaterialfv(GL_BACK, GL_DIFFUSE, mBackDiffuse.ptr());
00461   }
00462 
00463   if ( mFrontSpecular == mBackSpecular )
00464   {
00465     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mFrontSpecular.ptr()); 
00466   }
00467   else
00468   {
00469     glMaterialfv(GL_FRONT, GL_SPECULAR, mFrontSpecular.ptr()); 
00470     glMaterialfv(GL_BACK, GL_SPECULAR, mBackSpecular.ptr());
00471   }
00472 
00473   if ( mFrontEmission == mBackEmission )
00474   {
00475     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mFrontEmission.ptr()); 
00476   }
00477   else
00478   {
00479     glMaterialfv(GL_FRONT, GL_EMISSION, mFrontEmission.ptr()); 
00480     glMaterialfv(GL_BACK, GL_EMISSION, mBackEmission.ptr());
00481   }
00482 
00483   if ( mFrontShininess == mBackShininess )
00484   {
00485     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mFrontShininess); VL_CHECK_OGL();
00486   }
00487   else
00488   {
00489     glMaterialf(GL_FRONT, GL_SHININESS, mFrontShininess); VL_CHECK_OGL();
00490     glMaterialf(GL_BACK, GL_SHININESS, mBackShininess); VL_CHECK_OGL();
00491   }
00492 
00493 
00494 #else
00495 
00496   if (mColorMaterialEnabled)
00497   {
00498     // OpenGL ES supports only this
00499     if (colorMaterial() != CM_AMBIENT_AND_DIFFUSE)
00500     {
00501       Log::error("OpenGL ES 1.x supports only CM_AMBIENT_AND_DIFFUSE color material mode!\n");
00502       VL_TRAP();
00503     }
00504     glEnable(GL_COLOR_MATERIAL); VL_CHECK_OGL();
00505   }
00506   else
00507   {
00508     glDisable(GL_COLOR_MATERIAL); VL_CHECK_OGL();
00509   }
00510 
00511   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mFrontAmbient.ptr()); 
00512   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mFrontDiffuse.ptr()); 
00513   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mFrontSpecular.ptr()); 
00514   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mFrontEmission.ptr()); 
00515   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mFrontShininess); VL_CHECK_OGL();
00516 
00517 #endif
00518 
00519   VL_CHECK_OGL();
00520 }
00521 //------------------------------------------------------------------------------
00522 // LightModel
00523 //------------------------------------------------------------------------------
00524 void LightModel::apply(int, const Camera*, OpenGLContext*) const
00525 {
00526   if (Has_GL_Version_1_2||Has_GL_EXT_separate_specular_color)
00527   { 
00528     glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, (float)mColorControl); VL_CHECK_OGL() 
00529   }
00530 
00531   if (Has_GL_Version_1_1)
00532     glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, mLocalViewer ? 1.0f : 0.0f ); VL_CHECK_OGL()
00533 
00534   // Supported by GLES 1.x as well.
00535   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mAmbientColor.ptr()); VL_CHECK_OGL()
00536   glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, mTwoSide ? 1.0f : 0.0f ); VL_CHECK_OGL()
00537 }
00538 //------------------------------------------------------------------------------
00539 // Fog
00540 //------------------------------------------------------------------------------
00541 void Fog::apply(int, const Camera*, OpenGLContext*) const
00542 {
00543   glFogf(GL_FOG_MODE, (float)mMode); VL_CHECK_OGL()
00544   glFogf(GL_FOG_DENSITY, mDensity); VL_CHECK_OGL()
00545   glFogf(GL_FOG_START, mStart); VL_CHECK_OGL()
00546   glFogf(GL_FOG_END, mEnd); VL_CHECK_OGL()
00547   glFogfv(GL_FOG_COLOR, mColor.ptr()); VL_CHECK_OGL()
00548 }
00549 
00550 //------------------------------------------------------------------------------
00551 // PolygonOffset
00552 //------------------------------------------------------------------------------
00553 void PolygonOffset::apply(int, const Camera*, OpenGLContext*) const
00554 {
00555   glPolygonOffset(mFactor, mUnits); VL_CHECK_OGL()
00556 }
00557 //------------------------------------------------------------------------------
00558 // LogicOp
00559 //------------------------------------------------------------------------------
00560 void LogicOp::apply(int, const Camera*, OpenGLContext*) const
00561 {
00562   glLogicOp(mLogicOp); VL_CHECK_OGL()
00563 }
00564 //------------------------------------------------------------------------------
00565 // DepthRange
00566 //------------------------------------------------------------------------------
00567 void DepthRange::apply(int, const Camera*, OpenGLContext*) const
00568 {
00569   glDepthRange(mZNear, mZFar); VL_CHECK_OGL()
00570 }
00571 //------------------------------------------------------------------------------
00572 // LineWidth
00573 //------------------------------------------------------------------------------
00574 void LineWidth::apply(int, const Camera*, OpenGLContext*) const
00575 {
00576   glLineWidth(mLineWidth); VL_CHECK_OGL()
00577 }
00578 //------------------------------------------------------------------------------
00579 // PointSize
00580 //------------------------------------------------------------------------------
00581 void PointSize::apply(int, const Camera*, OpenGLContext*) const
00582 {
00583   glPointSize(mPointSize); VL_CHECK_OGL()
00584 }
00585 //------------------------------------------------------------------------------
00586 // PolygonStipple
00587 //------------------------------------------------------------------------------
00588 PolygonStipple::PolygonStipple()
00589 {
00590   VL_DEBUG_SET_OBJECT_NAME()
00591   memset(mMask, 0xFF, sizeof(unsigned char)*32*32/8);
00592 }
00593 //------------------------------------------------------------------------------
00594 PolygonStipple::PolygonStipple(const unsigned char* mask)
00595 {
00596   VL_DEBUG_SET_OBJECT_NAME()
00597   set(mask);
00598 }
00599 //------------------------------------------------------------------------------
00600 void PolygonStipple::set(const unsigned char* mask)
00601 {
00602   memcpy(mMask, mask, sizeof(unsigned char)*32*32/8);
00603 }
00604 //------------------------------------------------------------------------------
00605 void PolygonStipple::apply(int, const Camera*, OpenGLContext*) const
00606 {
00607   glPolygonStipple(mask()); VL_CHECK_OGL()
00608 }
00609 //------------------------------------------------------------------------------
00610 // LineStipple
00611 //------------------------------------------------------------------------------
00612 void LineStipple::apply(int, const Camera*, OpenGLContext*) const
00613 {
00614   glLineStipple(mFactor, mPattern); VL_CHECK_OGL()
00615 }
00616 //------------------------------------------------------------------------------
00617 // PointParameter
00618 //------------------------------------------------------------------------------
00619 void PointParameter::apply(int, const Camera*, OpenGLContext*) const
00620 {
00621   if (Has_GL_Version_1_4||Has_GLES_Version_1_1)
00622   {
00623     VL_glPointParameterf(GL_POINT_SIZE_MIN, mSizeMin); VL_CHECK_OGL()
00624     VL_glPointParameterf(GL_POINT_SIZE_MAX, mSizeMax); VL_CHECK_OGL()
00625     VL_glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (const float*)mDistanceAttenuation.ptr()); VL_CHECK_OGL()
00626   }
00627   if (Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GLES_Version_1_1)
00628   {
00629     VL_glPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, mFadeThresholdSize); VL_CHECK_OGL()
00630   }
00631   if (Has_GL_Version_2_0||Has_GL_Version_3_0||Has_GL_Version_4_0)
00632   {
00633     VL_glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, mPointSpriteCoordOrigin); VL_CHECK_OGL()
00634   }
00635 }
00636 //------------------------------------------------------------------------------
00637 // StencilFunc
00638 //------------------------------------------------------------------------------
00639 void StencilFunc::apply(int, const Camera*, OpenGLContext*) const
00640 {
00641   if(Has_GL_Version_2_0)
00642   {
00643     VL_glStencilFuncSeparate(GL_FRONT, mFunction_Front, mRefValue_Front, mMask_Front); VL_CHECK_OGL()
00644     VL_glStencilFuncSeparate(GL_BACK,  mFunction_Back,  mRefValue_Back,  mMask_Back);  VL_CHECK_OGL()
00645   }
00646   else
00647   {
00648     glStencilFunc(mFunction_Front, mRefValue_Front, mMask_Front); VL_CHECK_OGL()
00649   }
00650 }
00651 //------------------------------------------------------------------------------
00652 // StencilOp
00653 //------------------------------------------------------------------------------
00654 void StencilOp::apply(int, const Camera*, OpenGLContext*) const
00655 {
00656   if(Has_GL_Version_2_0)
00657   {
00658     VL_glStencilOpSeparate(GL_FRONT, mSFail_Front, mDpFail_Front, mDpPass_Front); VL_CHECK_OGL()
00659     VL_glStencilOpSeparate(GL_BACK,  mSFail_Back,  mDpFail_Back,  mDpPass_Back);  VL_CHECK_OGL()
00660   }
00661   else
00662   {
00663     glStencilOp(mSFail_Front, mDpFail_Front, mDpPass_Front); VL_CHECK_OGL()
00664   }
00665 }
00666 //------------------------------------------------------------------------------
00667 // StencilMask
00668 //------------------------------------------------------------------------------
00669 void StencilMask::apply(int, const Camera*, OpenGLContext*) const
00670 {
00671   if(Has_GL_Version_2_0)
00672   {
00673     glStencilMaskSeparate(GL_FRONT, mMask_Front); VL_CHECK_OGL()
00674     glStencilMaskSeparate(GL_BACK,  mMask_Back);  VL_CHECK_OGL()
00675   }
00676   else
00677   {
00678     glStencilMask(mMask_Front); VL_CHECK_OGL()
00679   }
00680 }
00681 //------------------------------------------------------------------------------
00682 // BlendColor
00683 //------------------------------------------------------------------------------
00684 void BlendColor::apply(int, const Camera*, OpenGLContext*) const
00685 {
00686   VL_glBlendColor(mBlendColor.r(), mBlendColor.g(), mBlendColor.b(), mBlendColor.a()); VL_CHECK_OGL()
00687 }
00688 //------------------------------------------------------------------------------
00689 // VertexAttrib
00690 //------------------------------------------------------------------------------
00691 void VertexAttrib::apply(int index, const Camera*, OpenGLContext* ctx) const
00692 {
00693   glVertexAttrib4fv( index, mValue.ptr() ); VL_CHECK_OGL()
00694   ctx->mVertexAttribValue[index] = mValue;
00695 }
00696 //------------------------------------------------------------------------------
00697 // Color
00698 //------------------------------------------------------------------------------
00699 void Color::apply(int, const Camera*, OpenGLContext* ctx) const
00700 {
00701   glColor4f( mColor.r(), mColor.g(), mColor.b(), mColor.a() ); VL_CHECK_OGL()
00702   ctx->mColor = mColor;
00703 }
00704 //------------------------------------------------------------------------------
00705 // SecondaryColor
00706 //------------------------------------------------------------------------------
00707 void SecondaryColor::apply(int, const Camera*, OpenGLContext* ctx) const
00708 {
00709   VL_glSecondaryColor3f( mSecondaryColor.r(), mSecondaryColor.g(), mSecondaryColor.b() ); VL_CHECK_OGL()
00710   ctx->mSecondaryColor = mSecondaryColor;
00711 }
00712 //------------------------------------------------------------------------------
00713 // Normal
00714 //------------------------------------------------------------------------------
00715 void Normal::apply(int, const Camera*, OpenGLContext* ctx) const
00716 {
00717   glNormal3f( mNormal.x(), mNormal.y(), mNormal.z() ); VL_CHECK_OGL()
00718   ctx->mNormal = mNormal;
00719 }
00720 //------------------------------------------------------------------------------
00721 // ColorMask
00722 //------------------------------------------------------------------------------
00723 void ColorMask::apply(int, const Camera*, OpenGLContext*) const
00724 {
00725   glColorMask(mRed?GL_TRUE:GL_FALSE, mGreen?GL_TRUE:GL_FALSE, mBlue?GL_TRUE:GL_FALSE, mAlpha?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00726 }
00727 //------------------------------------------------------------------------------
00728 // SampleCoverage
00729 //------------------------------------------------------------------------------
00730 void SampleCoverage::apply(int, const Camera*, OpenGLContext*) const
00731 {
00732   VL_glSampleCoverage(mValue, mInvert?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00733 }
00734 //------------------------------------------------------------------------------
00735 // TexParameter
00736 //------------------------------------------------------------------------------
00737 TexParameter::TexParameter()
00738 {
00739   mDirty = true;
00740   setMinFilter(TPF_LINEAR);
00741   setMagFilter(TPF_LINEAR);
00742   setWrapS(TPW_REPEAT);
00743   setWrapT(TPW_REPEAT);
00744   setWrapR(TPW_REPEAT);
00745   setBorderColor(fvec4(0,0,0,0));
00746   setAnisotropy(1.0f);
00747   setGenerateMipmap(false);
00748   setCompareFunc(TCF_LEQUAL);
00749   setCompareMode(TCM_NONE);
00750   setDepthTextureMode(DTM_LUMINANCE);
00751 }
00752 //------------------------------------------------------------------------------
00753 void TexParameter::setMagFilter(ETexParamFilter magfilter) 
00754 { 
00755   mDirty = true;
00756 
00757   switch(magfilter)
00758   {
00759     case TPF_LINEAR:
00760     case TPF_NEAREST:
00761     {
00762       mMagfilter = magfilter; 
00763       break;
00764     }
00765     default:
00766     {
00767       mMagfilter = TPF_LINEAR; 
00768       #ifndef NDEBUG
00769         Log::bug("TexParameter::setMagFilter() accepts only the following values: TPF_LINEAR, TPF_NEAREST.\n");
00770       #endif
00771     }
00772   }
00773 }
00774 //------------------------------------------------------------------------------
00775 void TexParameter::apply(ETextureDimension dimension, OpenGLContext* ) const
00776 {
00777   VL_CHECK_OGL()
00778 
00779 #ifndef NDEBUG
00780   if (dimension == TD_TEXTURE_RECTANGLE)
00781   {
00782     bool err = (wrapS() != GL_CLAMP && wrapS() != GL_CLAMP_TO_EDGE && wrapS() != GL_CLAMP_TO_BORDER) |
00783                (wrapT() != GL_CLAMP && wrapT() != GL_CLAMP_TO_EDGE && wrapT() != GL_CLAMP_TO_BORDER) |
00784                (wrapR() != GL_CLAMP && wrapR() != GL_CLAMP_TO_EDGE && wrapR() != GL_CLAMP_TO_BORDER);
00785     if (err)
00786     {
00787       Log::bug("ARB_texture_rectangle extension allows only the following wrapping modes: GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER.\n"); VL_TRAP()
00788     }
00789   }
00790 
00791   if (wrapS() == GL_MIRRORED_REPEAT || wrapT() == GL_MIRRORED_REPEAT || wrapR() == GL_MIRRORED_REPEAT)
00792   {
00793     if( !(Has_GL_IBM_texture_mirrored_repeat || Has_GL_ARB_texture_mirrored_repeat || Has_GL_Version_1_4 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GLES_Version_2_0) )
00794     {
00795       Log::bug("GL_MIRRORED_REPEAT not supported by your OpenGL implementation.\n"); VL_TRAP()
00796     }
00797   }
00798 
00799   if (wrapS() == GL_CLAMP_TO_EDGE || wrapT() == GL_CLAMP_TO_EDGE || wrapR() == GL_CLAMP_TO_EDGE)
00800   {
00801     if( !(Has_GL_SGIS_texture_edge_clamp || Has_GL_Version_1_2 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GLES_Version_1_1 || Has_GLES_Version_2_0) )
00802     {
00803       Log::bug("GL_CLAMP_TO_EDGE not supported by your OpenGL implementation.\n"); VL_TRAP()
00804     }
00805   }
00806 
00807   if (wrapS() == GL_CLAMP_TO_BORDER || wrapT() == GL_CLAMP_TO_BORDER || wrapR() == GL_CLAMP_TO_BORDER)
00808   {
00809     if( !(Has_GL_SGIS_texture_border_clamp || Has_GL_ARB_texture_border_clamp || Has_GL_Version_1_3 || Has_GL_Version_3_0 || Has_GL_Version_4_0) )
00810     {
00811       Log::bug("GL_CLAMP_TO_BORDER not supported by your OpenGL implementation.\n"); VL_TRAP()
00812     }
00813   }
00814 #endif
00815 
00816   // none of these are supported by texture buffers and multisample textures
00817 
00818   if (dimension != TD_TEXTURE_BUFFER && dimension != TD_TEXTURE_2D_MULTISAMPLE && dimension != TD_TEXTURE_2D_MULTISAMPLE_ARRAY)
00819   {
00820 #if defined(VL_OPENGL)
00821     glTexParameterfv(dimension, GL_TEXTURE_BORDER_COLOR, borderColor().ptr()); VL_CHECK_OGL()
00822 #endif
00823     glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, minFilter()); VL_CHECK_OGL()
00824     glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, magFilter()); VL_CHECK_OGL()
00825     glTexParameteri(dimension, GL_TEXTURE_WRAP_S, wrapS()); VL_CHECK_OGL()
00826     glTexParameteri(dimension, GL_TEXTURE_WRAP_T, wrapT()); VL_CHECK_OGL()
00827     if (Has_Texture_3D) 
00828       glTexParameteri(dimension, GL_TEXTURE_WRAP_R, wrapR()); VL_CHECK_OGL()
00829 
00830     if (Has_GL_EXT_texture_filter_anisotropic)
00831       glTexParameterf( dimension, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy() ); VL_CHECK_OGL()
00832 
00833     if (Has_GL_GENERATE_MIPMAP && dimension != TD_TEXTURE_RECTANGLE)
00834       glTexParameteri(dimension, GL_GENERATE_MIPMAP, generateMipmap() ? GL_TRUE : GL_FALSE); VL_CHECK_OGL()
00835 
00836     if (Has_GL_ARB_shadow||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0)
00837     {
00838       glTexParameteri(dimension, GL_TEXTURE_COMPARE_MODE, compareMode() ); VL_CHECK_OGL()
00839       glTexParameteri(dimension, GL_TEXTURE_COMPARE_FUNC, compareFunc() ); VL_CHECK_OGL()
00840       if(Has_GL_Version_1_4)
00841         glTexParameteri(dimension, GL_DEPTH_TEXTURE_MODE, depthTextureMode() ); VL_CHECK_OGL()
00842     }
00843   }
00844 
00845   mDirty = false;
00846 
00847   VL_CHECK_OGL()
00848 }
00849 namespace
00850 {
00851   bool checkTextureSampler(const char* str, int unit)
00852   {
00853     int max_texture = 1, max_tmp = 0;
00854 
00855     if (Has_GL_Version_1_3||Has_GL_ARB_multitexture||Has_GLES_Version_1_1)
00856     {
00857       glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
00858       max_texture = max_tmp > max_texture ? max_tmp : max_texture;
00859     }
00860 
00861     if (Has_GL_Version_2_0)
00862     {
00863       glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_tmp); VL_CHECK_OGL(); // also deprecated enum
00864       max_texture = max_tmp > max_texture ? max_tmp : max_texture;
00865     }
00866 
00867     if (Has_GLSL)
00868     {
00869       glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_tmp); VL_CHECK_OGL();
00870       max_texture = max_tmp > max_texture ? max_tmp : max_texture;
00871     }
00872 
00873     if (unit > max_texture-1)
00874     {
00875       Log::bug( Say("%s error: texture unit index #%n not supported by this OpenGL implementation. Max texture unit index is %n.\n") << str << unit << max_texture-1 );
00876       return false;
00877     }
00878 
00879     return true;
00880   }
00881 }
00882 //------------------------------------------------------------------------------
00883 // TexEnv
00884 //------------------------------------------------------------------------------
00885 TexEnv::TexEnv()
00886 {
00887   VL_DEBUG_SET_OBJECT_NAME()
00888 
00889   mMode = TEM_MODULATE;
00890   mColor = fvec4(0,0,0,0);
00891 
00892   // combiner settings
00893   mRGBScale = 1.0f;
00894   mCombineRGB = TEM_REPLACE;
00895   mSource0RGB = TES_TEXTURE;
00896   mSource1RGB = TES_TEXTURE;
00897   mSource2RGB = TES_TEXTURE;
00898   mOperand0RGB = TEO_SRC_COLOR;
00899   mOperand1RGB = TEO_SRC_COLOR;
00900   mOperand2RGB = TEO_SRC_COLOR;
00901 
00902   mAlphaScale  = 1.0f;
00903   mCombineAlpha = TEM_REPLACE;
00904   mSource0Alpha = TES_TEXTURE;
00905   mSource1Alpha = TES_TEXTURE;
00906   mSource2Alpha = TES_TEXTURE;
00907   mOperand0Alpha = TEO_SRC_ALPHA;
00908   mOperand1Alpha = TEO_SRC_ALPHA;
00909   mOperand2Alpha = TEO_SRC_ALPHA;
00910 
00911   mLodBias = 0.0;
00912   mPointSpriteCoordReplace = false;
00913 }
00914 //------------------------------------------------------------------------------
00915 void TexEnv::apply(int index, const Camera*, OpenGLContext*) const
00916 {
00917   VL_CHECK_OGL()
00918   VL_CHECK(index < VL_MAX_TEXTURE_UNITS)
00919   VL_CHECK(checkTextureSampler("TexEnv::apply", index));
00920 
00921   // if this fails probably you requested a texture unit index not supported by your OpenGL implementation.
00922   VL_glActiveTexture( GL_TEXTURE0 + index ); VL_CHECK_OGL();
00923 
00924   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode()); VL_CHECK_OGL()
00925 
00926   // red book 1.4 p411
00927   if (mode() == TEM_BLEND)
00928   {
00929     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color().ptr()); VL_CHECK_OGL()
00930   }
00931 
00932   // combiner settings
00933   // red book 1.4 p438
00934   if (mode() == TEM_COMBINE && (Has_GL_EXT_texture_env_combine || Has_GL_Version_1_3))
00935   {
00936     glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, rgbScale()); VL_CHECK_OGL()
00937     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB()); VL_CHECK_OGL()
00938     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, source0RGB()); VL_CHECK_OGL()
00939     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, source1RGB()); VL_CHECK_OGL()
00940     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, operand0RGB()); VL_CHECK_OGL()
00941     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, operand1RGB()); VL_CHECK_OGL()
00942     if (combineRGB() == TEM_INTERPOLATE)
00943     {
00944       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, source2RGB()); VL_CHECK_OGL()
00945       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, operand2RGB()); VL_CHECK_OGL()
00946     }
00947 
00948     glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, alphaScale()); VL_CHECK_OGL()
00949     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha()); VL_CHECK_OGL()
00950     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, source0Alpha()); VL_CHECK_OGL()
00951     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, source1Alpha()); VL_CHECK_OGL()
00952     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, operand0Alpha()); VL_CHECK_OGL()
00953     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, operand1Alpha()); VL_CHECK_OGL()
00954     if (combineAlpha() == TEM_INTERPOLATE)
00955     {
00956       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, source2Alpha()); VL_CHECK_OGL()
00957       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, operand2Alpha()); VL_CHECK_OGL()
00958     }
00959   }
00960 
00961   // no need to do it if point sprite is disabled but we cannot know it here
00962   if (Has_Point_Sprite)
00963   {
00964     glTexEnvi( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, mPointSpriteCoordReplace ? GL_TRUE : GL_FALSE ); VL_CHECK_OGL()
00965   }
00966 
00967   if (Has_GL_Version_1_4||Has_GL_EXT_texture_lod_bias)
00968   {
00969     glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, mLodBias); VL_CHECK_OGL()
00970   }
00971 }
00972 //-----------------------------------------------------------------------------
00973 // TexGen
00974 //-----------------------------------------------------------------------------
00978 TexGen::TexGen()
00979 {
00980   VL_DEBUG_SET_OBJECT_NAME()
00981   mEyePlaneS    = fvec4(1,0,0,0);
00982   mObjectPlaneS = fvec4(1,0,0,0);
00983   mEyePlaneT    = fvec4(0,1,0,0);
00984   mObjectPlaneT = fvec4(0,1,0,0);
00985   mEyePlaneR    = fvec4(0,0,1,0);
00986   mObjectPlaneR = fvec4(0,0,1,0);
00987   mEyePlaneQ    = fvec4(0,0,0,1);
00988   mObjectPlaneQ = fvec4(0,0,0,1);
00989   mGenModeS = TGM_DISABLED;
00990   mGenModeT = TGM_DISABLED;
00991   mGenModeR = TGM_DISABLED;
00992   mGenModeQ = TGM_DISABLED;
00993 }
00994 //-----------------------------------------------------------------------------
00995 void TexGen::apply(int index, const Camera*, OpenGLContext*) const
00996 {
00997   VL_CHECK_OGL();
00998 
00999   VL_CHECK(index < VL_MAX_TEXTURE_UNITS)
01000   VL_CHECK(checkTextureSampler("TexGen::apply", index));
01001 
01002   VL_glActiveTexture( GL_TEXTURE0 + index );
01003   // if this fails probably you requested a texture unit index not supported by your OpenGL implementation.
01004   VL_CHECK_OGL();
01005 
01006 #if defined(VL_OPENGL)
01007 
01008   if (genModeS() || genModeT() || genModeR() || genModeQ())
01009   {
01010     glMatrixMode(GL_MODELVIEW);
01011     glPushMatrix();
01012     glLoadIdentity();
01013 
01014     if (genModeS())
01015     {
01016       glEnable(GL_TEXTURE_GEN_S);
01017       glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, genModeS());
01018       // Note: these are not supported by OpenGL ES
01019       if (genModeS() == TGM_OBJECT_LINEAR) glTexGenfv(GL_S, GL_OBJECT_PLANE, objectPlaneS().ptr());
01020       if (genModeS() == TGM_EYE_LINEAR)    glTexGenfv(GL_S, GL_EYE_PLANE,       eyePlaneS().ptr());
01021     }
01022 
01023     VL_CHECK_OGL();
01024 
01025     if (genModeT())
01026     {
01027       glEnable(GL_TEXTURE_GEN_T);
01028       glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, genModeT());
01029       // Note: these are not supported by OpenGL ES
01030       if (genModeT() == TGM_OBJECT_LINEAR) glTexGenfv(GL_T, GL_OBJECT_PLANE, objectPlaneT().ptr());
01031       if (genModeT() == TGM_EYE_LINEAR)    glTexGenfv(GL_T, GL_EYE_PLANE,       eyePlaneT().ptr());
01032     }
01033 
01034     VL_CHECK_OGL();
01035 
01036     if (genModeR())
01037     {
01038       glEnable(GL_TEXTURE_GEN_R);
01039       glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, genModeR());
01040       // Note: these are not supported by OpenGL ES
01041       if (genModeR() == TGM_OBJECT_LINEAR) glTexGenfv(GL_R, GL_OBJECT_PLANE, objectPlaneR().ptr());
01042       if (genModeR() == TGM_EYE_LINEAR)    glTexGenfv(GL_R, GL_EYE_PLANE,       eyePlaneR().ptr());
01043     }
01044 
01045     VL_CHECK_OGL();
01046 
01047     if (genModeQ())
01048     {
01049       glEnable(GL_TEXTURE_GEN_Q);
01050       glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, genModeQ());
01051       // Note: these are not supported by OpenGL ES
01052       if (genModeQ() == TGM_OBJECT_LINEAR) glTexGenfv(GL_Q, GL_OBJECT_PLANE, objectPlaneQ().ptr());
01053       if (genModeQ() == TGM_EYE_LINEAR)    glTexGenfv(GL_Q, GL_EYE_PLANE,    eyePlaneQ().ptr());
01054     }
01055 
01056     glPopMatrix();
01057   }
01058 
01059   // these needs to be done here to apply a TexGen which has all components disabled
01060   // and to finish up the TexGen which mixed enabled/disabled components.
01061 
01062   VL_CHECK_OGL();
01063 
01064   if (!genModeS())
01065     glDisable(GL_TEXTURE_GEN_S);
01066   
01067   if (!genModeT())
01068     glDisable(GL_TEXTURE_GEN_T);
01069   
01070   if (!genModeR())
01071     glDisable(GL_TEXTURE_GEN_R);
01072   
01073   if (!genModeQ())
01074     glDisable(GL_TEXTURE_GEN_Q);
01075 
01076 #elif defined(VL_OPENGL_ES1)
01077 
01078   if ( genModeS() != TGM_DISABLED && genModeS() != TGM_REFLECTION_MAP && genModeS() != TGM_NORMAL_MAP )
01079   {
01080     Log::bug("OpenGL ES does not support GL_SPHERE_MAP, GL_EYE_LINEAR or GL_OBJECT_LINEAR texture coordinate generation!\n"); VL_TRAP();
01081     return;
01082   }
01083 
01084   if ( genModeS() != genModeT() || genModeT() != genModeR() )
01085   {
01086     Log::bug("OpenGL ES requires the same texture coordinate generation mode for S, T and R!\n"); VL_TRAP();
01087     return;
01088   }
01089 
01090   if(!Has_GL_OES_texture_cube_map)
01091   {
01092     Log::bug("Use of vl::TexGen under OpenGL ES requires GL_OES_texture_cube_map extension!\n"); VL_TRAP();
01093     return;
01094   }
01095 
01096   if (genModeS() && genModeT() && genModeR())
01097   {
01098     glMatrixMode(GL_MODELVIEW); VL_CHECK_OGL();
01099     glPushMatrix(); VL_CHECK_OGL();
01100     glLoadIdentity(); VL_CHECK_OGL(); 
01101 
01102     glEnable(GL_TEXTURE_GEN_STR_OES); VL_CHECK_OGL();
01103     glTexGeni( GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, genModeS() ); VL_CHECK_OGL();
01104 
01105     glPopMatrix(); VL_CHECK_OGL();
01106   }
01107   else    
01108   {
01109     glTexGeni( GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_OES ); VL_CHECK_OGL();
01110     glEnable(GL_TEXTURE_GEN_STR_OES); VL_CHECK_OGL();
01111     glDisable(GL_TEXTURE_GEN_STR_OES); VL_CHECK_OGL();
01112   }
01113 
01114 #endif
01115 }
01116 //-----------------------------------------------------------------------------
01117 // TextureMatrix
01118 //-----------------------------------------------------------------------------
01119 void TextureMatrix::apply(int index, const Camera* camera, OpenGLContext*) const
01120 {
01121   VL_CHECK_OGL();
01122   VL_CHECK(index < VL_MAX_TEXTURE_UNITS);
01123   VL_CHECK(checkTextureSampler("TextureMatrix::apply",index));
01124 
01125   VL_glActiveTexture( GL_TEXTURE0 + index );
01126   // if this fails probably you requested a texture unit index not supported by your OpenGL implementation.
01127   VL_CHECK_OGL();
01128   glMatrixMode(GL_TEXTURE);
01129   if (useCameraRotationInverse())
01130     VL_glLoadMatrix( ((mat4)matrix()*camera->modelingMatrix().as3x3()).ptr() );
01131   else
01132     VL_glLoadMatrix( ((mat4)matrix()).ptr() );
01133 }
01134 //-----------------------------------------------------------------------------
01135 // TextureSampler
01136 //-----------------------------------------------------------------------------
01137 bool TextureSampler::hasTexture() const 
01138 { 
01139   return mTexture && mTexture->handle(); 
01140 }
01141 //------------------------------------------------------------------------------
01142 void TextureSampler::apply(int index, const Camera*, OpenGLContext* ctx) const
01143 {
01144   VL_CHECK_OGL();
01145   VL_CHECK(index < VL_MAX_TEXTURE_UNITS)
01146   VL_CHECK(checkTextureSampler("TextureSampler::apply",index));
01147 
01148   // activate the appropriate texture unit
01149   VL_glActiveTexture( GL_TEXTURE0 + index ); VL_CHECK_OGL()
01150 
01151   // disable and unbind previous active texture target on this texture unit.
01152   vl::ETextureDimension prev_tex_target = ctx->texUnitBinding( index );
01153   if (prev_tex_target)
01154   {
01155     // this is not strictly necessary, it also avoids interaction witht FBOs etc.
01156     glBindTexture( prev_tex_target, 0 ); VL_CHECK_OGL()
01157 
01158     /* GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY are not supported by the OpenGL fixed function pipeline */
01159     if (Has_Fixed_Function_Pipeline)
01160     {
01161       switch(prev_tex_target)
01162       {
01163         case TD_TEXTURE_1D_ARRAY:
01164         case TD_TEXTURE_2D_ARRAY:
01165         case TD_TEXTURE_2D_MULTISAMPLE:
01166         case TD_TEXTURE_2D_MULTISAMPLE_ARRAY:
01167         case TD_TEXTURE_BUFFER:
01168           break;
01169         default:
01170           glDisable( prev_tex_target ); VL_CHECK_OGL()
01171       }
01172     }
01173   }
01174 
01175   if (hasTexture())
01176   {
01177     // bind the texture
01178     glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
01179 
01180     // if we request mipmapped filtering then we must have a mip-mapped texture.
01181 #if !defined(NDEBUG) && defined(VL_OPENGL) // glGetTexLevelParameter* is not supported under OpenGL ES
01182     if ( texture()->dimension() != TD_TEXTURE_BUFFER && (texture()->width() > 1 || texture()->height() > 1 || texture()->depth() > 1) )
01183     {
01184       GLint width = 0;
01185       ETextureDimension tex_target = texture()->dimension() == vl::TD_TEXTURE_CUBE_MAP ? (ETextureDimension)GL_TEXTURE_CUBE_MAP_POSITIVE_X : texture()->dimension();
01186       glGetTexLevelParameteriv( tex_target, 1, GL_TEXTURE_WIDTH, &width );
01187       VL_CHECK_OGL()
01188       if ( !width )
01189       {
01190         switch(texture()->getTexParameter()->minFilter())
01191         {
01192           case TPF_LINEAR_MIPMAP_LINEAR:
01193           case TPF_LINEAR_MIPMAP_NEAREST:
01194           case TPF_NEAREST_MIPMAP_LINEAR:
01195           case TPF_NEAREST_MIPMAP_NEAREST:
01196           {
01197             Log::bug( vl::Say("TextureSampler::apply() error: requested mipmapping texture filtering on a Texture with no mipmaps! (%s)\n") << texture()->objectName() );
01198             VL_TRAP()
01199             break;
01200           }
01201 
01202           default:
01203             break;
01204         }
01205       }
01206     }
01207 #endif
01208 
01209     // enable the texture
01210     if (Has_Fixed_Function_Pipeline)
01211     {
01212       /* GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY are not supported by the OpenGL fixed function pipeline */
01213       switch(texture()->dimension())
01214       {
01215         case TD_TEXTURE_1D_ARRAY:
01216         case TD_TEXTURE_2D_ARRAY:
01217         case TD_TEXTURE_2D_MULTISAMPLE:
01218         case TD_TEXTURE_2D_MULTISAMPLE_ARRAY:
01219         case TD_TEXTURE_BUFFER:
01220           break;
01221         default:
01222           glEnable( texture()->dimension() ); VL_CHECK_OGL()
01223       }
01224     }
01225 
01226     // track currently used texture target
01227     ctx->setTexUnitBinding( index, texture()->dimension() );
01228 
01229     // texture parameters
01230     // TexParameter overridden by the TextureSampler
01231     if ( getTexParameter() )
01232     {
01233       if( texture()->getTexParameterOverride() != getTexParameter() )
01234       {
01235         // schedule restore of original TexParameter once no override is used.
01236         texture()->getTexParameter()->setDirty(true);
01237         // install the TexParameter override and apply it
01238         texture()->mTexParameterOverride = getTexParameter();
01239         getTexParameter()->apply( texture()->dimension(), ctx );
01240       }
01241     }
01242     else
01243     // Regular TexParameter
01244     if ( texture()->getTexParameter()->dirty() )
01245       texture()->getTexParameter()->apply( texture()->dimension(), ctx );
01246   }
01247 }
01248 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:40.
Permission is granted to use this page to write and publish articles regarding Visualization Library.