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