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 dynamic_cast<const GLSLProgram*>( getRenderStateSet()->renderState( RS_GLSLProgram ) );
00062 }
00063
00064 GLSLProgram* Shader::getGLSLProgram()
00065 {
00066 return dynamic_cast<GLSLProgram*>( getRenderStateSet()->renderState( RS_GLSLProgram ) );
00067 }
00068
00069
00070
00071 #define GET_OR_CREATE(RS)\
00072 RS* rs = dynamic_cast<RS*>( gocRenderStateSet()->renderState( RS_##RS ) ); \
00073 if ( rs == NULL ) \
00074 { \
00075 rs = new RS; \
00076 gocRenderStateSet()->setRenderState( rs ); \
00077 } \
00078 return rs;
00079
00080 #define GET_OR_CREATE_IDX(RS, index)\
00081 RS* rs = dynamic_cast<RS*>( gocRenderStateSet()->renderState( (ERenderState)(RS_##RS##0 + index) ) ); \
00082 if ( rs == NULL ) \
00083 { \
00084 rs = new RS(index); \
00085 gocRenderStateSet()->setRenderState( rs ); \
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 ColorMask* Shader::gocColorMask() { GET_OR_CREATE(ColorMask) }
00104
00105 PolygonMode* Shader::gocPolygonMode() { GET_OR_CREATE(PolygonMode) }
00106
00107 ShadeModel* Shader::gocShadeModel() { GET_OR_CREATE(ShadeModel) }
00108
00109 BlendEquation* Shader::gocBlendEquation() { GET_OR_CREATE(BlendEquation) }
00110
00111 AlphaFunc* Shader::gocAlphaFunc() { GET_OR_CREATE(AlphaFunc) }
00112
00113 Material* Shader::gocMaterial() { GET_OR_CREATE(Material) }
00114
00115 LightModel* Shader::gocLightModel() { GET_OR_CREATE(LightModel) }
00116
00117 Fog* Shader::gocFog() { GET_OR_CREATE(Fog) }
00118
00119 PolygonOffset* Shader::gocPolygonOffset() { GET_OR_CREATE(PolygonOffset) }
00120
00121 LogicOp* Shader::gocLogicOp() { GET_OR_CREATE(LogicOp) }
00122
00123 DepthRange* Shader::gocDepthRange() { GET_OR_CREATE(DepthRange) }
00124
00125 LineWidth* Shader::gocLineWidth() { GET_OR_CREATE(LineWidth) }
00126
00127 PointSize* Shader::gocPointSize() { GET_OR_CREATE(PointSize) }
00128
00129 LineStipple* Shader::gocLineStipple() { GET_OR_CREATE(LineStipple) }
00130
00131 PolygonStipple* Shader::gocPolygonStipple() { GET_OR_CREATE(PolygonStipple) }
00132
00133 PointParameter* Shader::gocPointParameter() { GET_OR_CREATE(PointParameter) }
00134
00135 StencilFunc* Shader::gocStencilFunc() { GET_OR_CREATE(StencilFunc) }
00136
00137 StencilOp* Shader::gocStencilOp() { GET_OR_CREATE(StencilOp) }
00138
00139 StencilMask* Shader::gocStencilMask() { GET_OR_CREATE(StencilMask) }
00140
00141 BlendColor* Shader::gocBlendColor() { GET_OR_CREATE(BlendColor) }
00142
00143 BlendFunc* Shader::gocBlendFunc() { GET_OR_CREATE(BlendFunc) }
00144
00145 SampleCoverage* Shader::gocSampleCoverage() { GET_OR_CREATE(SampleCoverage) }
00146
00147 Light* Shader::gocLight(int light_index) { GET_OR_CREATE_IDX(Light, light_index) }
00148
00149 const Light* Shader::getLight(int light_index) const { return dynamic_cast<const Light*>( getRenderStateSet()->renderState( (ERenderState)(RS_Light0+light_index) ) ); }
00150
00151 Light* Shader::getLight(int light_index) { return dynamic_cast<Light*>( getRenderStateSet()->renderState( (ERenderState)(RS_Light0+light_index) ) ); }
00152
00153 ClipPlane* Shader::gocClipPlane(int plane_index) { GET_OR_CREATE_IDX(ClipPlane, plane_index) }
00154
00155 const ClipPlane* Shader::getClipPlane(int plane_index) const { return dynamic_cast<const ClipPlane*>( getRenderStateSet()->renderState( (ERenderState)(RS_ClipPlane0+plane_index) ) ); }
00156
00157 ClipPlane* Shader::getClipPlane(int plane_index) { return dynamic_cast<ClipPlane*>( getRenderStateSet()->renderState( (ERenderState)(RS_ClipPlane0+plane_index) ) ); }
00158
00159 TextureUnit* Shader::gocTextureUnit(int unit_index) { GET_OR_CREATE_IDX(TextureUnit, unit_index) }
00160
00161 TexGen* Shader::gocTexGen(int unit_index) { GET_OR_CREATE_IDX(TexGen, unit_index) }
00162
00163 TexEnv* Shader::gocTexEnv(int unit_index) { GET_OR_CREATE_IDX(TexEnv, unit_index) }
00164
00165 TextureMatrix* Shader::gocTextureMatrix(int unit_index) { GET_OR_CREATE_IDX(TextureMatrix, unit_index) }
00166
00167
00168
00169 void PixelTransfer::apply(const Camera*, OpenGLContext*) const
00170 {
00171 glPixelTransferi(GL_MAP_COLOR, mapColor() ? GL_TRUE : GL_FALSE);
00172 glPixelTransferi(GL_MAP_STENCIL, mapStencil() ? GL_TRUE : GL_FALSE);
00173 glPixelTransferi(GL_INDEX_SHIFT, indexShift() );
00174 glPixelTransferi(GL_INDEX_OFFSET, indexOffset() );
00175 glPixelTransferf(GL_RED_SCALE, redScale() );
00176 glPixelTransferf(GL_GREEN_SCALE, greenScale() );
00177 glPixelTransferf(GL_BLUE_SCALE, blueScale() );
00178 glPixelTransferf(GL_ALPHA_SCALE, alphaScale() );
00179 glPixelTransferf(GL_DEPTH_SCALE, depthScale() );
00180 glPixelTransferf(GL_RED_BIAS, redBias() );
00181 glPixelTransferf(GL_GREEN_BIAS, greenBias() );
00182 glPixelTransferf(GL_BLUE_BIAS, blueBias() );
00183 glPixelTransferf(GL_ALPHA_BIAS, alphaBias() );
00184 glPixelTransferf(GL_DEPTH_BIAS, depthBias() );
00185 VL_CHECK_OGL()
00186 if (GLEW_ARB_imaging)
00187 {
00188 glPixelTransferf(GL_POST_COLOR_MATRIX_RED_SCALE, postColorMatrixRedScale() );
00189 glPixelTransferf(GL_POST_COLOR_MATRIX_GREEN_SCALE, postColorMatrixGreenScale() );
00190 glPixelTransferf(GL_POST_COLOR_MATRIX_BLUE_SCALE, postColorMatrixBlueScale() );
00191 glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_SCALE, postColorMatrixAlphaScale() );
00192 glPixelTransferf(GL_POST_COLOR_MATRIX_RED_BIAS, postColorMatrixRedBias() );
00193 glPixelTransferf(GL_POST_COLOR_MATRIX_GREEN_BIAS, postColorMatrixGreenBias() );
00194 glPixelTransferf(GL_POST_COLOR_MATRIX_BLUE_BIAS, postColorMatrixBlueBias() );
00195 glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_BIAS, postColorMatrixAlphaBias() );
00196 glPixelTransferf(GL_POST_CONVOLUTION_RED_SCALE, postConvolutionRedScale() );
00197 glPixelTransferf(GL_POST_CONVOLUTION_GREEN_SCALE, postConvolutionGreenScale() );
00198 glPixelTransferf(GL_POST_CONVOLUTION_BLUE_SCALE, postConvolutionBlueScale() );
00199 glPixelTransferf(GL_POST_CONVOLUTION_ALPHA_SCALE, postConvolutionAlphaScale() );
00200 glPixelTransferf(GL_POST_CONVOLUTION_RED_BIAS, postConvolutionRedBias() );
00201 glPixelTransferf(GL_POST_CONVOLUTION_GREEN_BIAS, postConvolutionGreenBias() );
00202 glPixelTransferf(GL_POST_CONVOLUTION_BLUE_BIAS, postConvolutionBlueBias() );
00203 glPixelTransferf(GL_POST_CONVOLUTION_ALPHA_BIAS, postConvolutionAlphaBias() );
00204 VL_CHECK_OGL()
00205 }
00206 }
00207
00208
00209
00210 void Hint::apply(const Camera*, OpenGLContext* gl) const
00211 {
00212 VL_CHECK_OGL()
00213
00214 if( gl->isCompatible() )
00215 {
00216 glHint( GL_PERSPECTIVE_CORRECTION_HINT, mPerspectiveCorrectionHint ); VL_CHECK_OGL()
00217
00218 glHint( GL_FOG_HINT, mFogHint ); VL_CHECK_OGL()
00219
00220 if (GLEW_SGIS_generate_mipmap || GLEW_VERSION_1_4)
00221 {
00222 glHint( GL_GENERATE_MIPMAP_HINT, mGenerateMipmapHint ); VL_CHECK_OGL()
00223 }
00224 }
00225
00226 glHint( GL_POLYGON_SMOOTH_HINT, mPolygonSmoothHint ); VL_CHECK_OGL()
00227 glHint( GL_LINE_SMOOTH_HINT, mLineSmoothHint ); VL_CHECK_OGL()
00228 glHint( GL_POINT_SMOOTH_HINT, mPointSmoothHint ); VL_CHECK_OGL()
00229
00230 }
00231
00232
00233
00234 void CullFace::apply(const Camera*, OpenGLContext*) const
00235 {
00236 glCullFace(mFaceMode); VL_CHECK_OGL()
00237 }
00238
00239
00240
00241 void FrontFace::apply(const Camera*, OpenGLContext*) const
00242 {
00243 glFrontFace(mFrontFace); VL_CHECK_OGL()
00244 }
00245
00246
00247
00248 void DepthFunc::apply(const Camera*, OpenGLContext*) const
00249 {
00250 glDepthFunc(mDepthFunc); VL_CHECK_OGL()
00251 }
00252
00253
00254
00255 void DepthMask::apply(const Camera*, OpenGLContext*) const
00256 {
00257 glDepthMask(mDepthMask?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00258 }
00259
00260
00261
00262 void PolygonMode::apply(const Camera*, OpenGLContext*) const
00263 {
00264
00265 if ( mFrontFace == mBackFace )
00266 {
00267 glPolygonMode(GL_FRONT_AND_BACK, mFrontFace); VL_CHECK_OGL()
00268 }
00269 else
00270 {
00271 glPolygonMode(GL_FRONT, mFrontFace); VL_CHECK_OGL()
00272 glPolygonMode(GL_BACK, mBackFace); VL_CHECK_OGL()
00273 }
00274 }
00275
00276
00277
00278 void ShadeModel::apply(const Camera*, OpenGLContext*) const
00279 {
00280 glShadeModel(mShadeModel); VL_CHECK_OGL()
00281 }
00282
00283
00284
00285 void BlendFunc::apply(const Camera*, OpenGLContext*) const
00286 {
00287 if (GLEW_VERSION_1_4||GLEW_EXT_blend_func_separate)
00288 { VL_glBlendFuncSeparate(mSrcRGB, mDstRGB, mSrcAlpha, mDstAlpha); VL_CHECK_OGL() }
00289 else
00290 { glBlendFunc(mSrcRGB, mDstRGB); VL_CHECK_OGL() }
00291 }
00292
00293
00294
00295 void BlendEquation::apply(const Camera*, OpenGLContext*) const
00296 {
00297 if (GLEW_VERSION_2_0||GLEW_EXT_blend_equation_separate)
00298 { VL_glBlendEquationSeparate(mModeRGB, mModeAlpha); VL_CHECK_OGL() }
00299 else
00300 { VL_glBlendEquation(mModeRGB); VL_CHECK_OGL() }
00301 }
00302
00303
00304
00305 void AlphaFunc::apply(const Camera*, OpenGLContext*) const
00306 {
00307 glAlphaFunc(mAlphaFunc, mRefValue); VL_CHECK_OGL()
00308 }
00309
00310
00311
00312 Material::Material()
00313 {
00314 VL_DEBUG_SET_OBJECT_NAME()
00315 mFrontAmbient = fvec4(0.2f, 0.2f, 0.2f, 1.0f);
00316 mFrontDiffuse = fvec4(0.8f, 0.8f, 0.8f, 1.0f);
00317 mFrontSpecular = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00318 mFrontEmission = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00319 mFrontShininess = 0;
00320
00321 mBackAmbient = fvec4(0.2f, 0.2f, 0.2f, 1.0f);
00322 mBackDiffuse = fvec4(0.8f, 0.8f, 0.8f, 1.0f);
00323 mBackSpecular = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00324 mBackEmission = fvec4(0.0f, 0.0f, 0.0f, 1.0f);
00325 mBackShininess = 0;
00326
00327 mColorMaterialEnabled = false;
00328 mColorMaterialFace = PF_FRONT_AND_BACK;
00329 mColorMaterial = CM_AMBIENT_AND_DIFFUSE;
00330 }
00331
00332 void Material::setTransparency(float alpha)
00333 {
00334 mFrontAmbient.a() = mBackAmbient.a() = alpha;
00335 mFrontDiffuse.a() = mBackDiffuse.a() = alpha;
00336 mFrontSpecular.a() = mBackSpecular.a() = alpha;
00337 mFrontEmission.a() = mBackEmission.a() = alpha;
00338 }
00339
00340 void Material::setFrontTransparency(float alpha)
00341 {
00342 mFrontAmbient.a() = alpha;
00343 mFrontDiffuse.a() = alpha;
00344 mFrontSpecular.a() = alpha;
00345 mFrontEmission.a() = alpha;
00346 }
00347
00348 void Material::setBackTransparency(float alpha)
00349 {
00350 mBackAmbient.a() = alpha;
00351 mBackDiffuse.a() = alpha;
00352 mBackSpecular.a() = alpha;
00353 mBackEmission.a() = alpha;
00354 }
00355
00356 void Material::setFrontFlatColor(const fvec4& color)
00357 {
00358 mFrontAmbient = 0;
00359 mFrontDiffuse = 0;
00360 mFrontSpecular = 0;
00361 mFrontEmission = color;
00362 mFrontShininess = 0;
00363 setFrontTransparency(color.a());
00364 }
00365
00366 void Material::setBackFlatColor(const fvec4& color)
00367 {
00368 mBackAmbient = 0;
00369 mBackDiffuse = 0;
00370 mBackSpecular = 0;
00371 mBackEmission = color;
00372 mBackShininess = 0;
00373 setBackTransparency(color.a());
00374 }
00375
00376 void Material::setFlatColor(const fvec4& color)
00377 {
00378 setFrontFlatColor(color);
00379 setBackFlatColor(color);
00380 }
00381
00382 void Material::apply(const Camera*, OpenGLContext*) const
00383 {
00384 if (mColorMaterialEnabled)
00385 {
00386 glColorMaterial(colorMaterialFace(), colorMaterial());
00387 glEnable(GL_COLOR_MATERIAL);
00388 }
00389 else
00390 glDisable(GL_COLOR_MATERIAL);
00391
00392 glMaterialfv(GL_FRONT, GL_AMBIENT, mFrontAmbient.ptr());
00393 glMaterialfv(GL_FRONT, GL_DIFFUSE, mFrontDiffuse.ptr());
00394 glMaterialfv(GL_FRONT, GL_SPECULAR, mFrontSpecular.ptr());
00395 glMaterialfv(GL_FRONT, GL_EMISSION, mFrontEmission.ptr());
00396 glMaterialf(GL_FRONT, GL_SHININESS, mFrontShininess);
00397
00398 glMaterialfv(GL_BACK, GL_AMBIENT, mBackAmbient.ptr());
00399 glMaterialfv(GL_BACK, GL_DIFFUSE, mBackDiffuse.ptr());
00400 glMaterialfv(GL_BACK, GL_SPECULAR, mBackSpecular.ptr());
00401 glMaterialfv(GL_BACK, GL_EMISSION, mBackEmission.ptr());
00402 glMaterialf(GL_BACK, GL_SHININESS, mBackShininess);
00403 }
00404
00405
00406
00407 void LightModel::apply(const Camera*, OpenGLContext*) const
00408 {
00409 if (GLEW_VERSION_1_2||GLEW_EXT_separate_specular_color)
00410 { glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, mColorControl); VL_CHECK_OGL() }
00411
00412 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mAmbientColor.ptr()); VL_CHECK_OGL()
00413 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, mLocalViewer?1:0); VL_CHECK_OGL()
00414 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, mTwoSide?1:0); VL_CHECK_OGL()
00415 }
00416
00417
00418
00419 void Fog::apply(const Camera*, OpenGLContext*) const
00420 {
00421 glFogi(GL_FOG_MODE, mMode); VL_CHECK_OGL()
00422 glFogfv(GL_FOG_COLOR, mColor.ptr()); VL_CHECK_OGL()
00423 glFogf(GL_FOG_DENSITY, mDensity); VL_CHECK_OGL()
00424 glFogf(GL_FOG_START, mStart); VL_CHECK_OGL()
00425 glFogf(GL_FOG_END, mEnd); VL_CHECK_OGL()
00426 }
00427
00428
00429
00430 void PolygonOffset::apply(const Camera*, OpenGLContext*) const
00431 {
00432 glPolygonOffset(mFactor, mUnits); VL_CHECK_OGL()
00433 }
00434
00435
00436
00437 void LogicOp::apply(const Camera*, OpenGLContext*) const
00438 {
00439 glLogicOp(mLogicOp); VL_CHECK_OGL()
00440 }
00441
00442
00443
00444 void DepthRange::apply(const Camera*, OpenGLContext*) const
00445 {
00446 glDepthRange(mZNear, mZFar); VL_CHECK_OGL()
00447 }
00448
00449
00450
00451 void LineWidth::apply(const Camera*, OpenGLContext*) const
00452 {
00453 glLineWidth(mLineWidth); VL_CHECK_OGL()
00454 }
00455
00456
00457
00458 void PointSize::apply(const Camera*, OpenGLContext*) const
00459 {
00460 glPointSize(mPointSize); VL_CHECK_OGL()
00461 }
00462
00463
00464
00465 PolygonStipple::PolygonStipple()
00466 {
00467 VL_DEBUG_SET_OBJECT_NAME()
00468 memset(mMask, 0xFF, sizeof(unsigned char)*32*32/8);
00469 }
00470
00471 PolygonStipple::PolygonStipple(const unsigned char* mask)
00472 {
00473 VL_DEBUG_SET_OBJECT_NAME()
00474 set(mask);
00475 }
00476
00477 void PolygonStipple::set(const unsigned char* mask)
00478 {
00479 memcpy(mMask, mask, sizeof(unsigned char)*32*32/8);
00480 }
00481
00482 void PolygonStipple::apply(const Camera*, OpenGLContext*) const
00483 {
00484 glPolygonStipple(mask()); VL_CHECK_OGL()
00485 }
00486
00487
00488
00489 void LineStipple::apply(const Camera*, OpenGLContext*) const
00490 {
00491 glLineStipple(mFactor, mPattern); VL_CHECK_OGL()
00492 }
00493
00494
00495
00496 void PointParameter::apply(const Camera*, OpenGLContext*) const
00497 {
00498 if (GLEW_VERSION_1_4)
00499 {
00500 VL_glPointParameterf(GL_POINT_SIZE_MIN, mSizeMin); VL_CHECK_OGL()
00501 VL_glPointParameterf(GL_POINT_SIZE_MAX, mSizeMax); VL_CHECK_OGL()
00502 VL_glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (const float*)mDistanceAttenuation.ptr()); VL_CHECK_OGL()
00503 }
00504 if (GLEW_VERSION_1_4||GLEW_VERSION_3_0)
00505 {
00506 VL_glPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, mFadeThresholdSize); VL_CHECK_OGL()
00507 }
00508 if (GLEW_VERSION_2_0||GLEW_VERSION_3_0||GLEW_VERSION_4_0)
00509 {
00510 VL_glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, mPointSpriteCoordOrigin); VL_CHECK_OGL()
00511 }
00512 }
00513
00514
00515
00516 void StencilFunc::apply(const Camera*, OpenGLContext*) const
00517 {
00518 if(GLEW_VERSION_2_0)
00519 {
00520 VL_glStencilFuncSeparate(GL_FRONT, mFunction_Front, mRefValue_Front, mMask_Front); VL_CHECK_OGL()
00521 VL_glStencilFuncSeparate(GL_BACK, mFunction_Back, mRefValue_Back, mMask_Back); VL_CHECK_OGL()
00522 }
00523 else
00524 {
00525 glStencilFunc(mFunction_Front, mRefValue_Front, mMask_Front); VL_CHECK_OGL()
00526 }
00527 }
00528
00529
00530
00531 void StencilOp::apply(const Camera*, OpenGLContext*) const
00532 {
00533 if(GLEW_VERSION_2_0)
00534 {
00535 VL_glStencilOpSeparate(GL_FRONT, mSFail_Front, mDpFail_Front, mDpPass_Front); VL_CHECK_OGL()
00536 VL_glStencilOpSeparate(GL_BACK, mSFail_Back, mDpFail_Back, mDpPass_Back); VL_CHECK_OGL()
00537 }
00538 else
00539 {
00540 glStencilOp(mSFail_Front, mDpFail_Front, mDpPass_Front); VL_CHECK_OGL()
00541 }
00542 }
00543
00544
00545
00546 void StencilMask::apply(const Camera*, OpenGLContext*) const
00547 {
00548 if(GLEW_VERSION_2_0)
00549 {
00550 glStencilMaskSeparate(GL_FRONT, mMask_Front); VL_CHECK_OGL()
00551 glStencilMaskSeparate(GL_BACK, mMask_Back); VL_CHECK_OGL()
00552 }
00553 else
00554 {
00555 glStencilMask(mMask_Front); VL_CHECK_OGL()
00556 }
00557 }
00558
00559
00560
00561 void BlendColor::apply(const Camera*, OpenGLContext*) const
00562 {
00563 VL_glBlendColor(mBlendColor.r(), mBlendColor.g(), mBlendColor.b(), mBlendColor.a()); VL_CHECK_OGL()
00564 }
00565
00566
00567
00568 void ColorMask::apply(const Camera*, OpenGLContext*) const
00569 {
00570 glColorMask(mRed?GL_TRUE:GL_FALSE, mGreen?GL_TRUE:GL_FALSE, mBlue?GL_TRUE:GL_FALSE, mAlpha?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00571 }
00572
00573
00574
00575 void SampleCoverage::apply(const Camera*, OpenGLContext*) const
00576 {
00577 VL_glSampleCoverage(mValue, mInvert?GL_TRUE:GL_FALSE); VL_CHECK_OGL()
00578 }
00579
00580
00581
00582 TexParameter::TexParameter()
00583 {
00584 mDirty = true;
00585 setMinFilter(TPF_LINEAR);
00586 setMagFilter(TPF_LINEAR);
00587 setWrapS(TPW_REPEAT);
00588 setWrapT(TPW_REPEAT);
00589 setWrapR(TPW_REPEAT);
00590 setBorderColor(fvec4(0,0,0,0));
00591 setAnisotropy(1.0f);
00592 setGenerateMipmap(false);
00593 setTexCompareFunc(TCF_LEQUAL);
00594 setTexCompareMode(TCM_NONE);
00595 setDepthTextureMode(DTM_LUMINANCE);
00596 }
00597
00598 void TexParameter::setMagFilter(ETexParamFilter magfilter)
00599 {
00600 mDirty = true;
00601
00602 switch(magfilter)
00603 {
00604 case TPF_LINEAR:
00605 case TPF_NEAREST:
00606 {
00607 mMagfilter = magfilter;
00608 break;
00609 }
00610 default:
00611 {
00612 mMagfilter = TPF_LINEAR;
00613 #ifndef NDEBUG
00614 Log::bug("TexParameter::setMagFilter() accepts only the following values: TPF_LINEAR, TPF_NEAREST.\n");
00615 #endif
00616 }
00617 }
00618 }
00619
00620 void TexParameter::apply(ETextureDimension dimension, OpenGLContext* gl) const
00621 {
00622 VL_CHECK_OGL()
00623
00624 #ifndef NDEBUG
00625 if (dimension == TD_TEXTURE_RECTANGLE)
00626 {
00627 bool err = (wrapS() != GL_CLAMP && wrapS() != GL_CLAMP_TO_EDGE && wrapS() != GL_CLAMP_TO_BORDER) |
00628 (wrapT() != GL_CLAMP && wrapT() != GL_CLAMP_TO_EDGE && wrapT() != GL_CLAMP_TO_BORDER) |
00629 (wrapR() != GL_CLAMP && wrapR() != GL_CLAMP_TO_EDGE && wrapR() != GL_CLAMP_TO_BORDER);
00630 if (err)
00631 {
00632 Log::bug("ARB_texture_rectangle extension allows only the following wrapping modes: GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER.\n");
00633 }
00634 }
00635
00636 if (wrapS() == GL_MIRRORED_REPEAT || wrapT() == GL_MIRRORED_REPEAT || wrapR() == GL_MIRRORED_REPEAT)
00637 {
00638 if( !(GLEW_VERSION_1_4 || GLEW_ARB_texture_mirrored_repeat || GLEW_IBM_texture_mirrored_repeat) )
00639 Log::bug("GL_MIRRORED_REPEAT not supported by your OpenGL implementation.\n");
00640 }
00641
00642 if (wrapS() == GL_CLAMP_TO_EDGE || wrapT() == GL_CLAMP_TO_EDGE || wrapR() == GL_CLAMP_TO_EDGE)
00643 {
00644 if( !(GLEW_VERSION_1_2 || GLEW_EXT_texture_edge_clamp || GLEW_SGIS_texture_edge_clamp) )
00645 Log::bug("GL_CLAMP_TO_EDGE not supported by your OpenGL implementation.\n");
00646 }
00647
00648 if (wrapS() == GL_CLAMP_TO_BORDER || wrapT() == GL_CLAMP_TO_BORDER || wrapR() == GL_CLAMP_TO_BORDER)
00649 {
00650 if( !(GLEW_VERSION_1_3 || GLEW_ARB_texture_border_clamp || GLEW_SGIS_texture_border_clamp) )
00651 Log::bug("GL_CLAMP_TO_BORDER not supported by your OpenGL implementation.\n");
00652 }
00653 #endif
00654
00655
00656
00657 if (dimension != TD_TEXTURE_BUFFER && dimension != TD_TEXTURE_2D_MULTISAMPLE && dimension != TD_TEXTURE_2D_MULTISAMPLE_ARRAY)
00658 {
00659 glTexParameterfv(dimension, GL_TEXTURE_BORDER_COLOR, borderColor().ptr()); VL_CHECK_OGL()
00660 glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, minFilter()); VL_CHECK_OGL()
00661 glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, magFilter()); VL_CHECK_OGL()
00662 glTexParameteri(dimension, GL_TEXTURE_WRAP_S, wrapS()); VL_CHECK_OGL()
00663 glTexParameteri(dimension, GL_TEXTURE_WRAP_T, wrapT()); VL_CHECK_OGL()
00664 if (GLEW_VERSION_1_2)
00665 glTexParameteri(dimension, GL_TEXTURE_WRAP_R, wrapR()); VL_CHECK_OGL()
00666
00667 if (GLEW_EXT_texture_filter_anisotropic)
00668 glTexParameterf( dimension, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy() ); VL_CHECK_OGL()
00669
00670 if (gl->isCompatible())
00671 if (GLEW_VERSION_1_4||GLEW_SGIS_generate_mipmap)
00672 if (dimension != TD_TEXTURE_RECTANGLE)
00673 glTexParameteri(dimension, GL_GENERATE_MIPMAP, generateMipmap() ? GL_TRUE : GL_FALSE); VL_CHECK_OGL()
00674
00675 if (GLEW_VERSION_1_4||GLEW_ARB_shadow)
00676 {
00677 glTexParameteri(dimension, GL_TEXTURE_COMPARE_MODE, compareMode() ); VL_CHECK_OGL()
00678 glTexParameteri(dimension, GL_TEXTURE_COMPARE_FUNC, compareFunc() ); VL_CHECK_OGL()
00679 if(gl->isCompatible())
00680 glTexParameteri(dimension, GL_DEPTH_TEXTURE_MODE, depthTextureMode() ); VL_CHECK_OGL()
00681 }
00682 }
00683
00684 mDirty = false;
00685
00686 VL_CHECK_OGL()
00687 }
00688 namespace
00689 {
00690 bool checkTextureUnit(const char* str, int unit)
00691 {
00692 int max_texture = 1, max_tmp = 0;
00693
00694 if (GLEW_VERSION_1_3||GLEW_ARB_multitexture)
00695 {
00696 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tmp); VL_CHECK_OGL();
00697 max_texture = max_tmp > max_texture ? max_tmp : max_texture;
00698 }
00699
00700 if (GLEW_VERSION_2_0)
00701 {
00702 glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_tmp); VL_CHECK_OGL();
00703 max_texture = max_tmp > max_texture ? max_tmp : max_texture;
00704 }
00705
00706 if (GLEW_VERSION_2_0||GLEW_VERSION_3_0||GLEW_VERSION_4_0)
00707 {
00708 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_tmp); VL_CHECK_OGL();
00709 max_texture = max_tmp > max_texture ? max_tmp : max_texture;
00710 }
00711
00712 if (unit > max_texture-1)
00713 {
00714 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 );
00715 return false;
00716 }
00717
00718 return true;
00719 }
00720 }
00721
00722
00723
00724 TexEnv::TexEnv(int texunit)
00725 {
00726 VL_DEBUG_SET_OBJECT_NAME()
00727
00728 mTextureUnit = texunit;
00729 mMode = TEM_MODULATE;
00730 mColor = fvec4(0,0,0,0);
00731
00732
00733 mRGBScale = 1.0f;
00734 mCombineRGB = TEM_REPLACE;
00735 mSource0RGB = TES_TEXTURE;
00736 mSource1RGB = TES_TEXTURE;
00737 mSource2RGB = TES_TEXTURE;
00738 mOperand0RGB = TEO_SRC_COLOR;
00739 mOperand1RGB = TEO_SRC_COLOR;
00740 mOperand2RGB = TEO_SRC_COLOR;
00741
00742 mAlphaScale = 1.0f;
00743 mCombineAlpha = TEM_REPLACE;
00744 mSource0Alpha = TES_TEXTURE;
00745 mSource1Alpha = TES_TEXTURE;
00746 mSource2Alpha = TES_TEXTURE;
00747 mOperand0Alpha = TEO_SRC_ALPHA;
00748 mOperand1Alpha = TEO_SRC_ALPHA;
00749 mOperand2Alpha = TEO_SRC_ALPHA;
00750
00751 mLodBias = 0.0;
00752 mPointSpriteCoordReplace = false;
00753 }
00754
00755 void TexEnv::apply(const Camera*, OpenGLContext*) const
00756 {
00757 VL_CHECK_OGL()
00758 VL_CHECK(textureUnit() < VL_MAX_TEXTURE_UNITS)
00759 VL_CHECK(checkTextureUnit("TexEnv::apply",textureUnit()));
00760
00761 VL_glActiveTexture( GL_TEXTURE0 + textureUnit() );
00762
00763 VL_CHECK_OGL();
00764
00765 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode()); VL_CHECK_OGL()
00766
00767
00768 if (mode() == TEM_BLEND)
00769 {
00770 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color().ptr()); VL_CHECK_OGL()
00771 }
00772
00773
00774
00775 if (mode() == TEM_COMBINE && (GLEW_EXT_texture_env_combine || GLEW_VERSION_1_3))
00776 {
00777 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, rgbScale()); VL_CHECK_OGL()
00778 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB()); VL_CHECK_OGL()
00779 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, source0RGB()); VL_CHECK_OGL()
00780 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, source1RGB()); VL_CHECK_OGL()
00781 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, operand0RGB()); VL_CHECK_OGL()
00782 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, operand1RGB()); VL_CHECK_OGL()
00783 if (combineRGB() == TEM_INTERPOLATE)
00784 {
00785 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, source2RGB()); VL_CHECK_OGL()
00786 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, operand2RGB()); VL_CHECK_OGL()
00787 }
00788
00789 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, alphaScale()); VL_CHECK_OGL()
00790 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha()); VL_CHECK_OGL()
00791 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, source0Alpha()); VL_CHECK_OGL()
00792 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, source1Alpha()); VL_CHECK_OGL()
00793 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, operand0Alpha()); VL_CHECK_OGL()
00794 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, operand1Alpha()); VL_CHECK_OGL()
00795 if (combineAlpha() == TEM_INTERPOLATE)
00796 {
00797 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, source2Alpha()); VL_CHECK_OGL()
00798 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, operand2Alpha()); VL_CHECK_OGL()
00799 }
00800 }
00801
00802
00803 if (GLEW_VERSION_2_0||GLEW_ARB_point_sprite)
00804 {
00805 glTexEnvi( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, mPointSpriteCoordReplace ? GL_TRUE : GL_FALSE ); VL_CHECK_OGL()
00806 }
00807
00808 if (GLEW_VERSION_1_4||GLEW_EXT_texture_lod_bias)
00809 {
00810 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, mLodBias); VL_CHECK_OGL()
00811 }
00812 }
00813
00814
00815
00819 TexGen::TexGen(int texunit)
00820 {
00821 VL_DEBUG_SET_OBJECT_NAME()
00822 mTextureUnit = texunit;
00823 mEyePlaneS = fvec4(1,0,0,0);
00824 mObjectPlaneS = fvec4(1,0,0,0);
00825 mEyePlaneT = fvec4(0,1,0,0);
00826 mObjectPlaneT = fvec4(0,1,0,0);
00827 mEyePlaneR = fvec4(0,0,1,0);
00828 mObjectPlaneR = fvec4(0,0,1,0);
00829 mEyePlaneQ = fvec4(0,0,0,1);
00830 mObjectPlaneQ = fvec4(0,0,0,1);
00831 mGenModeS = TGM_DISABLED;
00832 mGenModeT = TGM_DISABLED;
00833 mGenModeR = TGM_DISABLED;
00834 mGenModeQ = TGM_DISABLED;
00835 }
00836
00837 void TexGen::apply(const Camera*, OpenGLContext*) const
00838 {
00839 VL_CHECK_OGL();
00840
00841 VL_CHECK(textureUnit() < VL_MAX_TEXTURE_UNITS)
00842 VL_CHECK(checkTextureUnit("TexGen::apply",textureUnit()));
00843
00844 VL_glActiveTexture( GL_TEXTURE0 + textureUnit() );
00845
00846 VL_CHECK_OGL();
00847
00848 if (genModeS() || genModeT() || genModeR() || genModeQ())
00849 {
00850 glMatrixMode(GL_MODELVIEW);
00851 glPushMatrix();
00852 glLoadIdentity();
00853
00854 VL_CHECK_OGL();
00855
00856 if (genModeS())
00857 {
00858 glEnable(GL_TEXTURE_GEN_S);
00859 glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, genModeS());
00860 if (genModeS() == TGM_OBJECT_LINEAR) glTexGenfv(GL_S, GL_OBJECT_PLANE, objectPlaneS().ptr());
00861 if (genModeS() == TGM_EYE_LINEAR) glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS().ptr());
00862 }
00863
00864 VL_CHECK_OGL();
00865
00866 if (genModeT())
00867 {
00868 glEnable(GL_TEXTURE_GEN_T);
00869 glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, genModeT());
00870 if (genModeT() == TGM_OBJECT_LINEAR) glTexGenfv(GL_T, GL_OBJECT_PLANE, objectPlaneT().ptr());
00871 if (genModeT() == TGM_EYE_LINEAR) glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT().ptr());
00872 }
00873
00874 VL_CHECK_OGL();
00875
00876 if (genModeR())
00877 {
00878 glEnable(GL_TEXTURE_GEN_R);
00879 glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, genModeR());
00880 if (genModeR() == TGM_OBJECT_LINEAR) glTexGenfv(GL_R, GL_OBJECT_PLANE, objectPlaneR().ptr());
00881 if (genModeR() == TGM_EYE_LINEAR) glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR().ptr());
00882 }
00883
00884 VL_CHECK_OGL();
00885
00886 if (genModeQ())
00887 {
00888 glEnable(GL_TEXTURE_GEN_Q);
00889 glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, genModeQ());
00890 if (genModeQ() == TGM_OBJECT_LINEAR) glTexGenfv(GL_Q, GL_OBJECT_PLANE, objectPlaneQ().ptr());
00891 if (genModeQ() == TGM_EYE_LINEAR) glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ().ptr());
00892 }
00893
00894 glPopMatrix();
00895 }
00896
00897
00898
00899
00900 if (!genModeS())
00901 glDisable(GL_TEXTURE_GEN_S);
00902
00903 if (!genModeT())
00904 glDisable(GL_TEXTURE_GEN_T);
00905
00906 if (!genModeR())
00907 glDisable(GL_TEXTURE_GEN_R);
00908
00909 if (!genModeQ())
00910 glDisable(GL_TEXTURE_GEN_Q);
00911
00912 VL_CHECK_OGL();
00913 }
00914
00915
00916
00917 void TextureMatrix::apply(const Camera* camera, OpenGLContext*) const
00918 {
00919 VL_CHECK_OGL();
00920 VL_CHECK(textureUnit() < VL_MAX_TEXTURE_UNITS);
00921 VL_CHECK(checkTextureUnit("TextureMatrix::apply",textureUnit()));
00922
00923 VL_glActiveTexture( GL_TEXTURE0 + textureUnit() );
00924
00925 VL_CHECK_OGL();
00926 glMatrixMode(GL_TEXTURE);
00927 if (useCameraRotationInverse())
00928 VL_glLoadMatrix( (matrix()*camera->inverseViewMatrix().as3x3()).ptr() );
00929 else
00930 VL_glLoadMatrix( matrix().ptr() );
00931 }
00932
00933
00934
00935 bool TextureUnit::hasTexture() const
00936 {
00937 return mTexture && mTexture->handle();
00938 }
00939
00940 void TextureUnit::apply(const Camera* camera, OpenGLContext* ctx) const
00941 {
00942 VL_CHECK_OGL();
00943 VL_CHECK(textureUnit() < VL_MAX_TEXTURE_UNITS)
00944 VL_CHECK(checkTextureUnit("TextureUnit::apply",textureUnit()));
00945
00946
00947 VL_glActiveTexture( GL_TEXTURE0 + textureUnit() ); VL_CHECK_OGL()
00948
00949
00950 vl::ETextureDimension prev_tex_target = ctx->texUnitBinding( textureUnit() );
00951 if (prev_tex_target)
00952 {
00953
00954 glBindTexture( prev_tex_target, 0 ); VL_CHECK_OGL()
00955
00956
00957 if (ctx->isCompatible())
00958 {
00959 switch(prev_tex_target)
00960 {
00961 case TD_TEXTURE_1D_ARRAY:
00962 case TD_TEXTURE_2D_ARRAY:
00963 case TD_TEXTURE_2D_MULTISAMPLE:
00964 case TD_TEXTURE_2D_MULTISAMPLE_ARRAY:
00965 case TD_TEXTURE_BUFFER:
00966 break;
00967 default:
00968 glDisable( prev_tex_target ); VL_CHECK_OGL()
00969 }
00970 }
00971 }
00972
00973 if (camera)
00974 {
00975 if( !hasTexture() )
00976 {
00977 Log::bug( Say("TextureUnit::apply() error: null texture! (%s) \n") << texture()->objectName() );
00978 VL_TRAP();
00979 return;
00980 }
00981
00982
00983 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00984
00985
00986 #ifndef NDEBUG
00987 if (texture()->dimension() != TD_TEXTURE_BUFFER)
00988 {
00989 GLint width = 0;
00990 int tex_target = texture()->dimension() == vl::TD_TEXTURE_CUBE_MAP ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texture()->dimension();
00991 glGetTexLevelParameteriv( tex_target, 1, GL_TEXTURE_WIDTH, &width );
00992 VL_CHECK_OGL()
00993 if ( !width )
00994 {
00995 switch(texture()->getTexParameter()->minFilter())
00996 {
00997 case TPF_LINEAR_MIPMAP_LINEAR:
00998 case TPF_LINEAR_MIPMAP_NEAREST:
00999 case TPF_NEAREST_MIPMAP_LINEAR:
01000 case TPF_NEAREST_MIPMAP_NEAREST:
01001 {
01002 Log::bug( vl::Say("TextureUnit::apply() error: requested mipmapping texture filtering on a Texture with no mipmaps! (%s)\n") << texture()->objectName() );
01003 VL_TRAP()
01004 break;
01005 }
01006
01007 default:
01008 break;
01009 }
01010 }
01011 }
01012 #endif
01013
01014
01015 if (ctx->isCompatible())
01016 {
01017
01018 switch(texture()->dimension())
01019 {
01020 case TD_TEXTURE_1D_ARRAY:
01021 case TD_TEXTURE_2D_ARRAY:
01022 case TD_TEXTURE_2D_MULTISAMPLE:
01023 case TD_TEXTURE_2D_MULTISAMPLE_ARRAY:
01024 case TD_TEXTURE_BUFFER:
01025 break;
01026 default:
01027 glEnable( texture()->dimension() ); VL_CHECK_OGL()
01028 }
01029 }
01030
01031
01032 ctx->setTexUnitBinding( textureUnit(), texture()->dimension() );
01033
01034
01035 if ( texture()->getTexParameter()->dirty() )
01036 texture()->getTexParameter()->apply( texture()->dimension(), ctx );
01037 }
01038 }
01039