Browse Source

Make the ES versions first-class on desktop OpenGL.

What this changes:

 * Before, a Version::GLES310 shader was created with `#version 450`
   directive, which is wrong, because an implementation might support
   GLES 3.1 but not GL 4.5 so this was not working and also the syntax
   is a bit different so this wasn't helpful at all.
 * Similarly, Context::isVersionSupported(Version::GLES310) was checking
   for support of OpenGL 4.5. Now it just checks for
   `ARB_ES3_1_compatibility` extension.
 * Added a small isVersionES() utility that just tells whether given
   version is ES or not.
pull/141/head
Vladimír Vondruš 10 years ago
parent
commit
5ff451791a
  1. 18
      src/Magnum/Context.cpp
  2. 4
      src/Magnum/Context.h
  3. 4
      src/Magnum/Shader.cpp
  4. 16
      src/Magnum/Test/ContextGLTest.cpp
  5. 36
      src/Magnum/Test/VersionTest.cpp
  6. 3
      src/Magnum/Version.cpp
  7. 54
      src/Magnum/Version.h

18
src/Magnum/Context.cpp

@ -377,13 +377,14 @@ const std::vector<Extension>& Extension::extensions(Version version) {
case Version::GL320: return extensions320; case Version::GL320: return extensions320;
case Version::GL330: return extensions330; case Version::GL330: return extensions330;
case Version::GL400: return extensions400; case Version::GL400: return extensions400;
/* case Version::GLES200: */
case Version::GL410: return extensions410; case Version::GL410: return extensions410;
case Version::GL420: return extensions420; case Version::GL420: return extensions420;
/* case Version::GLES300: */
case Version::GL430: return extensions430; case Version::GL430: return extensions430;
case Version::GL440: return extensions440; case Version::GL440: return extensions440;
case Version::GL450: return extensions450; case Version::GL450: return extensions450;
case Version::GLES200:
case Version::GLES300:
case Version::GLES310: return empty;
#else #else
case Version::GLES200: return empty; case Version::GLES200: return empty;
case Version::GLES300: case Version::GLES300:
@ -748,6 +749,19 @@ std::vector<std::string> Context::extensionStrings() const {
return extensions; return extensions;
} }
bool Context::isVersionSupported(Version version) const {
#ifndef MAGNUM_TARGET_GLES
if(version == Version::GLES200)
return isExtensionSupported<Extensions::GL::ARB::ES2_compatibility>();
if(version == Version::GLES300)
return isExtensionSupported<Extensions::GL::ARB::ES3_compatibility>();
if(version == Version::GLES310)
return isExtensionSupported<Extensions::GL::ARB::ES3_1_compatibility>();
#endif
return _version >= version;
}
Version Context::supportedVersion(std::initializer_list<Version> versions) const { Version Context::supportedVersion(std::initializer_list<Version> versions) const {
for(auto version: versions) for(auto version: versions)
if(isVersionSupported(version)) return version; if(isVersionSupported(version)) return version;

4
src/Magnum/Context.h

@ -362,9 +362,7 @@ class MAGNUM_EXPORT Context {
* *
* @see @ref supportedVersion(), @ref MAGNUM_ASSERT_VERSION_SUPPORTED() * @see @ref supportedVersion(), @ref MAGNUM_ASSERT_VERSION_SUPPORTED()
*/ */
bool isVersionSupported(Version version) const { bool isVersionSupported(Version version) const;
return _version >= version;
}
/** /**
* @brief Get supported OpenGL version * @brief Get supported OpenGL version

4
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::GL430: _sources.push_back("#version 430\n"); return;
case Version::GL440: _sources.push_back("#version 440\n"); return; case Version::GL440: _sources.push_back("#version 440\n"); return;
case Version::GL450: _sources.push_back("#version 450\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::GLES200: _sources.push_back("#version 100\n"); return;
case Version::GLES300: _sources.push_back("#version 300 es\n"); return; case Version::GLES300: _sources.push_back("#version 300 es\n"); return;
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
case Version::GLES310: _sources.push_back("#version 310 es\n"); return; case Version::GLES310: _sources.push_back("#version 310 es\n"); return;
#endif #endif
#endif
/* The user is responsible for (not) adding #version directive */ /* The user is responsible for (not) adding #version directive */
case Version::None: return; case Version::None: return;

16
src/Magnum/Test/ContextGLTest.cpp

@ -37,6 +37,9 @@ struct ContextGLTest: AbstractOpenGLTester {
void constructCopyMove(); void constructCopyMove();
void isVersionSupported(); void isVersionSupported();
#ifndef MAGNUM_TARGET_GLES
void isVersionSupportedES();
#endif
void supportedVersion(); void supportedVersion();
void isExtensionSupported(); void isExtensionSupported();
void isExtensionDisabled(); void isExtensionDisabled();
@ -46,6 +49,9 @@ ContextGLTest::ContextGLTest() {
addTests({&ContextGLTest::constructCopyMove, addTests({&ContextGLTest::constructCopyMove,
&ContextGLTest::isVersionSupported, &ContextGLTest::isVersionSupported,
#ifndef MAGNUM_TARGET_GLES
&ContextGLTest::isVersionSupportedES,
#endif
&ContextGLTest::supportedVersion, &ContextGLTest::supportedVersion,
&ContextGLTest::isExtensionSupported, &ContextGLTest::isExtensionSupported,
&ContextGLTest::isExtensionDisabled}); &ContextGLTest::isExtensionDisabled});
@ -70,6 +76,16 @@ void ContextGLTest::isVersionSupported() {
MAGNUM_ASSERT_VERSION_SUPPORTED(Version(Int(v)-1)); MAGNUM_ASSERT_VERSION_SUPPORTED(Version(Int(v)-1));
} }
#ifndef MAGNUM_TARGET_GLES
void ContextGLTest::isVersionSupportedES() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::ES2_compatibility>())
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() { void ContextGLTest::supportedVersion() {
const Version v = Context::current().version(); const Version v = Context::current().version();

36
src/Magnum/Test/VersionTest.cpp

@ -35,17 +35,32 @@ struct VersionTest: TestSuite::Tester {
void fromNumber(); void fromNumber();
void toNumber(); void toNumber();
#ifndef MAGNUM_TARGET_GLES
void toNumberES();
#endif
void isES();
void compare(); void compare();
void debug(); void debug();
#ifndef MAGNUM_TARGET_GLES
void debugES();
#endif
}; };
VersionTest::VersionTest() { VersionTest::VersionTest() {
addTests({&VersionTest::fromNumber, addTests({&VersionTest::fromNumber,
&VersionTest::toNumber, &VersionTest::toNumber,
#ifndef MAGNUM_TARGET_GLES
&VersionTest::toNumberES,
#endif
&VersionTest::isES,
&VersionTest::compare, &VersionTest::compare,
&VersionTest::debug}); &VersionTest::debug,
#ifndef MAGNUM_TARGET_GLES
&VersionTest::debugES
#endif
});
} }
void VersionTest::fromNumber() { void VersionTest::fromNumber() {
@ -68,6 +83,16 @@ void VersionTest::toNumber() {
#endif #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() { void VersionTest::compare() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
CORRADE_VERIFY(version(1, 1) < Version::GL210); CORRADE_VERIFY(version(1, 1) < Version::GL210);
@ -92,6 +117,15 @@ void VersionTest::debug() {
#endif #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) CORRADE_TEST_MAIN(Magnum::Test::VersionTest)

3
src/Magnum/Version.cpp

@ -46,7 +46,8 @@ Debug& operator<<(Debug& debug, Version value) {
_c(GL430, "OpenGL 4.3") _c(GL430, "OpenGL 4.3")
_c(GL440, "OpenGL 4.4") _c(GL440, "OpenGL 4.4")
_c(GL450, "OpenGL 4.5") _c(GL450, "OpenGL 4.5")
#elif defined(MAGNUM_TARGET_WEBGL) #endif
#ifdef MAGNUM_TARGET_WEBGL
_c(GLES200, "WebGL 1.0") _c(GLES200, "WebGL 1.0")
_c(GLES300, "WebGL 2.0") _c(GLES300, "WebGL 2.0")
#else #else

54
src/Magnum/Version.h

@ -36,6 +36,12 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
namespace Implementation {
enum: Int { VersionESMask = 0x10000 };
}
#endif
/** /**
@brief OpenGL version @brief OpenGL version
@ -60,12 +66,13 @@ enum class Version: Int {
/** /**
* @brief OpenGL ES 2.0 or WebGL 1.0, GLSL ES 1.00 * @brief OpenGL ES 2.0 or WebGL 1.0, GLSL ES 1.00
* *
* All the functionality is present in OpenGL 4.2 (extension * On desktop OpenGL, all related functionality is present in extension
* @extension{ARB,ES2_compatibility}), so on desktop OpenGL this is * @extension{ARB,ES2_compatibility} (OpenGL 4.1), so testing for this
* equivalent to @ref Version::GL410. * version using @ref Context::isVersionSupported() is equivalent to
* testing for availability of that extension.
*/ */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
GLES200 = 410, GLES200 = Implementation::VersionESMask|200,
#else #else
GLES200 = 200, GLES200 = 200,
#endif #endif
@ -73,12 +80,13 @@ enum class Version: Int {
/** /**
* @brief OpenGL ES 3.0 or WebGL 2.0, GLSL ES 3.00 * @brief OpenGL ES 3.0 or WebGL 2.0, GLSL ES 3.00
* *
* All the functionality is present in OpenGL 4.3 (extension * On desktop OpenGL, all related functionality is present in extension
* @extension{ARB,ES3_compatibility}), so on desktop OpenGL this is the * @extension{ARB,ES3_compatibility} (OpenGL 4.3), so testing for this
* equivalent to @ref Version::GL430. * version using @ref Context::isVersionSupported() is equivalent to
* testing for availability of that extension.
*/ */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
GLES300 = 430, GLES300 = Implementation::VersionESMask|300,
#else #else
GLES300 = 300, GLES300 = 300,
#endif #endif
@ -87,12 +95,13 @@ enum class Version: Int {
/** /**
* @brief OpenGL ES 3.1, GLSL ES 3.10 * @brief OpenGL ES 3.1, GLSL ES 3.10
* *
* All the functionality is present in OpenGL 4.5 (extension * On desktop OpenGL, all related functionality is present in extension
* @extension{ARB,ES3_1_compatibility}), so on desktop OpenGL this is the * @extension{ARB,ES3_1_compatibility} (OpenGL 4.5), so testing for this
* equivalent to @ref Version::GL450. * version using @ref Context::isVersionSupported() is equivalent to
* testing for availability of that extension.
*/ */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
GLES310 = 450 GLES310 = Implementation::VersionESMask|310,
#else #else
GLES310 = 310 GLES310 = 310
#endif #endif
@ -104,8 +113,27 @@ constexpr Version version(Int major, Int minor) {
return Version(major*100 + minor*10); return Version(major*100 + minor*10);
} }
/**
@brief Major and minor version number from enum value
@see @ref isVersionES()
*/
constexpr std::pair<Int, Int> version(Version version) { constexpr std::pair<Int, Int> 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} */ /** @debugoperatorenum{Magnum::Version} */

Loading…
Cancel
Save