diff --git a/include/osg/TexEnv b/include/osg/TexEnv index b94dc4bc2..cbe65a9c1 100644 --- a/include/osg/TexEnv +++ b/include/osg/TexEnv @@ -47,7 +47,8 @@ class SG_EXPORT TexEnv : public StateAttribute DECAL = GL_DECAL, MODULATE = GL_MODULATE, BLEND = GL_BLEND, - REPLACE = GL_REPLACE + REPLACE = GL_REPLACE, + ADD = GL_ADD }; void setMode( const Mode mode ) { _mode = mode; } diff --git a/include/osg/TexEnvCombine b/include/osg/TexEnvCombine index 5f2cb738b..2278fc337 100644 --- a/include/osg/TexEnvCombine +++ b/include/osg/TexEnvCombine @@ -37,6 +37,10 @@ #define GL_PREVIOUS_ARB 0x8578 #endif +#ifndef GL_TEXTURE0 +#define GL_TEXTURE0 0x84C0 +#endif + namespace osg { /** TexEnvCombine - encapsulates the OpenGL glTexEnvCombine (texture environment) state.*/ @@ -49,6 +53,7 @@ class SG_EXPORT TexEnvCombine : public StateAttribute /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ TexEnvCombine(const TexEnvCombine& texenv,const CopyOp& copyop=CopyOp::SHALLOW_COPY): StateAttribute(texenv,copyop), + _needsTexEnvCrossbar(texenv._needsTexEnvCrossbar), _combine_RGB(texenv._combine_RGB), _combine_Alpha(texenv._combine_Alpha), _source0_RGB(texenv._source0_RGB), @@ -81,6 +86,7 @@ class SG_EXPORT TexEnvCombine : public StateAttribute COMPARE_StateAttribute_Types(TexEnvCombine,sa) // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_needsTexEnvCrossbar) COMPARE_StateAttribute_Parameter(_combine_RGB) COMPARE_StateAttribute_Parameter(_combine_Alpha) COMPARE_StateAttribute_Parameter(_source0_RGB) @@ -121,19 +127,27 @@ class SG_EXPORT TexEnvCombine : public StateAttribute enum SourceParam { - TEXTURE = GL_TEXTURE, CONSTANT = GL_CONSTANT_ARB, PRIMARY_COLOR = GL_PRIMARY_COLOR_ARB, - PREVIOUS = GL_PREVIOUS_ARB + PREVIOUS = GL_PREVIOUS_ARB, + TEXTURE = GL_TEXTURE, + TEXTURE_0 = GL_TEXTURE0, + TEXTURE_1 = GL_TEXTURE0+1, + TEXTURE_2 = GL_TEXTURE0+2, + TEXTURE_3 = GL_TEXTURE0+3, + TEXTURE_4 = GL_TEXTURE0+4, + TEXTURE_5 = GL_TEXTURE0+5, + TEXTURE_6 = GL_TEXTURE0+6, + TEXTURE_7 = GL_TEXTURE0+7 }; - void setSource0_RGB(GLint sp) { _source0_RGB = sp; } - void setSource1_RGB(GLint sp) { _source1_RGB = sp; } - void setSource2_RGB(GLint sp) { _source2_RGB = sp; } + void setSource0_RGB(GLint sp) { _source0_RGB = sp; computeNeedoForTexEnvCombiners(); } + void setSource1_RGB(GLint sp) { _source1_RGB = sp; computeNeedoForTexEnvCombiners(); } + void setSource2_RGB(GLint sp) { _source2_RGB = sp; computeNeedoForTexEnvCombiners(); } - void setSource0_Alpha(GLint sp) { _source0_Alpha = sp; } - void setSource1_Alpha(GLint sp) { _source1_Alpha = sp; } - void setSource2_Alpha(GLint sp) { _source2_Alpha = sp; } + void setSource0_Alpha(GLint sp) { _source0_Alpha = sp; computeNeedoForTexEnvCombiners(); } + void setSource1_Alpha(GLint sp) { _source1_Alpha = sp; computeNeedoForTexEnvCombiners(); } + void setSource2_Alpha(GLint sp) { _source2_Alpha = sp; computeNeedoForTexEnvCombiners(); } GLint getSource0_RGB() const { return _source0_RGB; } GLint getSource1_RGB() const { return _source1_RGB; } @@ -184,11 +198,38 @@ class SG_EXPORT TexEnvCombine : public StateAttribute virtual ~TexEnvCombine(); + inline bool needsTexEnvCombiner(GLint value) const + { + switch(value) + { + case(CONSTANT): + case(PRIMARY_COLOR): + case(PREVIOUS): + case(TEXTURE): + return false; + } + return true; + } + + void computeNeedoForTexEnvCombiners() + { + _needsTexEnvCrossbar = (needsTexEnvCombiner(_source0_RGB) || + needsTexEnvCombiner(_source1_RGB) || + needsTexEnvCombiner(_source2_RGB) || + needsTexEnvCombiner(_source0_Alpha) || + needsTexEnvCombiner(_source1_Alpha) || + needsTexEnvCombiner(_source2_Alpha)); + } + + + + + + bool _needsTexEnvCrossbar; GLint _combine_RGB; GLint _combine_Alpha; - - + GLint _source0_RGB; GLint _source1_RGB; GLint _source2_RGB; diff --git a/src/osg/TexEnv.cpp b/src/osg/TexEnv.cpp index 28a1082f4..47fceb072 100644 --- a/src/osg/TexEnv.cpp +++ b/src/osg/TexEnv.cpp @@ -1,4 +1,5 @@ #include +#include using namespace osg; @@ -15,9 +16,20 @@ TexEnv::~TexEnv() void TexEnv::apply(State&) const { - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _mode); - if (_mode==TexEnv::BLEND) + if (_mode==ADD) { - glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, _color.ptr()); + static bool isTexEnvAddSupported = isGLExtensionSupported("GL_ARB_texture_env_add"); + if (isTexEnvAddSupported) + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, ADD); + else // fallback on OpenGL default. + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, MODULATE); + } + else + { + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _mode); + if (_mode==TexEnv::BLEND) + { + glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, _color.ptr()); + } } } diff --git a/src/osg/TexEnvCombine.cpp b/src/osg/TexEnvCombine.cpp index 86ef3dd3c..e18b86015 100644 --- a/src/osg/TexEnvCombine.cpp +++ b/src/osg/TexEnvCombine.cpp @@ -4,6 +4,7 @@ using namespace osg; TexEnvCombine::TexEnvCombine(): + _needsTexEnvCrossbar(false), _combine_RGB(GL_MODULATE), _combine_Alpha(GL_MODULATE), _source0_RGB(GL_TEXTURE), @@ -33,7 +34,10 @@ void TexEnvCombine::apply(State&) const static bool isTexEnvCombineSupported = isGLExtensionSupported("GL_ARB_texture_env_combine"); - if (isTexEnvCombineSupported) + static bool isTexEnvCrossbarSupported = + isGLExtensionSupported("GL_ARB_texture_env_crossbar"); + + if (isTexEnvCrossbarSupported || (!_needsTexEnvCrossbar && isTexEnvCombineSupported)) { glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); diff --git a/src/osgPlugins/osg/TexEnv.cpp b/src/osgPlugins/osg/TexEnv.cpp index aa042899b..78f864a55 100644 --- a/src/osgPlugins/osg/TexEnv.cpp +++ b/src/osgPlugins/osg/TexEnv.cpp @@ -66,6 +66,7 @@ bool TexEnv_writeLocalData(const Object& obj, Output& fw) case(TexEnv::DECAL): case(TexEnv::MODULATE): case(TexEnv::REPLACE): + case(TexEnv::ADD): break; case(TexEnv::BLEND): default: @@ -82,6 +83,7 @@ bool TexEnv_matchModeStr(const char* str,TexEnv::Mode& mode) else if (strcmp(str,"MODULATE")==0) mode = TexEnv::MODULATE; else if (strcmp(str,"BLEND")==0) mode = TexEnv::BLEND; else if (strcmp(str,"REPLACE")==0) mode = TexEnv::REPLACE; + else if (strcmp(str,"ADD")==0) mode = TexEnv::ADD; else return false; return true; } @@ -95,6 +97,7 @@ const char* TexEnv_getModeStr(TexEnv::Mode mode) case(TexEnv::MODULATE): return "MODULATE"; case(TexEnv::BLEND): return "BLEND"; case(TexEnv::REPLACE): return "REPLACE"; + case(TexEnv::ADD): return "ADD"; } return ""; }