diff --git a/include/osg/GLExtensions b/include/osg/GLExtensions index 48024f384..750ce91e3 100644 --- a/include/osg/GLExtensions +++ b/include/osg/GLExtensions @@ -38,6 +38,12 @@ extern OSG_EXPORT bool isExtensionInExtensionString(const char *extension, const */ extern OSG_EXPORT bool isGLExtensionSupported(unsigned int contextID, const char *extension); +/** Return true if OpenGL "extension" or minimum OpenGL version number is supported. + * Note: Must only be called within a valid OpenGL context, + * undefined behavior may occur otherwise. +*/ +extern OSG_EXPORT bool isGLExtensionOrVersionSupported(unsigned int contextID, const char *extension, float requiredGlVersion); + /** Return the address of the specified OpenGL function. * Return NULL if function not supported by OpenGL library. * Note, glGLExtensionFuncPtr is declared inline so that the code diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index cfa08f90d..15af23a16 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -68,84 +69,95 @@ bool osg::isExtensionInExtensionString(const char *extension, const char *extens } bool osg::isGLExtensionSupported(unsigned int contextID, const char *extension) +{ + return osg::isGLExtensionOrVersionSupported(contextID, extension, FLT_MAX); +} + +bool osg::isGLExtensionOrVersionSupported(unsigned int contextID, const char *extension, float requiredGLVersion) { ExtensionSet& extensionSet = s_glExtensionSetList[contextID]; std::string& rendererString = s_glRendererList[contextID]; - // if not already set up, initialize all the per graphic context values. - if (!s_glInitializedList[contextID]) - { - s_glInitializedList[contextID] = 1; + // first check to see if GL version number of recent enough. + bool result = requiredGLVersion <= osg::getGLVersionNumber(); - // set up the renderer - const GLubyte* renderer = glGetString(GL_RENDERER); - rendererString = renderer ? (const char*)renderer : ""; - - // get the extension list from OpenGL. - const char* extensions = (const char*)glGetString(GL_EXTENSIONS); - if (extensions==NULL) return false; - - // insert the ' ' delimiated extensions words into the extensionSet. - const char *startOfWord = extensions; - const char *endOfWord; - while ((endOfWord = strchr(startOfWord,' '))!=NULL) + if (!result) + { + // if not already set up, initialize all the per graphic context values. + if (!s_glInitializedList[contextID]) { - extensionSet.insert(std::string(startOfWord,endOfWord)); - startOfWord = endOfWord+1; - } - if (*startOfWord!=0) extensionSet.insert(std::string(startOfWord)); + s_glInitializedList[contextID] = 1; -#if defined(WIN32) + // set up the renderer + const GLubyte* renderer = glGetString(GL_RENDERER); + rendererString = renderer ? (const char*)renderer : ""; - // add WGL extensions to the list + // get the extension list from OpenGL. + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + if (extensions==NULL) return false; - typedef const char* WINAPI WGLGETEXTENSIONSSTRINGARB(HDC); - WGLGETEXTENSIONSSTRINGARB* wglGetExtensionsStringARB = - (WGLGETEXTENSIONSSTRINGARB*)getGLExtensionFuncPtr("wglGetExtensionsStringARB"); - - typedef const char* WINAPI WGLGETEXTENSIONSSTRINGEXT(); - WGLGETEXTENSIONSSTRINGEXT* wglGetExtensionsStringEXT = - (WGLGETEXTENSIONSSTRINGEXT*)getGLExtensionFuncPtr("wglGetExtensionsStringEXT"); - - const char* wglextensions = 0; - - if (wglGetExtensionsStringARB) - { - HDC dc = wglGetCurrentDC(); - wglextensions = wglGetExtensionsStringARB(dc); - } - else if (wglGetExtensionsStringEXT) - { - wglextensions = wglGetExtensionsStringEXT(); - } - - if (wglextensions) - { - const char* startOfWord = wglextensions; - const char* endOfWord; - while ((endOfWord = strchr(startOfWord, ' '))) + // insert the ' ' delimiated extensions words into the extensionSet. + const char *startOfWord = extensions; + const char *endOfWord; + while ((endOfWord = strchr(startOfWord,' '))!=NULL) { - extensionSet.insert(std::string(startOfWord, endOfWord)); + extensionSet.insert(std::string(startOfWord,endOfWord)); startOfWord = endOfWord+1; } - if (*startOfWord != 0) extensionSet.insert(std::string(startOfWord)); + if (*startOfWord!=0) extensionSet.insert(std::string(startOfWord)); + + #if defined(WIN32) + + // add WGL extensions to the list + + typedef const char* WINAPI WGLGETEXTENSIONSSTRINGARB(HDC); + WGLGETEXTENSIONSSTRINGARB* wglGetExtensionsStringARB = + (WGLGETEXTENSIONSSTRINGARB*)getGLExtensionFuncPtr("wglGetExtensionsStringARB"); + + typedef const char* WINAPI WGLGETEXTENSIONSSTRINGEXT(); + WGLGETEXTENSIONSSTRINGEXT* wglGetExtensionsStringEXT = + (WGLGETEXTENSIONSSTRINGEXT*)getGLExtensionFuncPtr("wglGetExtensionsStringEXT"); + + const char* wglextensions = 0; + + if (wglGetExtensionsStringARB) + { + HDC dc = wglGetCurrentDC(); + wglextensions = wglGetExtensionsStringARB(dc); + } + else if (wglGetExtensionsStringEXT) + { + wglextensions = wglGetExtensionsStringEXT(); + } + + if (wglextensions) + { + const char* startOfWord = wglextensions; + const char* endOfWord; + while ((endOfWord = strchr(startOfWord, ' '))) + { + extensionSet.insert(std::string(startOfWord, endOfWord)); + startOfWord = endOfWord+1; + } + if (*startOfWord != 0) extensionSet.insert(std::string(startOfWord)); + } + + #endif + + osg::notify(INFO)<<"OpenGL extensions supported by installed OpenGL drivers are:"<= 1.3 ) || - isGLExtensionSupported(contextID,"GL_ARB_multitexture") || - isGLExtensionSupported(contextID,"GL_EXT_multitexture"); + _isMultiTexturingSupported = isGLExtensionOrVersionSupported( contextID,"GL_ARB_multitexture", 1.3) || + isGLExtensionOrVersionSupported(contextID,"GL_EXT_multitexture", 1.3); + _isTextureFilterAnisotropicSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_filter_anisotropic"); - _isTextureCompressionARBSupported = ( glVersion >= 1.3 ) || - isGLExtensionSupported(contextID,"GL_ARB_texture_compression"); + + _isTextureCompressionARBSupported = isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_compression", 1.3); + _isTextureCompressionS3TCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc"); - _isTextureMirroredRepeatSupported = ( glVersion >= 1.4 ) || - isGLExtensionSupported(contextID,"GL_IBM_texture_mirrored_repeat") || - isGLExtensionSupported(contextID,"GL_ARB_texture_mirrored_repeat"); - _isTextureEdgeClampSupported = ( glVersion >= 1.2 ) || - isGLExtensionSupported(contextID,"GL_EXT_texture_edge_clamp") || - isGLExtensionSupported(contextID,"GL_SGIS_texture_edge_clamp"); - _isTextureBorderClampSupported = ( glVersion >= 1.3 ) || - isGLExtensionSupported(contextID,"GL_ARB_texture_border_clamp"); - _isGenerateMipMapSupported = (strncmp((const char*)glGetString(GL_VERSION),"1.4",3)>=0) || - isGLExtensionSupported(contextID,"GL_SGIS_generate_mipmap"); + + _isTextureMirroredRepeatSupported = isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4) || + isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4); + + _isTextureEdgeClampSupported = isGLExtensionOrVersionSupported(contextID,"GL_EXT_texture_edge_clamp", 1.2) || + isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2); + + _isTextureBorderClampSupported = isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3); + + _isGenerateMipMapSupported = isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4); + _isShadowSupported = isGLExtensionSupported(contextID,"GL_ARB_shadow"); + _isShadowAmbientSupported = isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient"); _isClientStorageSupported = isGLExtensionSupported(contextID,"GL_APPLE_client_storage"); - _isNonPowerOfTwoTextureNonMipMappedSupported = ( glVersion >= 2.0 ) || - isGLExtensionSupported(contextID,"GL_ARB_texture_non_power_of_two"); + _isNonPowerOfTwoTextureNonMipMappedSupported = isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_non_power_of_two", 2.0); _isNonPowerOfTwoTextureMipMappedSupported = _isNonPowerOfTwoTextureNonMipMappedSupported;