00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00044
00045 Shader::Shader()
00046 {
00047 VL_DEBUG_SET_OBJECT_NAME()
00048 mLastUpdateTime = 0;
00049
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
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
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
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
00250
00251 void CullFace::apply(int, const Camera*, OpenGLContext*) const
00252 {
00253 glCullFace(mFaceMode); VL_CHECK_OGL()
00254 }
00255
00256
00257
00258 void FrontFace::apply(int, const Camera*, OpenGLContext*) const
00259 {
00260 glFrontFace(mFrontFace); VL_CHECK_OGL()
00261 }
00262
00263
00264
00265 void DepthFunc::apply(int, const Camera*, OpenGLContext*) const
00266 {
00267 glDepthFunc(mDepthFunc); VL_CHECK_OGL()
00268 }
00269
00270
00271
00272 void DepthMask::apply(int, const Camera*, OpenGLContext*) const
00273 {
00274 glDepthMask(mDepthMask?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00275 }
00276
00277
00278
00279 void PolygonMode::apply(int, const Camera*, OpenGLContext*) const
00280 {
00281
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
00294
00295 void ShadeModel::apply(int, const Camera*, OpenGLContext*) const
00296 {
00297 glShadeModel(mShadeModel); VL_CHECK_OGL()
00298 }
00299
00300
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()
00311 }
00312 }
00313
00314
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
00325
00326 void AlphaFunc::apply(int, const Camera*, OpenGLContext*) const
00327 {
00328 glAlphaFunc(mAlphaFunc, mRefValue); VL_CHECK_OGL()
00329 }
00330
00331
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
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
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
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
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
00552
00553 void PolygonOffset::apply(int, const Camera*, OpenGLContext*) const
00554 {
00555 glPolygonOffset(mFactor, mUnits); VL_CHECK_OGL()
00556 }
00557
00558
00559
00560 void LogicOp::apply(int, const Camera*, OpenGLContext*) const
00561 {
00562 glLogicOp(mLogicOp); VL_CHECK_OGL()
00563 }
00564
00565
00566
00567 void DepthRange::apply(int, const Camera*, OpenGLContext*) const
00568 {
00569 glDepthRange(mZNear, mZFar); VL_CHECK_OGL()
00570 }
00571
00572
00573
00574 void LineWidth::apply(int, const Camera*, OpenGLContext*) const
00575 {
00576 glLineWidth(mLineWidth); VL_CHECK_OGL()
00577 }
00578
00579
00580
00581 void PointSize::apply(int, const Camera*, OpenGLContext*) const
00582 {
00583 glPointSize(mPointSize); VL_CHECK_OGL()
00584 }
00585
00586
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
00611
00612 void LineStipple::apply(int, const Camera*, OpenGLContext*) const
00613 {
00614 glLineStipple(mFactor, mPattern); VL_CHECK_OGL()
00615 }
00616
00617
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
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
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
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
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
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
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
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
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
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
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
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
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();
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();
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
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
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
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
00927 if (mode() == TEM_BLEND)
00928 {
00929 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color().ptr()); VL_CHECK_OGL()
00930 }
00931
00932
00933
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
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
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
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
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
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
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
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
01060
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
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
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
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
01149 VL_glActiveTexture( GL_TEXTURE0 + index ); VL_CHECK_OGL()
01150
01151
01152 vl::ETextureDimension prev_tex_target = ctx->texUnitBinding( index );
01153 if (prev_tex_target)
01154 {
01155
01156 glBindTexture( prev_tex_target, 0 ); VL_CHECK_OGL()
01157
01158
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
01178 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
01179
01180
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
01210 if (Has_Fixed_Function_Pipeline)
01211 {
01212
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
01227 ctx->setTexUnitBinding( index, texture()->dimension() );
01228
01229
01230
01231 if ( getTexParameter() )
01232 {
01233 if( texture()->getTexParameterOverride() != getTexParameter() )
01234 {
01235
01236 texture()->getTexParameter()->setDirty(true);
01237
01238 texture()->mTexParameterOverride = getTexParameter();
01239 getTexParameter()->apply( texture()->dimension(), ctx );
01240 }
01241 }
01242 else
01243
01244 if ( texture()->getTexParameter()->dirty() )
01245 texture()->getTexParameter()->apply( texture()->dimension(), ctx );
01246 }
01247 }
01248