diff --git a/include/osg/BlendEquation b/include/osg/BlendEquation index 1939c17a1..ed505b6be 100644 --- a/include/osg/BlendEquation +++ b/include/osg/BlendEquation @@ -56,10 +56,13 @@ class OSG_EXPORT BlendEquation : public StateAttribute BlendEquation(Equation equation); + BlendEquation(Equation equationRGB, Equation equationAlpha); + /** Copy constructor using CopyOp to manage deep vs shallow copy. */ BlendEquation(const BlendEquation& trans,const CopyOp& copyop=CopyOp::SHALLOW_COPY): StateAttribute(trans,copyop), - _equation(trans._equation){} + _equationRGB(trans._equationRGB), + _equationAlpha(trans._equationAlpha){} META_StateAttribute(osg, BlendEquation,BLENDEQUATION); @@ -71,7 +74,8 @@ class OSG_EXPORT BlendEquation : public StateAttribute COMPARE_StateAttribute_Types(BlendEquation,sa) // Compare each parameter in turn against the rhs. - COMPARE_StateAttribute_Parameter(_equation) + COMPARE_StateAttribute_Parameter(_equationRGB) + COMPARE_StateAttribute_Parameter(_equationAlpha) return 0; // Passed all the above comparison macros, so must be equal. } @@ -83,13 +87,15 @@ class OSG_EXPORT BlendEquation : public StateAttribute } - inline void setEquation(Equation equation) - { - _equation = equation; - } + inline void setEquation(Equation equation) { _equationRGB = _equationAlpha = equation; } + inline Equation getEquation() const { return _equationRGB; } + + inline void setEquationRGB(Equation equation) { _equationRGB = equation; } + inline Equation getEquationRGB() const { return _equationRGB; } + + inline void setEquationAlpha(Equation equation) { _equationAlpha = equation; } + inline Equation getEquationAlpha() const { return _equationAlpha; } - inline Equation getEquation() const { return _equation; } - virtual void apply(State& state) const; /** Encapsulates queries of extension availability, obtains extension * function pointers, and provides convenience wrappers for @@ -105,25 +111,28 @@ class OSG_EXPORT BlendEquation : public StateAttribute void setupGLExtensions(unsigned int contextID); - void setBlendEquationSupported(bool flag) { _isBlendEquationSupported=flag; } bool isBlendEquationSupported() const { return _isBlendEquationSupported; } + bool isBlendEquationSeparateSupported() const { return _isBlendEquationSeparateSupported; } bool isSGIXMinMaxSupported() const { return _isSGIXMinMaxSupported; } bool isLogicOpSupported() const { return _isLogicOpSupported; } void glBlendEquation(GLenum mode) const; + void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) const; protected: ~Extensions() {} - typedef void (APIENTRY * GLBlendEquationProc) (GLenum mode); + typedef void (APIENTRY * GLBlendEquationProc)(GLenum mode); + typedef void (APIENTRY * GLBlendEquationSeparateProc)(GLenum modeRGB, GLenum modeAlpha); bool _isBlendEquationSupported; + bool _isBlendEquationSeparateSupported; bool _isSGIXMinMaxSupported; bool _isLogicOpSupported; GLBlendEquationProc _glBlendEquation; - + GLBlendEquationSeparateProc _glBlendEquationSeparate; }; /** Returns the Extensions object for the given context. @@ -144,7 +153,7 @@ class OSG_EXPORT BlendEquation : public StateAttribute virtual ~BlendEquation(); - Equation _equation; + Equation _equationRGB, _equationAlpha; }; } diff --git a/src/osg/BlendEquation.cpp b/src/osg/BlendEquation.cpp index bda807d44..817070a94 100644 --- a/src/osg/BlendEquation.cpp +++ b/src/osg/BlendEquation.cpp @@ -20,12 +20,20 @@ using namespace osg; BlendEquation::BlendEquation(): - _equation(FUNC_ADD) + _equationRGB(FUNC_ADD), + _equationAlpha(FUNC_ADD) { } BlendEquation::BlendEquation(Equation equation): - _equation(equation) + _equationRGB(equation), + _equationAlpha(equation) +{ +} + +BlendEquation::BlendEquation(Equation equationRGB, Equation equationAlpha): + _equationRGB(equationRGB), + _equationAlpha(equationAlpha) { } @@ -48,23 +56,30 @@ void BlendEquation::apply(State& state) const return; } - GLenum eqn = static_cast(_equation); - - if((eqn == ALPHA_MIN || eqn == ALPHA_MAX) && - !extensions->isSGIXMinMaxSupported()) + if((_equationRGB == ALPHA_MIN || _equationRGB == ALPHA_MAX) && !extensions->isSGIXMinMaxSupported()) { - notify(WARN)<<"Warning: BlendEquation::apply(..) failed, SGIX_blend_alpha_minmax extension is not supported by OpenGL driver." << std::endl; - return; + notify(WARN)<<"Warning: BlendEquation::apply(..) failed, SGIX_blend_alpha_minmax extension is not supported by OpenGL driver." << std::endl; + return; } - if(eqn == LOGIC_OP && !extensions->isLogicOpSupported()) + if(_equationRGB == LOGIC_OP && !extensions->isLogicOpSupported()) { - notify(WARN)<<"Warning: BlendEquation::apply(..) failed, EXT_blend_logic_op extension is not supported by OpenGL driver." << std::endl; - return; + notify(WARN)<<"Warning: BlendEquation::apply(..) failed, EXT_blend_logic_op extension is not supported by OpenGL driver." << std::endl; + return; + } + + if (_equationRGB == _equationAlpha) + extensions->glBlendEquation(static_cast(_equationRGB)); + else + { + if (extensions->isBlendEquationSeparateSupported()) + extensions->glBlendEquationSeparate(static_cast(_equationRGB), static_cast(_equationAlpha)); + else + { + notify(WARN)<<"Warning: BlendEquation::apply(..) failed, EXT_blend_equation_separate extension is not supported by OpenGL driver." << std::endl; + return; + } } - - extensions->glBlendEquation(static_cast(_equation)); - } @@ -92,26 +107,34 @@ BlendEquation::Extensions::Extensions(const Extensions& rhs): Referenced() { _isBlendEquationSupported = rhs._isBlendEquationSupported; + _isBlendEquationSeparateSupported = rhs._isBlendEquationSeparateSupported; _isSGIXMinMaxSupported = rhs._isSGIXMinMaxSupported; _isLogicOpSupported = rhs._isLogicOpSupported; _glBlendEquation = rhs._glBlendEquation; + _glBlendEquationSeparate = rhs._glBlendEquationSeparate; } void BlendEquation::Extensions::lowestCommonDenominator(const Extensions& rhs) { if (!rhs._isBlendEquationSupported) _isBlendEquationSupported = false; if (!rhs._glBlendEquation) _glBlendEquation = 0; + if (!rhs._isBlendEquationSeparateSupported) _isBlendEquationSeparateSupported = false; + if (!rhs._glBlendEquationSeparate) _glBlendEquationSeparate = 0; } void BlendEquation::Extensions::setupGLExtensions(unsigned int contextID) { - _isBlendEquationSupported = isGLExtensionSupported(contextID,"GL_EXT_blend_equation") || - strncmp((const char*)glGetString(GL_VERSION),"1.2",3)>=0; - + _isBlendEquationSupported = isGLExtensionSupported(contextID, "GL_EXT_blend_equation") || + strncmp((const char*)glGetString(GL_VERSION), "1.2", 3) >= 0; + + _isBlendEquationSeparateSupported = isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") || + strncmp((const char*)glGetString(GL_VERSION), "2.0", 3) >= 0; + _isSGIXMinMaxSupported = isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax"); _isLogicOpSupported = isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op"); setGLExtensionFuncPtr(_glBlendEquation, "glBlendEquation", "glBlendEquationEXT"); + setGLExtensionFuncPtr(_glBlendEquationSeparate, "glBlendEquationSeparate", "glBlendEquationSeparateEXT"); } void BlendEquation::Extensions::glBlendEquation(GLenum mode) const @@ -126,4 +149,15 @@ void BlendEquation::Extensions::glBlendEquation(GLenum mode) const } } +void BlendEquation::Extensions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) const +{ + if (_glBlendEquationSeparate) + { + _glBlendEquationSeparate(modeRGB, modeAlpha); + } + else + { + notify(WARN)<<"Error: glBlendEquationSeparate not supported by OpenGL driver"<