diff --git a/src/Context.h b/src/Context.h index 9e27df393..b76878f77 100644 --- a/src/Context.h +++ b/src/Context.h @@ -317,8 +317,9 @@ class MAGNUM_EXPORT Context { * @endcode * * If no version from the list is supported, returns lowest available - * OpenGL version (@ref Version::GL210 for desktop OpenGL, @ref Version::GLES200 - * for OpenGL ES). + * OpenGL version (@ref Version::GL210 for desktop OpenGL, + * @ref Version::GLES200 for OpenGL ES). + * @see @ref isExtensionSupported(Version) */ Version supportedVersion(std::initializer_list versions) const; @@ -342,6 +343,25 @@ class MAGNUM_EXPORT Context { return isVersionSupported(T::coreVersion()) || (isVersionSupported(T::requiredVersion()) && extensionStatus[T::Index]); } + /** + * @brief Whether given extension is supported in given version + * + * Similar to @ref isExtensionSupported(), but checks also that the + * minimal required version of the extension is larger or equal to + * @p version. Useful mainly in shader compilation when the decisions + * depend on selected GLSL version, for example: + * @code + * const Version version = Context::current()->supportedVersion({Version::GL320, Version::GL300, Version::GL210}); + * if(Context::current()->isExtensionSupported(version)) { + * // Called only if ARB_explicit_attrib_location is supported + * // *and* version is higher than GL 3.1 + * } + * @endcode + */ + template bool isExtensionSupported(Version version) const { + return T::coreVersion() <= version || (T::requiredVersion() <= version && extensionStatus[T::Index]); + } + /** * @brief Whether given extension is supported * diff --git a/src/Test/ContextTest.cpp b/src/Test/ContextTest.cpp index 69dd9d05a..ba2a9cb22 100644 --- a/src/Test/ContextTest.cpp +++ b/src/Test/ContextTest.cpp @@ -37,6 +37,7 @@ class ContextTest: public AbstractOpenGLTester { void supportedExtension(); void unsupportedExtension(); void pastExtension(); + void versionDependentExtension(); }; ContextTest::ContextTest() { @@ -44,7 +45,8 @@ ContextTest::ContextTest() { &ContextTest::versionList, &ContextTest::supportedExtension, &ContextTest::unsupportedExtension, - &ContextTest::pastExtension}); + &ContextTest::pastExtension, + &ContextTest::versionDependentExtension}); } void ContextTest::version() { @@ -114,6 +116,19 @@ void ContextTest::pastExtension() { #endif } +void ContextTest::versionDependentExtension() { + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE(Extensions::GL::ARB::get_program_binary::requiredVersion(), Version::GL300); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::get_program_binary::string() + std::string("extension isn't supported, can't test")); + + CORRADE_VERIFY(Context::current()->isExtensionSupported(Context::current()->version())); + CORRADE_VERIFY(!Context::current()->isExtensionSupported(Version::GL210)); + #else + CORRADE_SKIP("No OpenGL ES 3.0-only extensions exist yet"); + #endif +} + }} CORRADE_TEST_MAIN(Magnum::Test::ContextTest)