diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 673ba7918..9eace912e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,8 +53,9 @@ Code contribution Contact ------- -* Website - http://mosra.cz/blog/magnum.php -* GitHub - https://github.com/mosra/magnum -* Twitter - https://twitter.com/czmosra -* E-mail - mosra@centrum.cz -* Jabber - mosra@jabbim.cz +* Website -- http://mosra.cz/blog/magnum.php +* GitHub -- https://github.com/mosra/magnum +* Google Groups -- https://groups.google.com/forum/#!forum/magnum-engine +* Twitter -- https://twitter.com/czmosra +* E-mail -- mosra@centrum.cz +* Jabber -- mosra@jabbim.cz diff --git a/README.md b/README.md index b789be059..8b17a853b 100644 --- a/README.md +++ b/README.md @@ -163,11 +163,12 @@ CONTACT Want to learn more about the library? Found a bug or want to tell me an awesome idea? Feel free to visit my website or contact me at: -* Website - http://mosra.cz/blog/magnum.php -* GitHub - https://github.com/mosra/magnum -* Twitter - https://twitter.com/czmosra -* E-mail - mosra@centrum.cz -* Jabber - mosra@jabbim.cz +* Website -- http://mosra.cz/blog/magnum.php +* GitHub -- https://github.com/mosra/magnum +* Google Groups -- https://groups.google.com/forum/#!forum/magnum-engine +* Twitter -- https://twitter.com/czmosra +* E-mail -- mosra@centrum.cz +* Jabber -- mosra@jabbim.cz LICENSE ======= diff --git a/doc/mainpage.dox b/doc/mainpage.dox index 4cea30e2d..46816d411 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -109,11 +109,12 @@ make the library as consistent and maintainable as possible. Feel free to get more information or contact the author at: -- Website - http://mosra.cz/blog/magnum.php -- GitHub - https://github.com/mosra/magnum -- Twitter - https://twitter.com/czmosra -- E-mail - mosra@centrum.cz -- Jabber - mosra@jabbim.cz +- Website -- http://mosra.cz/blog/magnum.php +- GitHub -- https://github.com/mosra/magnum +- Google Groups -- https://groups.google.com/forum/#!forum/magnum-engine +- Twitter -- https://twitter.com/czmosra +- E-mail -- mosra@centrum.cz +- Jabber -- mosra@jabbim.cz @section mainpage-license License diff --git a/package/archlinux/PKGBUILD-es2desktop b/package/archlinux/PKGBUILD-es2desktop index 7cc1d0562..bdceef969 100644 --- a/package/archlinux/PKGBUILD-es2desktop +++ b/package/archlinux/PKGBUILD-es2desktop @@ -22,6 +22,7 @@ build() { -DTARGET_GLES2=ON \ -DTARGET_DESKTOP_GLES=ON \ -DWITH_AUDIO=ON \ + -DWITH_SDL2APPLICATION=ON \ -DWITH_GLXAPPLICATION=ON \ -DWITH_WINDOWLESSGLXAPPLICATION=ON \ -DWITH_MAGNUMFONT=ON \ diff --git a/package/archlinux/PKGBUILD-es3desktop b/package/archlinux/PKGBUILD-es3desktop new file mode 100644 index 000000000..e47b3fdfc --- /dev/null +++ b/package/archlinux/PKGBUILD-es3desktop @@ -0,0 +1,47 @@ +# Author: mosra +pkgname=magnum +pkgver=dev.es3desktop +pkgrel=1 +pkgdesc="C++11 and OpenGL 2D/3D graphics engine (desktop OpenGL ES 3.0 version)" +arch=('i686' 'x86_64') +url="http://mosra.cz/blog/magnum.php" +license=('MIT') +depends=('corrade' 'openal') +makedepends=('cmake' 'ninja') +options=(!strip) +provides=('magnum-git') + +build() { + mkdir -p "$startdir/build-es3desktop" + cd "$startdir/build-es3desktop" + + cmake .. \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DTARGET_GLES=ON \ + -DTARGET_GLES2=OFF \ + -DTARGET_DESKTOP_GLES=ON \ + -DWITH_AUDIO=ON \ + -DWITH_SDL2APPLICATION=ON \ + -DWITH_GLXAPPLICATION=ON \ + -DWITH_WINDOWLESSGLXAPPLICATION=ON \ + -DWITH_MAGNUMFONT=ON \ + -DWITH_TGAIMAGECONVERTER=ON \ + -DWITH_TGAIMPORTER=ON \ + -DWITH_WAVAUDIOIMPORTER=ON \ + -DWITH_MAGNUMINFO=ON \ + -DBUILD_TESTS=ON \ + -DBUILD_GL_TESTS=ON \ + -G Ninja + ninja +} + +check() { + cd "$startdir/build-es3desktop" + ctest --output-on-failure +} + +package() { + cd "$startdir/build-es3desktop" + DESTDIR="$pkgdir/" ninja install +} diff --git a/package/ci/jenkins-gltests.xml b/package/ci/jenkins-gltests.xml index 239d14e4d..8285cb565 100644 --- a/package/ci/jenkins-gltests.xml +++ b/package/ci/jenkins-gltests.xml @@ -39,6 +39,14 @@ false Magnum-Compatibility + + gl + + desktop + es2desktop + es3desktop + + compiler @@ -65,15 +73,6 @@ deprecated - - gl - - desktop - es2 - es2desktop - es3 - - diff --git a/package/ci/jenkins.xml b/package/ci/jenkins.xml index dd3941a28..341505ca5 100644 --- a/package/ci/jenkins.xml +++ b/package/ci/jenkins.xml @@ -39,6 +39,16 @@ false Magnum-Compatibility + + gl + + desktop + es2 + es2desktop + es3 + es3desktop + + compiler @@ -65,15 +75,6 @@ deprecated - - gl - - desktop - es2 - es2desktop - es3 - - @@ -111,6 +112,10 @@ elif [ ${gl} = "es3" ] ; then gl_flags="-DTARGET_GLES=ON -DTARGET_GLES2=OFF" desktop_flag=OFF windowless_flag=OFF +elif [ ${gl} = "es3desktop" ] ; then + gl_flags="-DTARGET_GLES=ON -DTARGET_GLES2=OFF -DTARGET_DESKTOP_GLES=ON" + desktop_flag=OFF + windowless_flag=ON fi mkdir -p build-${compiler}-${libraries}-${compatibility}-${gl} diff --git a/src/AbstractObject.cpp b/src/AbstractObject.cpp index 6b5d9265b..74b2df9ba 100644 --- a/src/AbstractObject.cpp +++ b/src/AbstractObject.cpp @@ -26,6 +26,7 @@ #include +#include "Context.h" #include "Extensions.h" #include "Implementation/State.h" #include "Implementation/DebugState.h" diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index dd0fa3864..a3a150f1b 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -27,6 +27,7 @@ #include /* std::max(), needed by MSVC */ #include "Math/RectangularMatrix.h" +#include "Context.h" #include "Extensions.h" #include "Shader.h" #include "Implementation/DebugState.h" diff --git a/src/Buffer.h b/src/Buffer.h index 1667849ef..59f56c84b 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -322,7 +322,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Map buffer for reading only. * @requires_gl Only @ref Magnum::Buffer::MapAccess "MapAccess::WriteOnly" - * is available in OpenGL ES 2.0. + * is available in OpenGL ES. */ ReadOnly = GL_READ_ONLY, #endif @@ -336,7 +336,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject { /** * Map buffer for both reading and writing. * @requires_gl Only @ref Magnum::Buffer::MapAccess "MapAccess::WriteOnly" - * is available in OpenGL ES 2.0. + * is available in OpenGL ES. */ ReadWrite = GL_READ_WRITE #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a73a6d92b..7080f890a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -78,6 +78,7 @@ set(Magnum_SRCS Sampler.cpp Shader.cpp Timeline.cpp + Version.cpp Implementation/BufferState.cpp Implementation/DebugState.cpp @@ -146,6 +147,7 @@ set(Magnum_HEADERS TextureFormat.h Timeline.h Types.h + Version.h magnumVisibility.h) diff --git a/src/Context.cpp b/src/Context.cpp index 755df8ae2..8590432ac 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -45,33 +45,6 @@ namespace Magnum { -#ifndef DOXYGEN_GENERATING_OUTPUT -Debug operator<<(Debug debug, Version value) { - switch(value) { - #define _c(value, string) case Version::value: return debug << string; - _c(None, "None") - #ifndef MAGNUM_TARGET_GLES - _c(GL210, "OpenGL 2.1") - _c(GL300, "OpenGL 3.0") - _c(GL310, "OpenGL 3.1") - _c(GL320, "OpenGL 3.2") - _c(GL330, "OpenGL 3.3") - _c(GL400, "OpenGL 4.0") - _c(GL410, "OpenGL 4.1") - _c(GL420, "OpenGL 4.2") - _c(GL430, "OpenGL 4.3") - _c(GL440, "OpenGL 4.4") - #else - _c(GLES200, "OpenGL ES 2.0") - _c(GLES300, "OpenGL ES 3.0") - #endif - #undef _c - } - - return debug << "Invalid"; -} -#endif - const std::vector& Extension::extensions(Version version) { #define _extension(prefix, vendor, extension) \ {Extensions::prefix::vendor::extension::Index, Extensions::prefix::vendor::extension::requiredVersion(), Extensions::prefix::vendor::extension::coreVersion(), Extensions::prefix::vendor::extension::string()} @@ -322,6 +295,9 @@ Context::Context() { #endif _version = static_cast(_majorVersion*100+_minorVersion*10); + CORRADE_ASSERT(Renderer::error() == Renderer::Error::NoError, + "Context: cannot retrieve OpenGL version", ); + #ifndef MAGNUM_TARGET_GLES CORRADE_ASSERT(isVersionSupported(Version::GL210), "Context: unsupported OpenGL version" << Int(_version), ); #elif defined(MAGNUM_TARGET_GLES2) diff --git a/src/Context.h b/src/Context.h index fe59e0216..e6837c6bb 100644 --- a/src/Context.h +++ b/src/Context.h @@ -25,7 +25,7 @@ */ /** @file /Context.h - * @brief Class @ref Magnum::Context, @ref Magnum::Extension, enum @ref Magnum::Version, macro @ref MAGNUM_ASSERT_VERSION_SUPPORTED(), @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED() + * @brief Class @ref Magnum::Context, @ref Magnum::Extension, macro @ref MAGNUM_ASSERT_VERSION_SUPPORTED(), @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED() */ #include @@ -45,64 +45,6 @@ namespace Implementation { struct State; } -/** -@brief OpenGL version - -@see @ref Context, @ref MAGNUM_ASSERT_VERSION_SUPPORTED() -*/ -enum class Version: Int { - None = 0xFFFF, /**< @brief Unspecified */ - #ifndef MAGNUM_TARGET_GLES - GL210 = 210, /**< @brief OpenGL 2.1 / GLSL 1.20 */ - GL300 = 300, /**< @brief OpenGL 3.0 / GLSL 1.30 */ - GL310 = 310, /**< @brief OpenGL 3.1 / GLSL 1.40 */ - GL320 = 320, /**< @brief OpenGL 3.2 / GLSL 1.50 */ - GL330 = 330, /**< @brief OpenGL 3.3, GLSL 3.30 */ - GL400 = 400, /**< @brief OpenGL 4.0, GLSL 4.00 */ - GL410 = 410, /**< @brief OpenGL 4.1, GLSL 4.10 */ - GL420 = 420, /**< @brief OpenGL 4.2, GLSL 4.20 */ - GL430 = 430, /**< @brief OpenGL 4.3, GLSL 4.30 */ - GL440 = 440, /**< @brief OpenGL 4.4, GLSL 4.40 */ - #endif - - /** - * @brief OpenGL ES 2.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. - */ - #ifndef MAGNUM_TARGET_GLES - GLES200 = 410, - #else - GLES200 = 200, - #endif - - /** - * @brief OpenGL ES 3.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. - */ - #ifndef MAGNUM_TARGET_GLES - GLES300 = 430 - #else - GLES300 = 300 - #endif -}; - -#if defined(CORRADE_GCC44_COMPATIBILITY) && !defined(DOXYGEN_GENERATING_OUTPUT) -/* GCC 4.4 somehow doesn't have comparison operators for strongly-typed enums */ -inline bool operator<=(Version a, Version b) { return Int(a) <= Int(b); } -inline bool operator>=(Version a, Version b) { return Int(a) >= Int(b); } -inline bool operator<(Version a, Version b) { return Int(a) < Int(b); } -inline bool operator>(Version a, Version b) { return Int(a) > Int(b); } -#endif - -/** @debugoperator{Magnum::Context} */ -Debug MAGNUM_EXPORT operator<<(Debug debug, Version value); - /** @brief Run-time information about OpenGL extension diff --git a/src/Extensions.h b/src/Extensions.h index 4ae0faf3e..a9df50b48 100644 --- a/src/Extensions.h +++ b/src/Extensions.h @@ -28,7 +28,7 @@ * @brief Namespace Magnum::Extensions */ -#include "Context.h" +#include "Version.h" namespace Magnum { diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 533796605..959ed0543 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -241,33 +241,47 @@ void Mesh::vertexAttribPointer(const LongAttribute& attribute) { #endif void Mesh::initializeContextBasedFunctionality(Context& context) { - /** @todo VAOs are in ES 3.0 and as extension in ES 2.0, enable them when some extension wrangler is available */ + /** @todo Enable when some extension wrangler is available in ES 2.0 */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) + #elif defined(MAGNUM_TARGET_GLES2) + if(context.isExtensionSupported()) + #else + static_cast(context); + #endif + { + #ifndef MAGNUM_TARGET_GLES Debug() << "Mesh: using" << Extensions::GL::APPLE::vertex_array_object::string() << "features"; + #elif defined(MAGNUM_TARGET_GLES2) + Debug() << "Mesh: using" << Extensions::GL::OES::vertex_array_object::string() << "features"; + #endif createImplementation = &Mesh::createImplementationVAO; destroyImplementation = &Mesh::destroyImplementationVAO; + #ifndef MAGNUM_TARGET_GLES if(context.isExtensionSupported()) { Debug() << "Mesh: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; attributePointerImplementation = &Mesh::attributePointerImplementationDSA; attributeIPointerImplementation = &Mesh::attributePointerImplementationDSA; attributeLPointerImplementation = &Mesh::attributePointerImplementationDSA; - } else { + } else + #endif + { attributePointerImplementation = &Mesh::attributePointerImplementationVAO; + #ifndef MAGNUM_TARGET_GLES2 attributeIPointerImplementation = &Mesh::attributePointerImplementationVAO; + #ifndef MAGNUM_TARGET_GLES attributeLPointerImplementation = &Mesh::attributePointerImplementationVAO; + #endif + #endif } bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationVAO; bindImplementation = &Mesh::bindImplementationVAO; unbindImplementation = &Mesh::unbindImplementationVAO; } - #else - static_cast(context); - #endif } void Mesh::createImplementationDefault() { _id = 0; } diff --git a/src/MeshTools/FullScreenTriangle.cpp b/src/MeshTools/FullScreenTriangle.cpp index 80d7ca37f..14ba470d1 100644 --- a/src/MeshTools/FullScreenTriangle.cpp +++ b/src/MeshTools/FullScreenTriangle.cpp @@ -29,6 +29,7 @@ #include "Buffer.h" #include "Context.h" #include "Mesh.h" +#include "Version.h" namespace Magnum { namespace MeshTools { diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index cdbbb58fc..f6944bb1f 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -38,14 +38,14 @@ namespace Magnum { namespace Platform { /** @todo Delegating constructor when support for GCC 4.6 is dropped */ -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, const Configuration& configuration): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { +AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, const Configuration& configuration): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { createContext(configuration); } #ifndef CORRADE_GCC45_COMPATIBILITY -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, std::nullptr_t) +AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, std::nullptr_t) #else -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, void*) +AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, void*) #endif : contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {} @@ -93,7 +93,7 @@ bool AbstractXApplication::tryCreateContext(const Configuration& configuration) XSetWMProtocols(display, window, &deleteWindow, 1); /* Create context */ - contextHandler->createContext(window); + contextHandler->createContext(configuration, window); /* Capture exposure, keyboard and mouse button events */ XSelectInput(display, window, INPUT_MASK); diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index f413ba6b7..46e03dc39 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -48,7 +48,7 @@ class Context; namespace Platform { namespace Implementation { - template class AbstractContextHandler; + template class AbstractContextHandler; } /** @nosubgrouping @@ -160,12 +160,12 @@ class AbstractXApplication { #else protected: #endif - explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, const Configuration& configuration); + explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, const Configuration& configuration); #ifndef CORRADE_GCC45_COMPATIBILITY - explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, std::nullptr_t); + explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, std::nullptr_t); #else - explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, void*); + explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, void*); #endif private: @@ -181,7 +181,7 @@ class AbstractXApplication { Window window; Atom deleteWindow; - Implementation::AbstractContextHandler* contextHandler; + Implementation::AbstractContextHandler* contextHandler; Context* c; @@ -220,23 +220,28 @@ class AbstractXApplication::Configuration { return *this; } - /** @brief Window size */ + /** @copydoc GlutApplication::Configuration::size() */ Vector2i size() const { return _size; } - /** - * @brief Set window size - * @return Reference to self (for method chaining) - * - * Default is `{800, 600}`. - */ + /** @copydoc GlutApplication::Configuration::setSize() */ Configuration& setSize(const Vector2i& size) { _size = size; return *this; } + /** @copydoc GlutApplication::Configuration::version() */ + Version version() const { return _version; } + + /** @copydoc GlutApplication::Configuration::setVersion() */ + Configuration& setVersion(Version version) { + _version = version; + return *this; + } + private: std::string _title; Vector2i _size; + Version _version; }; /** diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 6ae5e0084..c4bad545b 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -24,7 +24,10 @@ #include "GlutApplication.h" +#include + #include "Context.h" +#include "Version.h" #include "Platform/ScreenedApplication.hpp" @@ -81,6 +84,18 @@ bool GlutApplication::tryCreateContext(const Configuration& configuration) { glutInitDisplayMode(flags); glutInitWindowSize(configuration.size().x(), configuration.size().y()); + + /* Set context version, if requested */ + if(configuration.version() != Version::None) { + Int major, minor; + std::tie(major, minor) = version(configuration.version()); + glutInitContextVersion(major, minor); + #ifndef MAGNUM_TARGET_GLES + if(configuration.version() >= Version::GL310) + glutInitContextProfile(GLUT_CORE_PROFILE); + #endif + } + if(!glutCreateWindow(configuration.title().data())) { Error() << "Platform::GlutApplication::tryCreateContext(): cannot create context"; return false; diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 7b776f60c..acf8cd526 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -294,6 +294,22 @@ class GlutApplication::Configuration { return *this; } + /** @brief Context version */ + Version version() const { return _version; } + + /** + * @brief Set context version + * + * If requesting version greater or equal to OpenGL 3.1, core profile + * is used. The created context will then have any version which is + * backwards-compatible with requested one. Default is + * @ref Version::None, i.e. any provided version is used. + */ + Configuration& setVersion(Version version) { + _version = version; + return *this; + } + /** @brief Sample count */ Int sampleCount() const { return _sampleCount; } @@ -314,6 +330,7 @@ class GlutApplication::Configuration { std::string _title; Vector2i _size; Int _sampleCount; + Version _version; }; /** diff --git a/src/Platform/Implementation/AbstractContextHandler.h b/src/Platform/Implementation/AbstractContextHandler.h index 3c279c003..964434424 100644 --- a/src/Platform/Implementation/AbstractContextHandler.h +++ b/src/Platform/Implementation/AbstractContextHandler.h @@ -31,7 +31,7 @@ namespace Magnum { namespace Platform { namespace Implementation { @todo GLX_MESA_query_renderer, EGL_MESA_query_renderer */ -template class AbstractContextHandler { +template class AbstractContextHandler { public: /** * @brief Get visual ID @@ -50,7 +50,7 @@ template class AbstractContextHandl virtual ~AbstractContextHandler() {} /** @brief Create context */ - virtual void createContext(Window nativeWindow) = 0; + virtual void createContext(const Configuration& configuration, Window nativeWindow) = 0; /** @brief Make the context current */ virtual void makeCurrent() = 0; @@ -59,7 +59,7 @@ template class AbstractContextHandl virtual void swapBuffers() = 0; }; -template inline AbstractContextHandler::AbstractContextHandler() = default; +template inline AbstractContextHandler::AbstractContextHandler() = default; }}} diff --git a/src/Platform/Implementation/EglContextHandler.cpp b/src/Platform/Implementation/EglContextHandler.cpp index ed7d523a0..121af16f8 100644 --- a/src/Platform/Implementation/EglContextHandler.cpp +++ b/src/Platform/Implementation/EglContextHandler.cpp @@ -24,9 +24,12 @@ #include "EglContextHandler.h" +#include +#include #include #include "Context.h" +#include "Version.h" namespace Magnum { namespace Platform { namespace Implementation { @@ -62,8 +65,12 @@ VisualId EglContextHandler::getVisualId(EGLNativeDisplayType nativeDisplay) { EGL_DEPTH_SIZE, 1, #ifndef MAGNUM_TARGET_GLES EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - #else + #elif defined(MAGNUM_TARGET_GLES3) + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + #elif defined(MAGNUM_TARGET_GLES2) EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + #else + #error Unsupported OpenGL edition #endif EGL_NONE }; @@ -88,14 +95,51 @@ VisualId EglContextHandler::getVisualId(EGLNativeDisplayType nativeDisplay) { return visualId; } -void EglContextHandler::createContext(EGLNativeWindowType window) { - static const EGLint contextAttributes[] = { - #ifdef MAGNUM_TARGET_GLES - EGL_CONTEXT_CLIENT_VERSION, 2, - #endif +void EglContextHandler::createContext(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType window) { + EGLint attributes[] = { + /* Leave some space for optional attributes below */ + EGL_NONE, EGL_NONE, + EGL_NONE, EGL_NONE, + EGL_NONE, EGL_NONE, + EGL_NONE }; - if(!eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes)) { + + /* Set context version, if requested. On desktop needs + EGL_KHR_create_context. */ + /** @todo Test for presence of EGL_KHR_create_context extension */ + if(configuration.version() != Version::None) { + Int major, minor; + std::tie(major, minor) = version(configuration.version()); + + attributes[0] = EGL_CONTEXT_MAJOR_VERSION_KHR; + attributes[1] = major; + attributes[2] = EGL_CONTEXT_MINOR_VERSION_KHR; + attributes[3] = minor; + + #ifndef MAGNUM_TARGET_GLES + if(configuration.version() >= Version::GL310) { + attributes[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; + attributes[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; + } + #endif + } + + /* We need this to run ES (default is desktop GL) */ + #ifdef MAGNUM_TARGET_GLES + else { + attributes[0] = EGL_CONTEXT_CLIENT_VERSION; + #ifdef MAGNUM_TARGET_GLES3 + attributes[1] = 3; + #elif defined(MAGNUM_TARGET_GLES2) + attributes[1] = 2; + #else + #error Unsupported OpenGL ES version + #endif + } + #endif + + if(!eglCreateContext(display, config, EGL_NO_CONTEXT, attributes)) { Error() << "Cannot create EGL context:" << errorString(eglGetError()); std::exit(1); } diff --git a/src/Platform/Implementation/EglContextHandler.h b/src/Platform/Implementation/EglContextHandler.h index 32cc2da94..94724da66 100644 --- a/src/Platform/Implementation/EglContextHandler.h +++ b/src/Platform/Implementation/EglContextHandler.h @@ -34,7 +34,8 @@ /* undef Xlib nonsense to avoid conflicts */ #undef None -#include "AbstractContextHandler.h" +#include "Platform/AbstractXApplication.h" +#include "Platform/Implementation/AbstractContextHandler.h" #include "corradeCompatibility.h" @@ -54,13 +55,13 @@ typedef EGLInt VisualId; Used in XEglApplication. */ -class EglContextHandler: public AbstractContextHandler { +class EglContextHandler: public AbstractContextHandler { public: explicit EglContextHandler() = default; ~EglContextHandler(); VisualId getVisualId(EGLNativeDisplayType nativeDisplay) override; - void createContext(EGLNativeWindowType nativeWindow) override; + void createContext(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType nativeWindow) override; void makeCurrent() override { eglMakeCurrent(display, surface, surface, context); diff --git a/src/Platform/Implementation/GlxContextHandler.cpp b/src/Platform/Implementation/GlxContextHandler.cpp index dc80b6c7e..bc90befc3 100644 --- a/src/Platform/Implementation/GlxContextHandler.cpp +++ b/src/Platform/Implementation/GlxContextHandler.cpp @@ -25,12 +25,12 @@ #include "GlxContextHandler.h" #include +#include #include #include #include "Context.h" - -#define None 0L // redef Xlib nonsense +#include "Version.h" namespace Magnum { namespace Platform { namespace Implementation { @@ -71,18 +71,57 @@ VisualID GlxContextHandler::getVisualId(Display* nativeDisplay) { return visualId; } -void GlxContextHandler::createContext(Window nativeWindow) { +void GlxContextHandler::createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) { window = nativeWindow; GLint attributes[] = { - #ifdef MAGNUM_TARGET_GLES - GLX_CONTEXT_MAJOR_VERSION_ARB, 2, - GLX_CONTEXT_MINOR_VERSION_ARB, 0, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, - #endif + /* Leave some space for optional attributes below */ + 0, 0, + 0, 0, + 0, 0, + 0 }; + /* Set context version, if requested */ + if(configuration.version() != Version::None) { + Int major, minor; + std::tie(major, minor) = version(configuration.version()); + + attributes[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; + attributes[1] = major; + attributes[2] = GLX_CONTEXT_MINOR_VERSION_ARB; + attributes[3] = minor; + + #ifndef MAGNUM_TARGET_GLES + if(configuration.version() >= Version::GL310) { + attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB; + attributes[5] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + #else + attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB; + attributes[5] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + #endif + } + + /* We need this to run ES (default is desktop GL) */ + #ifdef MAGNUM_TARGET_GLES + else { + attributes[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; + #ifdef MAGNUM_TARGET_GLES3 + attributes[1] = 3; + #elif defined(MAGNUM_TARGET_GLES2) + attributes[1] = 2; + #else + #error Unsupported OpenGL ES version + #endif + attributes[2] = GLX_CONTEXT_MINOR_VERSION_ARB; + attributes[3] = 0; + attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB; + attributes[5] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + } + #endif + /** @todo Use some extension wrangler for this, not GLEW, as it apparently needs context to create context, yo dawg wtf. */ PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); context = glXCreateContextAttribsARB(display, configs[0], nullptr, True, attributes); @@ -94,7 +133,7 @@ void GlxContextHandler::createContext(Window nativeWindow) { } GlxContextHandler::~GlxContextHandler() { - glXMakeCurrent(display, None, nullptr); + glXMakeCurrent(display, 0, nullptr); glXDestroyContext(display, context); } diff --git a/src/Platform/Implementation/GlxContextHandler.h b/src/Platform/Implementation/GlxContextHandler.h index 3678350b6..036c19e07 100644 --- a/src/Platform/Implementation/GlxContextHandler.h +++ b/src/Platform/Implementation/GlxContextHandler.h @@ -31,7 +31,8 @@ #undef None #undef Always -#include "AbstractContextHandler.h" +#include "Platform/AbstractXApplication.h" +#include "Platform/Implementation/AbstractContextHandler.h" #include "corradeCompatibility.h" @@ -43,13 +44,13 @@ namespace Magnum { namespace Platform { namespace Implementation { Creates OpenGL or OpenGL ES 2.0 context, if targeting OpenGL ES. Used in GlxApplication. */ -class GlxContextHandler: public AbstractContextHandler { +class GlxContextHandler: public AbstractContextHandler { public: explicit GlxContextHandler(); ~GlxContextHandler(); VisualID getVisualId(Display* nativeDisplay) override; - void createContext(Window nativeWindow) override; + void createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) override; void makeCurrent() override { glXMakeCurrent(display, window, context); diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index ef607fa54..24668163c 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -373,6 +373,15 @@ class NaClApplication::Configuration { return *this; } + /** + * @brief Set context version + * + * @note This function does nothing and is included only for + * compatibility with other toolkits. @ref Version::GLES200 is + * always used. + */ + Configuration& setVersion(Version) { return *this; } + /** @brief Sample count */ Int sampleCount() const { return _sampleCount; } diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 1999c7ee7..9429c839a 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -24,11 +24,14 @@ #include "Sdl2Application.h" -#ifdef CORRADE_TARGET_EMSCRIPTEN +#ifndef CORRADE_TARGET_EMSCRIPTEN +#include +#else #include #endif #include "Context.h" +#include "Version.h" #include "Platform/ScreenedApplication.hpp" namespace Magnum { namespace Platform { @@ -117,23 +120,60 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { /** @todo Remove when Emscripten has proper SDL2 support */ #ifndef CORRADE_TARGET_EMSCRIPTEN + /* Set context version, if requested */ + if(configuration.version() != Version::None) { + Int major, minor; + std::tie(major, minor) = version(configuration.version()); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor); + + #ifndef MAGNUM_TARGET_GLES + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, configuration.version() >= Version::GL310 ? + SDL_GL_CONTEXT_PROFILE_CORE : SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + #else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + #endif + } - #ifdef __APPLE__ + #ifdef MAGNUM_TARGET_GLES + else { + #ifdef MAGNUM_TARGET_GLES3 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + #elif defined(MAGNUM_TARGET_GLES2) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + #else + #error Unsupported OpenGL ES version + #endif + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + } - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + /* On OS X we need to create 3.2 context, as the default (2.1) contains + compatibility features which are not implemented for newer GL versions + in Apple's GL drivers, thus we would be forever stuck on 2.1 without the + new features. In practice SDL fails to create 2.1 context on recent OS X + versions. */ + #elif defined(__APPLE__) + else { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + } + #endif if(!(window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration.size().x(), configuration.size().y(), - SDL_WINDOW_OPENGL|flags))){ - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create core window:" << SDL_GetError(); - return false; + SDL_WINDOW_OPENGL|flags))) + { + Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); + return false; } + /* Fall back to GL 2.1, if 3.2 context creation fails on OS X */ + #ifdef __APPLE__ if(!(context = SDL_GL_CreateContext(window))){ - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:" << SDL_GetError() << " falling back to compatibility context."; + Warning() << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:" << SDL_GetError() << "(falling back to compatibility context)"; SDL_DestroyWindow(window); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); @@ -143,9 +183,10 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { if(!(window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration.size().x(), configuration.size().y(), - SDL_WINDOW_OPENGL|flags))){ - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); - return false; + SDL_WINDOW_OPENGL|flags))) + { + Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); + return false; } if(!(context = SDL_GL_CreateContext(window))){ @@ -155,16 +196,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { return false; } } - #else - if(!(window = SDL_CreateWindow(configuration.title().data(), - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - configuration.size().x(), configuration.size().y(), - SDL_WINDOW_OPENGL|flags))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); - return false; - } - if(!(context = SDL_GL_CreateContext(window))) { Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create context:" << SDL_GetError(); SDL_DestroyWindow(window); @@ -302,7 +334,7 @@ Sdl2Application::Configuration::Configuration(): #ifndef CORRADE_TARGET_EMSCRIPTEN _title("Magnum SDL2 Application"), #endif - _size(800, 600), _flags(Flag::Resizable), _sampleCount(0) {} + _size(800, 600), _flags(Flag::Resizable), _sampleCount(0), _version(Version::None) {} Sdl2Application::Configuration::~Configuration() = default; diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 0b839c18c..fc10169ac 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -54,12 +54,13 @@ namespace Platform { Application using [Simple DirectMedia Layer](http://www.libsdl.org/) toolkit. Supports keyboard and mouse handling. -This application library is available on desktop OpenGL (Linux, Windows, OS X) -and in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". It depends on **SDL2** -library (Emscripten has it built in) and is built if `WITH_SDL2APPLICATION` is -enabled in CMake. To use it, you need to copy `FindSDL2.cmake` from `modules/` -directory in %Magnum source to `modules/` dir in your project (so CMake is able -to find SDL2), request `%Sdl2Application` component in CMake, add +This application library is in theory available for all platforms for which +SDL2 is ported (thus also @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten", but not +@ref CORRADE_TARGET_NACL "NaCl"). It depends on **SDL2** library (Emscripten +has it built in) and is built if `WITH_SDL2APPLICATION` is enabled in CMake. To +use it, you need to copy `FindSDL2.cmake` from `modules/` directory in %Magnum +source to `modules/` dir in your project (so CMake is able to find SDL2), +request `%Sdl2Application` component in CMake, add `${MAGNUM_SDL2APPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_SDL2APPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and @@ -401,7 +402,7 @@ class Sdl2Application::Configuration { /** * @brief Window title * - * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN. + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". */ std::string title() const { return _title; } #endif @@ -452,6 +453,34 @@ class Sdl2Application::Configuration { return *this; } + #ifndef CORRADE_TARGET_EMSCRIPTEN + /** + * @brief Context version + * + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + Version version() const { return _version; } + #endif + + /** + * @brief Set context version + * + * If requesting version greater or equal to OpenGL 3.1, core profile + * is used. The created context will then have any version which is + * backwards-compatible with requested one. Default is + * @ref Version::None, i.e. any provided version is used. + * @note In @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" this function + * does nothing (@ref Version::GLES200 is always used). + */ + Configuration& setVersion(Version version) { + #ifndef CORRADE_TARGET_EMSCRIPTEN + _version = version; + #else + static_cast(version); + #endif + return *this; + } + /** @brief Sample count */ Int sampleCount() const { return _sampleCount; } @@ -474,6 +503,7 @@ class Sdl2Application::Configuration { Vector2i _size; Flags _flags; Int _sampleCount; + Version _version; }; CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::Flags) diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index a1144e6ac..e95d28032 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -82,7 +82,13 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { GLint contextAttributes[] = { #ifdef MAGNUM_TARGET_GLES + #ifdef MAGNUM_TARGET_GLES3 + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + #elif defined(MAGNUM_TARGET_GLES2) GLX_CONTEXT_MAJOR_VERSION_ARB, 2, + #else + #error Unsupported OpenGL ES version + #endif GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, #endif diff --git a/src/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index deb10c8a7..0bd047c90 100644 --- a/src/Platform/magnum-info.cpp +++ b/src/Platform/magnum-info.cpp @@ -332,28 +332,44 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat } #endif + /** @todo Somehow sort the following into previous list for ES3 */ + #ifndef MAGNUM_TARGET_GLES2 - if(c->isExtensionSupported()) { + #ifndef MAGNUM_TARGET_GLES + if(c->isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES _h(ARB::uniform_buffer_object) + #endif _l(Shader::maxUniformBlocks(Shader::Type::Vertex)) + #ifndef MAGNUM_TARGET_GLES _l(Shader::maxUniformBlocks(Shader::Type::TessellationControl)) _l(Shader::maxUniformBlocks(Shader::Type::TessellationEvaluation)) _l(Shader::maxUniformBlocks(Shader::Type::Geometry)) _l(Shader::maxUniformBlocks(Shader::Type::Compute)) + #endif _l(Shader::maxUniformBlocks(Shader::Type::Fragment)) _l(Shader::maxCombinedUniformBlocks()) _l(Shader::maxCombinedUniformComponents(Shader::Type::Vertex)) + #ifndef MAGNUM_TARGET_GLES _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationControl)) _l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationEvaluation)) _l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry)) _l(Shader::maxCombinedUniformComponents(Shader::Type::Compute)) + #endif _l(Shader::maxCombinedUniformComponents(Shader::Type::Fragment)) _l(AbstractShaderProgram::maxUniformBlockSize()) } - if(c->isExtensionSupported()) { + #ifndef MAGNUM_TARGET_GLES + if(c->isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES _h(EXT::gpu_shader4) + #endif _l(Buffer::maxUniformBindings()) _l(AbstractShaderProgram::minTexelOffset()) diff --git a/src/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index 9dd217025..c58cb02df 100644 --- a/src/Primitives/CMakeLists.txt +++ b/src/Primitives/CMakeLists.txt @@ -54,7 +54,7 @@ set(MagnumPrimitives_HEADERS add_library(MagnumPrimitives ${SHARED_OR_STATIC} ${MagnumPrimitives_SRCS}) if(BUILD_STATIC_PIC) # TODO: CMake 2.8.9 has this as POSITION_INDEPENDENT_CODE property - set_target_properties(Magnum PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + set_target_properties(MagnumPrimitives PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") endif() target_link_libraries(MagnumPrimitives Magnum) diff --git a/src/Query.h b/src/Query.h index 8becdf1ec..3e97e4e6c 100644 --- a/src/Query.h +++ b/src/Query.h @@ -25,7 +25,7 @@ */ /** @file - * @brief Class Magnum::AbstractQuery, Magnum::PrimitiveQuery, Magnum::SampleQuery, Magnum::TimeQuery + * @brief Class @ref Magnum::AbstractQuery, @ref Magnum::PrimitiveQuery, @ref Magnum::SampleQuery, @ref Magnum::TimeQuery */ #include @@ -38,10 +38,9 @@ namespace Magnum { /** @brief Base class for queries -See PrimitiveQuery, SampleQuery and TimeQuery documentation for more -information. +See @ref PrimitiveQuery, @ref SampleQuery and @ref TimeQuery documentation for +more information. @todo Support for AMD's query buffer (@extension{AMD,query_buffer_object}) -@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean} */ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { public: @@ -101,9 +100,9 @@ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { * Note that this function is blocking until the result is available. * See resultAvailable(). * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT} - * @requires_gl33 %Extension @extension{ARB,timer_query} (result type - * @ref Magnum::UnsignedInt "UnsignedInt" and @ref Magnum::Long - * "Long") + * @requires_gl33 %Extension @extension{ARB,timer_query} for result + * type @ref Magnum::UnsignedInt "UnsignedInt" and @ref Magnum::Long + * "Long" * @requires_es_extension %Extension @es_extension{EXT,disjoint_timer_query} * for result types @ref Magnum::Int "Int", @ref Magnum::UnsignedLong "UnsignedLong" * @ref Magnum::Long "Long". @@ -113,7 +112,7 @@ class MAGNUM_EXPORT AbstractQuery: public AbstractObject { /** * @brief End query * - * The result can be then retrieved by calling result(). + * The result can be then retrieved by calling @ref result(). * @see @fn_gl{EndQuery} */ void end(); @@ -158,9 +157,9 @@ template<> Long MAGNUM_EXPORT AbstractQuery::result(); Queries count of generated primitives from vertex shader, geometry shader or transform feedback and elapsed time. Example usage: @code -Query q; +PrimitiveQuery q; -q.begin(Query::Target::PrimitivesGenerated); +q.begin(PrimitiveQuery::Target::PrimitivesGenerated); // rendering... q.end(); @@ -198,7 +197,7 @@ class PrimitiveQuery: public AbstractQuery { /** * @brief Begin query * - * Begins counting of given @p target until end() is called. + * Begins counting of given @p target until @ref end() is called. * @see @fn_gl{BeginQuery} */ void begin(Target target) { @@ -369,10 +368,10 @@ query either duration of sequence of commands or absolute timestamp. Example usage of both methods: @code TimeQuery q1, q2; -q1.begin(Query::Target::TimeElapsed); +q1.begin(TimeQuery::Target::TimeElapsed); // rendering... q1.end(); -q2.begin(Query::Target::TimeElapsed); +q2.begin(TimeQuery::Target::TimeElapsed); // another rendering... q2.end(); UnsignedInt timeElapsed1 = q1.result(); diff --git a/src/Shader.cpp b/src/Shader.cpp index 82bfe5e54..8e7480472 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -30,6 +30,7 @@ #include #include +#include "Context.h" #include "Extensions.h" #include "Implementation/DebugState.h" #include "Implementation/State.h" diff --git a/src/Shader.h b/src/Shader.h index 6764fde00..57680b960 100644 --- a/src/Shader.h +++ b/src/Shader.h @@ -32,8 +32,7 @@ #include #include "AbstractObject.h" -#include "Context.h" - +#include "Magnum.h" #include "magnumVisibility.h" namespace Magnum { diff --git a/src/Shaders/Flat.cpp b/src/Shaders/Flat.cpp index d0b12c383..f552058e0 100644 --- a/src/Shaders/Flat.cpp +++ b/src/Shaders/Flat.cpp @@ -26,6 +26,7 @@ #include +#include "Context.h" #include "Extensions.h" #include "Shader.h" diff --git a/src/Shaders/MeshVisualizer.frag b/src/Shaders/MeshVisualizer.frag index 981b30a8b..a3adfcc03 100644 --- a/src/Shaders/MeshVisualizer.frag +++ b/src/Shaders/MeshVisualizer.frag @@ -60,10 +60,12 @@ in lowp vec3 barycentric; #endif #ifdef NEW_GLSL -out vec4 fragmentColor; +out lowp vec4 fragmentColor; #endif -#if defined(WIREFRAME_RENDERING) && defined(GL_ES) && __VERSION__ < 300 +/* This is needed also on desktop ES 3.0 emulation on NVidia 330.20 even though + fwidth() is part of GLSL ES 3.0 */ +#if defined(WIREFRAME_RENDERING) && defined(GL_ES) #extension GL_OES_standard_derivatives : enable #endif diff --git a/src/Shaders/Phong.cpp b/src/Shaders/Phong.cpp index c352fc98a..78f0f844f 100644 --- a/src/Shaders/Phong.cpp +++ b/src/Shaders/Phong.cpp @@ -26,6 +26,7 @@ #include +#include "Context.h" #include "Extensions.h" #include "Shader.h" diff --git a/src/Shaders/VertexColor.cpp b/src/Shaders/VertexColor.cpp index 6d2e8c924..b65b5991b 100644 --- a/src/Shaders/VertexColor.cpp +++ b/src/Shaders/VertexColor.cpp @@ -26,6 +26,7 @@ #include +#include "Context.h" #include "Extensions.h" #include "Shader.h" diff --git a/src/Test/BufferGLTest.cpp b/src/Test/BufferGLTest.cpp index a5718eab2..92b8a0c34 100644 --- a/src/Test/BufferGLTest.cpp +++ b/src/Test/BufferGLTest.cpp @@ -197,7 +197,7 @@ void BufferGLTest::data() { } void BufferGLTest::map() { - #ifdef MAGNUM_TARGET_GLES2 + #ifdef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::OES::mapbuffer::string() + std::string(" is not supported")); #endif @@ -206,7 +206,7 @@ void BufferGLTest::map() { constexpr char data[] = {2, 7, 5, 13, 25}; buffer.setData(data, BufferUsage::StaticDraw); - #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES char* contents = reinterpret_cast(buffer.map(Buffer::MapAccess::ReadWrite)); #else char* contents = reinterpret_cast(buffer.map(Buffer::MapAccess::WriteOnly)); @@ -254,10 +254,10 @@ void BufferGLTest::mapSub() { #endif void BufferGLTest::mapRange() { - #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::map_buffer_range::string() + std::string(" is not supported")); - #else + #elif defined(MAGNUM_TARGET_GLES2) if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::map_buffer_range::string() + std::string(" is not supported")); #endif @@ -285,10 +285,10 @@ void BufferGLTest::mapRange() { } void BufferGLTest::mapRangeExplicitFlush() { - #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::map_buffer_range::string() + std::string(" is not supported")); - #else + #elif defined(MAGNUM_TARGET_GLES2) if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::map_buffer_range::string() + std::string(" is not supported")); #endif diff --git a/src/Test/BufferImageGLTest.cpp b/src/Test/BufferImageGLTest.cpp index ff01edf04..815aeb1c4 100644 --- a/src/Test/BufferImageGLTest.cpp +++ b/src/Test/BufferImageGLTest.cpp @@ -52,16 +52,23 @@ BufferImageTest::BufferImageTest() { void BufferImageTest::construct() { const unsigned char data[] = { 'a', 'b', 'c' }; BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw); + + #ifndef MAGNUM_TARGET_GLES const auto imageData = a.buffer().data(); + #endif MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(a.format(), ColorFormat::Red); CORRADE_COMPARE(a.type(), ColorType::UnsignedByte); CORRADE_COMPARE(a.size(), Vector2i(1, 3)); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), std::vector(data, data + 3), TestSuite::Compare::Container); + #endif } void BufferImageTest::constructCopy() { @@ -113,16 +120,23 @@ void BufferImageTest::setData() { const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 }; a.setData(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 1}, data2, BufferUsage::StaticDraw); + + #ifndef MAGNUM_TARGET_GLES const auto imageData = a.buffer().data(); + #endif MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(a.format(), ColorFormat::RGBA); CORRADE_COMPARE(a.type(), ColorType::UnsignedShort); CORRADE_COMPARE(a.size(), Vector2i(2, 1)); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), std::vector(data2, data2 + 8), TestSuite::Compare::Container); + #endif } }} diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 43c63b64b..d747f50b1 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -36,6 +36,7 @@ corrade_add_test(RendererTest RendererTest.cpp LIBRARIES Magnum) corrade_add_test(ResourceManagerTest ResourceManagerTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(SamplerTest SamplerTest.cpp LIBRARIES Magnum) corrade_add_test(ShaderTest ShaderTest.cpp LIBRARIES Magnum) +corrade_add_test(VersionTest VersionTest.cpp LIBRARIES Magnum) if(BUILD_GL_TESTS) corrade_add_test(AbstractObjectGLTest AbstractObjectGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) diff --git a/src/Test/CubeMapTextureGLTest.cpp b/src/Test/CubeMapTextureGLTest.cpp index 387f81018..d72978e72 100644 --- a/src/Test/CubeMapTextureGLTest.cpp +++ b/src/Test/CubeMapTextureGLTest.cpp @@ -244,6 +244,8 @@ void CubeMapTextureGLTest::subImageBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(CubeMapTexture::Coordinate::PositiveX, 0, image, BufferUsage::StaticRead); @@ -257,6 +259,7 @@ void CubeMapTextureGLTest::subImageBuffer() { 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), TestSuite::Compare::Container); + #endif } #endif diff --git a/src/Test/TextureGLTest.cpp b/src/Test/TextureGLTest.cpp index 73edceb96..f3582b65a 100644 --- a/src/Test/TextureGLTest.cpp +++ b/src/Test/TextureGLTest.cpp @@ -701,6 +701,8 @@ void TextureGLTest::storage1DArray() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32)); CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32)); CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32)); @@ -709,6 +711,7 @@ void TextureGLTest::storage1DArray() { CORRADE_COMPARE(texture.imageSize(5), Vector2i( 0, 0)); /* not available */ MAGNUM_VERIFY_NO_ERROR(); + #endif } #endif @@ -724,6 +727,8 @@ void TextureGLTest::storage2DArray() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32)); CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32)); CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32)); @@ -732,6 +737,7 @@ void TextureGLTest::storage2DArray() { CORRADE_COMPARE(texture.imageSize(5), Vector3i( 0, 0, 0)); /* not available */ MAGNUM_VERIFY_NO_ERROR(); + #endif } #endif @@ -843,6 +849,8 @@ void TextureGLTest::image2DBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); @@ -852,6 +860,7 @@ void TextureGLTest::image2DBuffer() { CORRADE_COMPARE(image.size(), Vector2i(2)); CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), std::vector(data, data + 16), TestSuite::Compare::Container); + #endif } #endif @@ -904,6 +913,8 @@ void TextureGLTest::image3DBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); @@ -913,6 +924,7 @@ void TextureGLTest::image3DBuffer() { CORRADE_COMPARE(image.size(), Vector3i(2)); CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), std::vector(data, data + 32), TestSuite::Compare::Container); + #endif } #endif @@ -988,6 +1000,8 @@ void TextureGLTest::image2DArray() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image); @@ -996,6 +1010,7 @@ void TextureGLTest::image2DArray() { CORRADE_COMPARE(image.size(), Vector3i(2)); CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), std::vector(data, data + 32), TestSuite::Compare::Container); + #endif } void TextureGLTest::image2DArrayBuffer() { @@ -1018,6 +1033,8 @@ void TextureGLTest::image2DArrayBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); @@ -1027,6 +1044,7 @@ void TextureGLTest::image2DArrayBuffer() { CORRADE_COMPARE(image.size(), Vector3i(2)); CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), std::vector(data, data + 32), TestSuite::Compare::Container); + #endif } #endif @@ -1204,6 +1222,8 @@ void TextureGLTest::subImage2DBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); @@ -1217,6 +1237,7 @@ void TextureGLTest::subImage2DBuffer() { 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), TestSuite::Compare::Container); + #endif } #endif @@ -1294,6 +1315,8 @@ void TextureGLTest::subImage3DBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); @@ -1322,6 +1345,7 @@ void TextureGLTest::subImage3DBuffer() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), TestSuite::Compare::Container); + #endif } #endif @@ -1414,6 +1438,8 @@ void TextureGLTest::subImage2DArray() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image); @@ -1441,6 +1467,7 @@ void TextureGLTest::subImage2DArray() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), TestSuite::Compare::Container); + #endif } void TextureGLTest::subImage2DArrayBuffer() { @@ -1466,6 +1493,8 @@ void TextureGLTest::subImage2DArrayBuffer() { MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); texture.image(0, image, BufferUsage::StaticRead); const auto imageData = image.buffer().data(); @@ -1494,6 +1523,7 @@ void TextureGLTest::subImage2DArrayBuffer() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), TestSuite::Compare::Container); + #endif } #endif @@ -1713,13 +1743,18 @@ void TextureGLTest::generateMipmap2DArray() { texture.setImage(0, TextureFormat::RGBA8, ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(32))); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(texture.imageSize(0), Vector3i(32)); CORRADE_COMPARE(texture.imageSize(1), Vector3i( 0)); + #endif texture.generateMipmap(); MAGNUM_VERIFY_NO_ERROR(); + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32)); CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32)); CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32)); @@ -1728,6 +1763,7 @@ void TextureGLTest::generateMipmap2DArray() { CORRADE_COMPARE(texture.imageSize(5), Vector3i( 1, 1, 32)); MAGNUM_VERIFY_NO_ERROR(); + #endif } #endif diff --git a/src/Test/VersionTest.cpp b/src/Test/VersionTest.cpp new file mode 100644 index 000000000..d3d6d9693 --- /dev/null +++ b/src/Test/VersionTest.cpp @@ -0,0 +1,62 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Version.h" + +namespace Magnum { namespace Test { + +class VersionTest: public TestSuite::Tester { + public: + explicit VersionTest(); + + void fromNumber(); + void toNumber(); +}; + +VersionTest::VersionTest() { + addTests({&VersionTest::fromNumber, + &VersionTest::toNumber}); +} + +void VersionTest::fromNumber() { + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE(version(4, 3), Version::GL430); + #else + CORRADE_COMPARE(version(3, 0), Version::GLES300); + #endif +} + +void VersionTest::toNumber() { + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE(version(Version::GL430), std::make_pair(4, 3)); + #else + CORRADE_COMPARE(version(Version::GLES300), std::make_pair(3, 0)); + #endif +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::VersionTest) diff --git a/src/Text/DistanceFieldGlyphCache.cpp b/src/Text/DistanceFieldGlyphCache.cpp index 9110108d4..64fc47517 100644 --- a/src/Text/DistanceFieldGlyphCache.cpp +++ b/src/Text/DistanceFieldGlyphCache.cpp @@ -27,6 +27,7 @@ #ifndef CORRADE_NO_ASSERT #include "ColorFormat.h" #endif +#include "Context.h" #include "Extensions.h" #include "ImageReference.h" #include "TextureFormat.h" diff --git a/src/Text/GlyphCache.cpp b/src/Text/GlyphCache.cpp index e5b98666e..d7acc5a26 100644 --- a/src/Text/GlyphCache.cpp +++ b/src/Text/GlyphCache.cpp @@ -24,6 +24,7 @@ #include "GlyphCache.h" +#include "Context.h" #include "Extensions.h" #include "Image.h" #include "TextureFormat.h" diff --git a/src/TextureTools/DistanceField.cpp b/src/TextureTools/DistanceField.cpp index 52e75465f..107d7d033 100644 --- a/src/TextureTools/DistanceField.cpp +++ b/src/TextureTools/DistanceField.cpp @@ -29,6 +29,7 @@ #include "Math/Range.h" #include "AbstractShaderProgram.h" #include "Buffer.h" +#include "Context.h" #include "Extensions.h" #include "Framebuffer.h" #include "Mesh.h" diff --git a/src/Version.cpp b/src/Version.cpp new file mode 100644 index 000000000..57cdd543b --- /dev/null +++ b/src/Version.cpp @@ -0,0 +1,58 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Version.h" + +#include + +namespace Magnum { + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, Version value) { + switch(value) { + #define _c(value, string) case Version::value: return debug << string; + _c(None, "None") + #ifndef MAGNUM_TARGET_GLES + _c(GL210, "OpenGL 2.1") + _c(GL300, "OpenGL 3.0") + _c(GL310, "OpenGL 3.1") + _c(GL320, "OpenGL 3.2") + _c(GL330, "OpenGL 3.3") + _c(GL400, "OpenGL 4.0") + _c(GL410, "OpenGL 4.1") + _c(GL420, "OpenGL 4.2") + _c(GL430, "OpenGL 4.3") + _c(GL440, "OpenGL 4.4") + #else + _c(GLES200, "OpenGL ES 2.0") + _c(GLES300, "OpenGL ES 3.0") + #endif + #undef _c + } + + return debug << "Invalid"; +} +#endif + +} diff --git a/src/Version.h b/src/Version.h new file mode 100644 index 000000000..e89cb45fb --- /dev/null +++ b/src/Version.h @@ -0,0 +1,108 @@ +#ifndef Magnum_Version_h +#define Magnum_Version_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file Version.h + * Enum @ref Magnum::Version, function @ref version() + */ + +#include + +#include "Magnum.h" +#include "magnumVisibility.h" + +namespace Magnum { + +/** +@brief OpenGL version + +@see @ref Context, @ref MAGNUM_ASSERT_VERSION_SUPPORTED() +*/ +enum class Version: Int { + None = 0xFFFF, /**< @brief Unspecified */ + #ifndef MAGNUM_TARGET_GLES + GL210 = 210, /**< @brief OpenGL 2.1 / GLSL 1.20 */ + GL300 = 300, /**< @brief OpenGL 3.0 / GLSL 1.30 */ + GL310 = 310, /**< @brief OpenGL 3.1 / GLSL 1.40 */ + GL320 = 320, /**< @brief OpenGL 3.2 / GLSL 1.50 */ + GL330 = 330, /**< @brief OpenGL 3.3, GLSL 3.30 */ + GL400 = 400, /**< @brief OpenGL 4.0, GLSL 4.00 */ + GL410 = 410, /**< @brief OpenGL 4.1, GLSL 4.10 */ + GL420 = 420, /**< @brief OpenGL 4.2, GLSL 4.20 */ + GL430 = 430, /**< @brief OpenGL 4.3, GLSL 4.30 */ + GL440 = 440, /**< @brief OpenGL 4.4, GLSL 4.40 */ + #endif + + /** + * @brief OpenGL ES 2.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. + */ + #ifndef MAGNUM_TARGET_GLES + GLES200 = 410, + #else + GLES200 = 200, + #endif + + /** + * @brief OpenGL ES 3.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. + */ + #ifndef MAGNUM_TARGET_GLES + GLES300 = 430 + #else + GLES300 = 300 + #endif +}; + +#if defined(CORRADE_GCC44_COMPATIBILITY) && !defined(DOXYGEN_GENERATING_OUTPUT) +/* GCC 4.4 somehow doesn't have comparison operators for strongly-typed enums */ +inline bool operator<=(Version a, Version b) { return Int(a) <= Int(b); } +inline bool operator>=(Version a, Version b) { return Int(a) >= Int(b); } +inline bool operator<(Version a, Version b) { return Int(a) < Int(b); } +inline bool operator>(Version a, Version b) { return Int(a) > Int(b); } +#endif + +/** @brief Enum value from major and minor version number */ +inline Version version(Int major, Int minor) { + return Version(major*100 + minor*10); +} + +/** @brief Major and minor version number from enum value */ +inline std::pair version(Version version) { + return {Int(version)/100, (Int(version)%100)/10}; +} + +/** @debugoperator{Magnum::Context} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, Version value); + +} + +#endif