diff --git a/include/osg/Point b/include/osg/Point index 9cda26d06..84d09de1c 100644 --- a/include/osg/Point +++ b/include/osg/Point @@ -77,7 +77,48 @@ class OSG_EXPORT Point : public StateAttribute virtual void apply(State& state) const; - static void init_GL_EXT(); + /** Encapsulates queries of extension availability, obtains extension + * function pointers, and provides convinience wrappers for + * calling extension functions. */ + class OSG_EXPORT Extensions : public osg::Referenced + { + public: + Extensions(); + + Extensions(const Extensions& rhs); + + void lowestCommonDenominator(const Extensions& rhs); + + void setupGLExtenions(); + + void setPointParametersSupported(bool flag) { _isPointParametersSupported=flag; } + bool isPointParametersSupported() const { return _isPointParametersSupported; } + + void glPointParameterf(GLenum pname, GLfloat param) const; + void glPointParameterfv(GLenum pname, const GLfloat *params) const; + + protected: + + ~Extensions() {} + + bool _isPointParametersSupported; + + void* _glPointParameterf; + void* _glPointParameterfv; + + }; + + /** Returns the Extensions object for the given context. + * If createIfNotInitalized is true and the Exentsions 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/src/osg/Point.cpp b/src/osg/Point.cpp index 881f43536..85377e823 100644 --- a/src/osg/Point.cpp +++ b/src/osg/Point.cpp @@ -10,46 +10,23 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ -// Ideas and code borrowed from GLUT pointburst demo -// written by Mark J. Kilgard #include #include +#include #include #include using namespace osg; -// if extensions not defined by gl.h (or via glext.h) define them -// ourselves and allow the extensions to detectd at runtine using -// osg::isGLExtensionSupported(). -#if defined(GL_SGIS_point_parameters) && !defined(GL_EXT_point_parameters) -/* Use the EXT point parameters interface for the SGIS implementation. */ -# define GL_POINT_SIZE_MIN_EXT GL_POINT_SIZE_MIN_SGIS -# define GL_POINT_SIZE_MAX_EXT GL_POINT_SIZE_MAX_SGIS -# define GL_POINT_FADE_THRESHOLD_SIZE_EXT GL_POINT_FADE_THRESHOLD_SIZE_SGIS -# define GL_DISTANCE_ATTENUATION_EXT GL_DISTANCE_ATTENUATION_SGIS -# define GL_EXT_point_parameters 1 +// ARB, EXT and SGIS versions use same values as OpenGL version 1.4. +#ifndef GL_VERSION_1_4 +# define GL_POINT_SIZE_MIN 0x8126 +# define GL_POINT_SIZE_MAX 0x8127 +# define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +# define GL_POINT_DISTANCE_ATTENUATION 0x8129 #endif -#if !defined(GL_EXT_point_parameters) -# define GL_POINT_SIZE_MIN_EXT 0x8126 -# define GL_POINT_SIZE_MAX_EXT 0x8127 -# define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -# define GL_DISTANCE_ATTENUATION_EXT 0x8129 -# define GL_EXT_point_parameters 1 -#endif - -#ifndef PFNGLPOINTPARAMETERFEXTPROC -typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -#endif -#ifndef PFNGLPOINTPARAMETERFVEXTPROC -typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); -#endif - -PFNGLPOINTPARAMETERFEXTPROC s_PointParameterfEXT = NULL; -PFNGLPOINTPARAMETERFVEXTPROC s_PointParameterfvEXT = NULL; - Point::Point() { _size = 1.0f; // TODO find proper default @@ -66,24 +43,6 @@ Point::~Point() { } -void Point::init_GL_EXT() -{ - if (isGLExtensionSupported("GL_EXT_point_parameters")) - { - s_PointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC) - getGLExtensionFuncPtr("glPointParameterfEXT"); - s_PointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC) - getGLExtensionFuncPtr("glPointParameterfvEXT"); - } - else if (isGLExtensionSupported("GL_SGIS_point_parameters")) - { - s_PointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC) - getGLExtensionFuncPtr("glPointParameterfSGIS"); - s_PointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC) - getGLExtensionFuncPtr("glPointParameterfvSGIS"); - } - -} void Point::setSize( float size ) { @@ -112,26 +71,92 @@ void Point::setMaxSize(float maxSize) _maxSize = maxSize; } -void Point::apply(State&) const +void Point::apply(State& state) const { glPointSize(_size); - static bool s_gl_ext_init=false; + const unsigned int contextID = state.getContextID(); + const Extensions* extensions = getExtensions(contextID,true); - if (!s_gl_ext_init) + if (!extensions->isPointParametersSupported()) + return; + + extensions->glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, (const GLfloat*)&_distanceAttenuation); + extensions->glPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, _fadeThresholdSize); + extensions->glPointParameterf(GL_POINT_SIZE_MIN, _minSize); + extensions->glPointParameterf(GL_POINT_SIZE_MAX, _maxSize); +} + + +typedef buffered_value< ref_ptr > BufferedExtensions; +static BufferedExtensions s_extensions; + +Point::Extensions* Point::getExtensions(unsigned int contextID,bool createIfNotInitalized) +{ + if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions; + return s_extensions[contextID].get(); +} + +void Point::setExtensions(unsigned int contextID,Extensions* extensions) +{ + s_extensions[contextID] = extensions; +} + +Point::Extensions::Extensions() +{ + setupGLExtenions(); +} + +Point::Extensions::Extensions(const Extensions& rhs): + Referenced() +{ + _isPointParametersSupported = rhs._isPointParametersSupported; +} + +void Point::Extensions::lowestCommonDenominator(const Extensions& rhs) +{ + if (!rhs._isPointParametersSupported) _isPointParametersSupported = false; + if (!rhs._glPointParameterf) _glPointParameterf = 0; + if (!rhs._glPointParameterfv) _glPointParameterfv = 0; +} + +void Point::Extensions::setupGLExtenions() +{ + _isPointParametersSupported = strncmp((const char*)glGetString(GL_VERSION),"1.4",3)>=0 || + isGLExtensionSupported("GL_ARB_point_parameters") || + isGLExtensionSupported("GL_EXT_point_parameters") || + isGLExtensionSupported("GL_SGIS_point_parameters"); + + _glPointParameterf = getGLExtensionFuncPtr("glPointParameterf", "glPointParameterfARB"); + if (!_glPointParameterf) _glPointParameterf = getGLExtensionFuncPtr("glPointParameterfEXT", "glPointParameterfSGIS"); + + _glPointParameterfv = getGLExtensionFuncPtr("glPointParameterfv", "glPointParameterfvARB"); + if (!_glPointParameterfv) _glPointParameterfv = getGLExtensionFuncPtr("glPointParameterfvEXT", "glPointParameterfvSGIS"); +} + + +void Point::Extensions::glPointParameterf(GLenum pname, GLfloat param) const +{ + if (_glPointParameterf) { - s_gl_ext_init = true; - init_GL_EXT(); + typedef void (APIENTRY * GLPointParameterfProc) (GLenum pname, GLfloat param); + ((GLPointParameterfProc)_glPointParameterf)(pname, param); } - - - if (s_PointParameterfvEXT) s_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, (const GLfloat*)&_distanceAttenuation); - - if (s_PointParameterfEXT) + else { - s_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, _fadeThresholdSize); - s_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT, _minSize); - s_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT, _maxSize); + notify(WARN)<<"Error: glPointParameterf not supported by OpenGL driver"<