Second try!

-------- Исходное сообщение --------
Тема:   GL_blend_equation_separate extension support
Дата:   Thu, 28 May 2009 16:02:13 +0400
От:     Konstantin Sinitsyn <[email protected]>
Кому: OpenSceneGraph Submissions <[email protected]>



Hi Robert!

This changes is for using GL_EXT_blend_equation_separate extension like in blend_mode. Can you commit it, please.

Konstantin!



/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/
#include <osg/BlendEquation>
#include <osg/GLExtensions>
#include <osg/State>
#include <osg/Notify>
#include <osg/buffered_value>


using namespace osg;

BlendEquation::BlendEquation():
    _equationRGB(FUNC_ADD),
    _equationAlpha(FUNC_ADD)
{
}

BlendEquation::BlendEquation(Equation equation):
    _equationRGB(equation),
    _equationAlpha(equation)
{
}

BlendEquation::BlendEquation(Equation equationRGB, Equation equationAlpha):
    _equationRGB(equationRGB),
    _equationAlpha(equationAlpha)
{
}

BlendEquation::~BlendEquation()
{
}

void BlendEquation::apply(State& state) const
{

   // get the contextID (user defined ID of 0 upwards) for the 
    // current OpenGL context.
    const unsigned int contextID = state.getContextID();
    
    const Extensions* extensions = getExtensions(contextID,true);
                                        
    if (!extensions->isBlendEquationSupported())
    {
        notify(WARN)<<"Warning: BlendEquation::apply(..) failed, BlendEquation 
is not support by OpenGL driver."<<std::endl;
        return;
    }

    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;
    }

    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;
    }

    if (_equationRGB == _equationAlpha)
        extensions->glBlendEquation(static_cast<GLenum>(_equationRGB));
    else
    {
        if (extensions->isBlendEquationSeparateSupported())
            
extensions->glBlendEquationSeparate(static_cast<GLenum>(_equationRGB), 
static_cast<GLenum>(_equationAlpha));
        else
        {
            notify(WARN)<<"Warning: BlendEquation::apply(..) failed, 
EXT_blend_equation_separate extension is not supported by OpenGL driver." << 
std::endl;
            return;
        }
    }
}


typedef buffered_value< ref_ptr<BlendEquation::Extensions> > BufferedExtensions;
static BufferedExtensions s_extensions;

BlendEquation::Extensions* BlendEquation::getExtensions(unsigned int 
contextID,bool createIfNotInitalized)
{
    if (!s_extensions[contextID] && createIfNotInitalized) 
s_extensions[contextID] = new Extensions(contextID);
    return s_extensions[contextID].get();
}

void BlendEquation::setExtensions(unsigned int contextID,Extensions* extensions)
{
    s_extensions[contextID] = extensions;
}


BlendEquation::Extensions::Extensions(unsigned int contextID)
{
    setupGLExtensions(contextID);
}

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;

    _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
{
    if (_glBlendEquation)
    {
        _glBlendEquation(mode);
    }
    else
    {
        notify(WARN)<<"Error: glBlendEquation not supported by OpenGL 
driver"<<std::endl;
    }
}

void BlendEquation::Extensions::glBlendEquationSeparate(GLenum modeRGB, GLenum 
modeAlpha) const
{
    if (_glBlendEquationSeparate)
    {
        _glBlendEquationSeparate(modeRGB, modeAlpha);
    }
    else
    {
        notify(WARN)<<"Error: glBlendEquationSeparate not supported by OpenGL 
driver"<<std::endl;
    }
}

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/

#ifndef OSG_BLENDEQUATION
#define OSG_BLENDEQUATION 1

#include <osg/StateAttribute>

#ifndef GL_VERSION_1_2
/* Logic Ops */
#define GL_MIN                                  0x8007
#define GL_MAX                                  0x8008
#define GL_FUNC_ADD                             0x8006
#define GL_FUNC_SUBTRACT                        0x800A
#define GL_FUNC_REVERSE_SUBTRACT                0x800B
#endif

#ifndef GL_LOGIC_OP
#define GL_LOGIC_OP                             0x0BF1
#endif

#ifndef GL_ALPHA_MIN_SGIX
#define GL_ALPHA_MIN_SGIX                       0x8320
#define GL_ALPHA_MAX_SGIX                       0x8321
#endif

namespace osg {

/** Encapsulates OpenGL BlendEquation state. */
class OSG_EXPORT BlendEquation : public StateAttribute
{
    public :

        enum Equation {
            RGBA_MIN                        = GL_MIN,
            RGBA_MAX                        = GL_MAX,
            ALPHA_MIN                       = GL_ALPHA_MIN_SGIX,
            ALPHA_MAX                       = GL_ALPHA_MAX_SGIX,
            LOGIC_OP                        = GL_LOGIC_OP,
            FUNC_ADD                        = GL_FUNC_ADD,
            FUNC_SUBTRACT                   = GL_FUNC_SUBTRACT,
            FUNC_REVERSE_SUBTRACT           = GL_FUNC_REVERSE_SUBTRACT,
        };

        BlendEquation();
        
        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),
            _equationRGB(trans._equationRGB),
            _equationAlpha(trans._equationAlpha){}

        META_StateAttribute(osg, BlendEquation,BLENDEQUATION);
        
        /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
        virtual int compare(const StateAttribute& sa) const
        {
            // Check for equal types, then create the rhs variable
            // used by the COMPARE_StateAttribute_Paramter macros below.
            COMPARE_StateAttribute_Types(BlendEquation,sa)

            // Compare each parameter in turn against the rhs.
            COMPARE_StateAttribute_Parameter(_equationRGB)
            COMPARE_StateAttribute_Parameter(_equationAlpha)

            return 0; // Passed all the above comparison macros, so must be 
equal.
        }

        virtual bool getModeUsage(StateAttribute::ModeUsage& usage) const
        {
            usage.usesMode(GL_BLEND);
            return true;
        }


        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; }

        virtual void apply(State& state) const;
        /** Encapsulates queries of extension availability, obtains extension
          * function pointers, and provides convenience wrappers for
          * calling extension functions. */        
        class OSG_EXPORT Extensions : public osg::Referenced
        {
            public:
                Extensions(unsigned int contextID);

                Extensions(const Extensions& rhs);
                
                void lowestCommonDenominator(const Extensions& rhs);
                
                void setupGLExtensions(unsigned int contextID);

                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 * 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.
          * If createIfNotInitalized is true and the Extensions object doesn't
          * exist, getExtensions() creates it on the given context.
          * Returns NULL if createIfNotInitalized is false and the Extensions
          * object doesn't exist. */
        static Extensions* getExtensions(unsigned int contextID,bool 
createIfNotInitalized);

        /** setExtensions() allows users to override the extensions across 
graphics contexts.
          * Typically used when you have different extensions supported across 
graphics pipes,
          * but need to ensure that they all use the same low common 
denominator extensions. */
        static void setExtensions(unsigned int contextID,Extensions* 
extensions);


    protected :

        virtual ~BlendEquation();


        Equation _equationRGB, _equationAlpha;
};

}

#endif
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to