diff --git a/include/osg/BlendFunc b/include/osg/BlendFunc index d2cb3d2a4..ec73cf8e9 100644 --- a/include/osg/BlendFunc +++ b/include/osg/BlendFunc @@ -15,6 +15,7 @@ #define OSG_BLENDFUNC 1 #include +#include #ifndef GL_VERSION_1_2 @@ -157,54 +158,25 @@ class OSG_EXPORT BlendFunc : public StateAttribute inline GLenum getDestinationAlpha() const { return _destination_factor_alpha; } 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 + struct Extensions : public osg::Referenced { - public: - Extensions(unsigned int contextID); + bool isBlendFuncSeparateSupported; + void (GL_APIENTRY * glBlendFuncSeparate) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) ; - Extensions(const Extensions& rhs); - - void lowestCommonDenominator(const Extensions& rhs); - - void setupGLExtensions(unsigned int contextID); - - void setBlendFuncSeparateSupported(bool flag) { _isBlendFuncSeparateSupported=flag; } - bool isBlendFuncSeparateSupported() const { return _isBlendFuncSeparateSupported; } - - void glBlendFuncSeparate(GLenum sfactorRGB, - GLenum dfactorRGB, - GLenum sfactorAlpha, - GLenum dfactorAlpha) const; - - protected: - - ~Extensions() {} - - - typedef void (GL_APIENTRY * GLBlendFuncSeparateProc) (GLenum sfactorRGB, - GLenum dfactorRGB, - GLenum sfactorAlpha, - GLenum dfactorAlpha); - bool _isBlendFuncSeparateSupported; - GLBlendFuncSeparateProc _glBlendFuncSeparate; + Extensions(unsigned int contextID) + { + isBlendFuncSeparateSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || + osg::isGLExtensionSupported(contextID, "GL_EXT_blend_func_separate") || + strncmp((const char*)glGetString(GL_VERSION), "1.4", 3) >= 0; + setGLExtensionFuncPtr(glBlendFuncSeparate, "glBlendFuncSeparate", "glBlendFuncSeparateEXT"); + } }; - /** 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 : diff --git a/include/osg/State b/include/osg/State index 64beb580d..85cc23ea4 100644 --- a/include/osg/State +++ b/include/osg/State @@ -150,6 +150,37 @@ class OSG_EXPORT State : public Referenced inline unsigned int getContextID() const { return _contextID; } + // ExtensionMap contains GL Extentsions objects used by StateAttribue to call OpenGL extensions/advanced features + typedef std::map > ExtensionMap; + ExtensionMap _extensionMap; + + /** Get a specific GL extensions object, initialize if not already present. + * Note, must only be called from a the graphics context thread associated with this osg::State. */ + template + T* get() + { + const std::type_info* id(&typeid(T)); + osg::ref_ptr& ptr = _extensionMap[id]; + if (!ptr) + { + ptr = new T(_contextID); + } + return static_cast(ptr.get()); + } + + /** Get a specific GL extensions object if it already exists in the extension map. + * Note, safe to call outwith a the graphics context thread associated with this osg::State. + * Returns NULL if the desired extension object has not been created yet.*/ + template + const T* getExisting() const + { + const std::type_info* id(&typeid(T)); + ExtensionMap::const_iterator itr = _extensionMap.find(id); + if (itr==_extensionMap.end()) return 0; + else return itr->second.get(); + } + + /* Set whether shader composition is enabled.*/ void setShaderCompositionEnabled(bool flag) { _shaderCompositionEnabled = flag; } diff --git a/src/osg/BlendFunc.cpp b/src/osg/BlendFunc.cpp index 5c8c905fd..054e856e0 100644 --- a/src/osg/BlendFunc.cpp +++ b/src/osg/BlendFunc.cpp @@ -50,13 +50,8 @@ void BlendFunc::apply(State& state) const if (_source_factor != _source_factor_alpha || _destination_factor != _destination_factor_alpha) { - // 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->isBlendFuncSeparateSupported()) + const Extensions* extensions = state.get(); + if (!extensions->isBlendFuncSeparateSupported) { OSG_WARN<<"Warning: BlendFunc::apply(..) failed, BlendFuncSeparate is not support by OpenGL driver, falling back to BlendFunc."< > BufferedExtensions; -static BufferedExtensions s_extensions; - -BlendFunc::Extensions* BlendFunc::getExtensions(unsigned int contextID,bool createIfNotInitalized) -{ - if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions(contextID); - return s_extensions[contextID].get(); -} - -void BlendFunc::setExtensions(unsigned int contextID,Extensions* extensions) -{ - s_extensions[contextID] = extensions; -} - - -BlendFunc::Extensions::Extensions(unsigned int contextID) -{ - setupGLExtensions(contextID); -} - -BlendFunc::Extensions::Extensions(const Extensions& rhs): - Referenced() -{ - _isBlendFuncSeparateSupported = rhs._isBlendFuncSeparateSupported; - _glBlendFuncSeparate = rhs._glBlendFuncSeparate; -} - -void BlendFunc::Extensions::lowestCommonDenominator(const Extensions& rhs) -{ - if (!rhs._isBlendFuncSeparateSupported) _isBlendFuncSeparateSupported = false; - if (!rhs._glBlendFuncSeparate) _glBlendFuncSeparate = 0; -} - -void BlendFunc::Extensions::setupGLExtensions(unsigned int contextID) -{ - _isBlendFuncSeparateSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || - isGLExtensionSupported(contextID, "GL_EXT_blend_func_separate") || - strncmp((const char*)glGetString(GL_VERSION), "1.4", 3) >= 0; - - setGLExtensionFuncPtr(_glBlendFuncSeparate, "glBlendFuncSeparate", "glBlendFuncSeparateEXT"); -} - -void BlendFunc::Extensions::glBlendFuncSeparate(GLenum sfactorRGB, - GLenum dfactorRGB, - GLenum sfactorAlpha, - GLenum dfactorAlpha) const -{ - if (_glBlendFuncSeparate) - { - _glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); - } - else - { - OSG_WARN<<"Error: glBlendFuncSeparate not supported by OpenGL driver"<