diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp index 3eca63356..e0973b764 100644 --- a/src/Magnum/Context.cpp +++ b/src/Magnum/Context.cpp @@ -377,13 +377,14 @@ const std::vector& Extension::extensions(Version version) { case Version::GL320: return extensions320; case Version::GL330: return extensions330; case Version::GL400: return extensions400; - /* case Version::GLES200: */ case Version::GL410: return extensions410; case Version::GL420: return extensions420; - /* case Version::GLES300: */ case Version::GL430: return extensions430; case Version::GL440: return extensions440; case Version::GL450: return extensions450; + case Version::GLES200: + case Version::GLES300: + case Version::GLES310: return empty; #else case Version::GLES200: return empty; case Version::GLES300: @@ -748,6 +749,19 @@ std::vector Context::extensionStrings() const { return extensions; } +bool Context::isVersionSupported(Version version) const { + #ifndef MAGNUM_TARGET_GLES + if(version == Version::GLES200) + return isExtensionSupported(); + if(version == Version::GLES300) + return isExtensionSupported(); + if(version == Version::GLES310) + return isExtensionSupported(); + #endif + + return _version >= version; +} + Version Context::supportedVersion(std::initializer_list versions) const { for(auto version: versions) if(isVersionSupported(version)) return version; diff --git a/src/Magnum/Context.h b/src/Magnum/Context.h index 99a602282..d9821ff92 100644 --- a/src/Magnum/Context.h +++ b/src/Magnum/Context.h @@ -362,9 +362,7 @@ class MAGNUM_EXPORT Context { * * @see @ref supportedVersion(), @ref MAGNUM_ASSERT_VERSION_SUPPORTED() */ - bool isVersionSupported(Version version) const { - return _version >= version; - } + bool isVersionSupported(Version version) const; /** * @brief Get supported OpenGL version diff --git a/src/Magnum/Shader.cpp b/src/Magnum/Shader.cpp index 694b60e36..eba5bb1ad 100644 --- a/src/Magnum/Shader.cpp +++ b/src/Magnum/Shader.cpp @@ -733,13 +733,13 @@ Shader::Shader(const Version version, const Type type): _type(type), _id(0) { case Version::GL430: _sources.push_back("#version 430\n"); return; case Version::GL440: _sources.push_back("#version 440\n"); return; case Version::GL450: _sources.push_back("#version 450\n"); return; - #else + #endif + /* `#version 100` really is GLSL ES 1.00 and *not* GLSL 1.00. What a mess. */ case Version::GLES200: _sources.push_back("#version 100\n"); return; case Version::GLES300: _sources.push_back("#version 300 es\n"); return; #ifndef MAGNUM_TARGET_WEBGL case Version::GLES310: _sources.push_back("#version 310 es\n"); return; #endif - #endif /* The user is responsible for (not) adding #version directive */ case Version::None: return; diff --git a/src/Magnum/Test/ContextGLTest.cpp b/src/Magnum/Test/ContextGLTest.cpp index cef1210a0..7f0986a0f 100644 --- a/src/Magnum/Test/ContextGLTest.cpp +++ b/src/Magnum/Test/ContextGLTest.cpp @@ -37,6 +37,9 @@ struct ContextGLTest: AbstractOpenGLTester { void constructCopyMove(); void isVersionSupported(); + #ifndef MAGNUM_TARGET_GLES + void isVersionSupportedES(); + #endif void supportedVersion(); void isExtensionSupported(); void isExtensionDisabled(); @@ -46,6 +49,9 @@ ContextGLTest::ContextGLTest() { addTests({&ContextGLTest::constructCopyMove, &ContextGLTest::isVersionSupported, + #ifndef MAGNUM_TARGET_GLES + &ContextGLTest::isVersionSupportedES, + #endif &ContextGLTest::supportedVersion, &ContextGLTest::isExtensionSupported, &ContextGLTest::isExtensionDisabled}); @@ -70,6 +76,16 @@ void ContextGLTest::isVersionSupported() { MAGNUM_ASSERT_VERSION_SUPPORTED(Version(Int(v)-1)); } +#ifndef MAGNUM_TARGET_GLES +void ContextGLTest::isVersionSupportedES() { + if(!Context::current().isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::ES2_compatibility::string() + std::string(" extension should not be supported, can't test")); + + /* No assertions should be fired */ + CORRADE_VERIFY(Context::current().isVersionSupported(Version::GLES200)); +} +#endif + void ContextGLTest::supportedVersion() { const Version v = Context::current().version(); diff --git a/src/Magnum/Test/VersionTest.cpp b/src/Magnum/Test/VersionTest.cpp index a2121dde9..2fe3e4e82 100644 --- a/src/Magnum/Test/VersionTest.cpp +++ b/src/Magnum/Test/VersionTest.cpp @@ -35,17 +35,32 @@ struct VersionTest: TestSuite::Tester { void fromNumber(); void toNumber(); + #ifndef MAGNUM_TARGET_GLES + void toNumberES(); + #endif + void isES(); void compare(); void debug(); + #ifndef MAGNUM_TARGET_GLES + void debugES(); + #endif }; VersionTest::VersionTest() { addTests({&VersionTest::fromNumber, &VersionTest::toNumber, + #ifndef MAGNUM_TARGET_GLES + &VersionTest::toNumberES, + #endif + &VersionTest::isES, &VersionTest::compare, - &VersionTest::debug}); + &VersionTest::debug, + #ifndef MAGNUM_TARGET_GLES + &VersionTest::debugES + #endif + }); } void VersionTest::fromNumber() { @@ -68,6 +83,16 @@ void VersionTest::toNumber() { #endif } +#ifndef MAGNUM_TARGET_GLES +void VersionTest::toNumberES() { + CORRADE_COMPARE(version(Version::GLES310), std::make_pair(3, 1)); +} +#endif + +void VersionTest::isES() { + CORRADE_VERIFY(isVersionES(Version::GLES200)); +} + void VersionTest::compare() { #ifndef MAGNUM_TARGET_GLES CORRADE_VERIFY(version(1, 1) < Version::GL210); @@ -92,6 +117,15 @@ void VersionTest::debug() { #endif } +#ifndef MAGNUM_TARGET_GLES +void VersionTest::debugES() { + std::ostringstream out; + + Debug{&out} << Version::GLES310; + CORRADE_COMPARE(out.str(), "OpenGL ES 3.1\n"); +} +#endif + }} CORRADE_TEST_MAIN(Magnum::Test::VersionTest) diff --git a/src/Magnum/Version.cpp b/src/Magnum/Version.cpp index be628069d..c0853dff7 100644 --- a/src/Magnum/Version.cpp +++ b/src/Magnum/Version.cpp @@ -46,7 +46,8 @@ Debug& operator<<(Debug& debug, Version value) { _c(GL430, "OpenGL 4.3") _c(GL440, "OpenGL 4.4") _c(GL450, "OpenGL 4.5") - #elif defined(MAGNUM_TARGET_WEBGL) + #endif + #ifdef MAGNUM_TARGET_WEBGL _c(GLES200, "WebGL 1.0") _c(GLES300, "WebGL 2.0") #else diff --git a/src/Magnum/Version.h b/src/Magnum/Version.h index 1cb6f62f2..936210a5c 100644 --- a/src/Magnum/Version.h +++ b/src/Magnum/Version.h @@ -36,6 +36,12 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES +namespace Implementation { + enum: Int { VersionESMask = 0x10000 }; +} +#endif + /** @brief OpenGL version @@ -60,12 +66,13 @@ enum class Version: Int { /** * @brief OpenGL ES 2.0 or WebGL 1.0, GLSL ES 1.00 * - * All the functionality is present in OpenGL 4.2 (extension - * @extension{ARB,ES2_compatibility}), so on desktop OpenGL this is - * equivalent to @ref Version::GL410. + * On desktop OpenGL, all related functionality is present in extension + * @extension{ARB,ES2_compatibility} (OpenGL 4.1), so testing for this + * version using @ref Context::isVersionSupported() is equivalent to + * testing for availability of that extension. */ #ifndef MAGNUM_TARGET_GLES - GLES200 = 410, + GLES200 = Implementation::VersionESMask|200, #else GLES200 = 200, #endif @@ -73,12 +80,13 @@ enum class Version: Int { /** * @brief OpenGL ES 3.0 or WebGL 2.0, GLSL ES 3.00 * - * All the functionality is present in OpenGL 4.3 (extension - * @extension{ARB,ES3_compatibility}), so on desktop OpenGL this is the - * equivalent to @ref Version::GL430. + * On desktop OpenGL, all related functionality is present in extension + * @extension{ARB,ES3_compatibility} (OpenGL 4.3), so testing for this + * version using @ref Context::isVersionSupported() is equivalent to + * testing for availability of that extension. */ #ifndef MAGNUM_TARGET_GLES - GLES300 = 430, + GLES300 = Implementation::VersionESMask|300, #else GLES300 = 300, #endif @@ -87,12 +95,13 @@ enum class Version: Int { /** * @brief OpenGL ES 3.1, GLSL ES 3.10 * - * All the functionality is present in OpenGL 4.5 (extension - * @extension{ARB,ES3_1_compatibility}), so on desktop OpenGL this is the - * equivalent to @ref Version::GL450. + * On desktop OpenGL, all related functionality is present in extension + * @extension{ARB,ES3_1_compatibility} (OpenGL 4.5), so testing for this + * version using @ref Context::isVersionSupported() is equivalent to + * testing for availability of that extension. */ #ifndef MAGNUM_TARGET_GLES - GLES310 = 450 + GLES310 = Implementation::VersionESMask|310, #else GLES310 = 310 #endif @@ -104,8 +113,27 @@ constexpr Version version(Int major, Int minor) { return Version(major*100 + minor*10); } +/** +@brief Major and minor version number from enum value + +@see @ref isVersionES() +*/ constexpr std::pair version(Version version) { - return {Int(version)/100, (Int(version)%100)/10}; + return {(Int(version) & ~Implementation::VersionESMask)/100, + ((Int(version) & ~Implementation::VersionESMask)%100)/10}; +} + +/** +@brief Whether given version is OpenGL ES or WebGL + +Always `true` on @ref MAGNUM_TARGET_GLES "OpenGL ES" and WebGL build. +*/ +constexpr bool isVersionES(Version version) { + #ifndef MAGNUM_TARGET_GLES + return Int(version) & Implementation::VersionESMask; + #else + return true; + #endif } /** @debugoperatorenum{Magnum::Version} */