diff --git a/doc/changelog.dox b/doc/changelog.dox index f92a88e62..999ba3f9c 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -143,6 +143,13 @@ See also: added @ref Platform::Sdl2Application::GLConfiguration::addFlags() "GLConfiguration::addFlags()" and @ref Platform::Sdl2Application::GLConfiguration::clearFlags() "GLConfiguration::clearFlags()" for easier flag handling +- Exposed enabled-by-default @ref Platform::WindowlessEglApplication::Configuration::Flag::ForwardCompatible "Configuration::Flag::ForwardCompatible" + flag in @ref Platform::WindowlessEglApplication, + @ref Platform::WindowlessGlxApplication and + @ref Platform::WindowlessWglApplication, + added @ref Platform::WindowlessEglApplication::Configuration::addFlags() "Configuration::addFlags()" + and @ref Platform::WindowlessEglApplication::Configuration::clearFlags() "Configuration::clearFlags()" + for easier flag handling @subsubsection changelog-latest-new-primitives Primitives library diff --git a/src/Magnum/Platform/WindowlessEglApplication.cpp b/src/Magnum/Platform/WindowlessEglApplication.cpp index 8a7ae2f6d..058d05470 100644 --- a/src/Magnum/Platform/WindowlessEglApplication.cpp +++ b/src/Magnum/Platform/WindowlessEglApplication.cpp @@ -188,6 +188,14 @@ bool WindowlessEglContext::makeCurrent() { return false; } +WindowlessEglContext::Configuration::Configuration() + #ifndef MAGNUM_TARGET_GLES + : _flags{Flag::ForwardCompatible} + #elif !defined(MAGNUM_TARGET_WEBGL) + : _flags{} + #endif + {} + #ifndef DOXYGEN_GENERATING_OUTPUT WindowlessEglApplication::WindowlessEglApplication(const Arguments& arguments): WindowlessEglApplication{arguments, Configuration{}} {} #endif diff --git a/src/Magnum/Platform/WindowlessEglApplication.h b/src/Magnum/Platform/WindowlessEglApplication.h index fcf001b97..ac18af82a 100644 --- a/src/Magnum/Platform/WindowlessEglApplication.h +++ b/src/Magnum/Platform/WindowlessEglApplication.h @@ -139,6 +139,16 @@ class WindowlessEglContext::Configuration { * @requires_gles Context flags are not available in WebGL. */ enum class Flag: int { + #ifndef MAGNUM_TARGET_GLES + /** + * Forward compatible context + * + * @requires_gl Core/compatibility profile distinction and forward + * compatibility applies only to desktop GL. + */ + ForwardCompatible = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + #endif + Debug = EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR /**< Create debug context */ }; @@ -149,13 +159,17 @@ class WindowlessEglContext::Configuration { * @requires_gles Context flags are not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - typedef Containers::EnumSet Flags; + typedef Containers::EnumSet Flags; #else typedef Containers::EnumSet Flags; #endif #endif - constexpr /*implicit*/ Configuration() {} + /*implicit*/ Configuration(); #ifndef MAGNUM_TARGET_WEBGL /** @@ -169,13 +183,43 @@ class WindowlessEglContext::Configuration { * @brief Set context flags * @return Reference to self (for method chaining) * - * Default is no flag. See also @ref GL::Context::flags(). + * Default is @ref Flag::ForwardCompatible on desktop GL and no flags + * on OpenGL ES. + * @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags() * @requires_gles Context flags are not available in WebGL. */ Configuration& setFlags(Flags flags) { _flags = flags; return *this; } + + /** + * @brief Add context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ORs the flags with existing instead of + * replacing them. Useful for preserving the defaults. + * @see @ref clearFlags() + * @requires_gles Context flags are not available in WebGL. + */ + Configuration& addFlags(Flags flags) { + _flags |= flags; + return *this; + } + + /** + * @brief Clear context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ANDs the inverse of @p flags with existing + * instead of replacing them. Useful for removing default flags. + * @see @ref addFlags() + * @requires_gles Context flags are not available in WebGL. + */ + Configuration& clearFlags(Flags flags) { + _flags &= ~flags; + return *this; + } #endif private: @@ -184,6 +228,10 @@ class WindowlessEglContext::Configuration { #endif }; +#ifndef MAGNUM_TARGET_WEBGL +CORRADE_ENUMSET_OPERATORS(WindowlessEglContext::Configuration::Flags) +#endif + /** @brief Windowless EGL application diff --git a/src/Magnum/Platform/WindowlessGlxApplication.cpp b/src/Magnum/Platform/WindowlessGlxApplication.cpp index a0c0f8502..a37f38898 100644 --- a/src/Magnum/Platform/WindowlessGlxApplication.cpp +++ b/src/Magnum/Platform/WindowlessGlxApplication.cpp @@ -85,7 +85,7 @@ WindowlessGlxContext::WindowlessGlxContext(const WindowlessGlxContext::Configura GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB|GLint(configuration.flags()), + GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags()), #endif 0 }; @@ -130,7 +130,8 @@ WindowlessGlxContext::WindowlessGlxContext(const WindowlessGlxContext::Configura /* Destroy the core context and create a compatibility one */ glXDestroyContext(_display, _context); const GLint fallbackContextAttributes[] = { - GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags()), + /** @todo keep the fwcompat? */ + GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags() & ~Configuration::Flag::ForwardCompatible), 0 }; _context = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, fallbackContextAttributes); @@ -180,6 +181,14 @@ bool WindowlessGlxContext::makeCurrent() { return false; } +WindowlessGlxContext::Configuration::Configuration(): + #ifndef MAGNUM_TARGET_GLES + _flags{Flag::ForwardCompatible} + #else + _flags{} + #endif + {} + #ifndef DOXYGEN_GENERATING_OUTPUT WindowlessGlxApplication::WindowlessGlxApplication(const Arguments& arguments): WindowlessGlxApplication{arguments, Configuration{}} {} #endif diff --git a/src/Magnum/Platform/WindowlessGlxApplication.h b/src/Magnum/Platform/WindowlessGlxApplication.h index 6c367b888..943d46a00 100644 --- a/src/Magnum/Platform/WindowlessGlxApplication.h +++ b/src/Magnum/Platform/WindowlessGlxApplication.h @@ -148,6 +148,16 @@ class WindowlessGlxContext::Configuration { * @see @ref Flags, @ref setFlags(), @ref Context::Flag */ enum class Flag: int { + #ifndef MAGNUM_TARGET_GLES + /** + * Forward compatible context + * + * @requires_gl Core/compatibility profile distinction and forward + * compatibility applies only to desktop GL. + */ + ForwardCompatible = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + #endif + Debug = GLX_CONTEXT_DEBUG_BIT_ARB /**< Create debug context */ }; @@ -157,12 +167,16 @@ class WindowlessGlxContext::Configuration { * @see @ref setFlags(), @ref Context::Flags */ #ifndef DOXYGEN_GENERATING_OUTPUT - typedef Containers::EnumSet Flags; + typedef Containers::EnumSet Flags; #else typedef Containers::EnumSet Flags; #endif - constexpr /*implicit*/ Configuration() {} + /*implicit*/ Configuration(); /** @brief Context flags */ Flags flags() const { return _flags; } @@ -171,17 +185,47 @@ class WindowlessGlxContext::Configuration { * @brief Set context flags * @return Reference to self (for method chaining) * - * Default is no flag. See also @ref GL::Context::flags(). + * Default is @ref Flag::ForwardCompatible on desktop GL and no flags + * on OpenGL ES. + * @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags() */ Configuration& setFlags(Flags flags) { _flags = flags; return *this; } + /** + * @brief Add context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ORs the flags with existing instead of + * replacing them. Useful for preserving the defaults. + * @see @ref clearFlags() + */ + Configuration& addFlags(Flags flags) { + _flags |= flags; + return *this; + } + + /** + * @brief Clear context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ANDs the inverse of @p flags with existing + * instead of replacing them. Useful for removing default flags. + * @see @ref addFlags() + */ + Configuration& clearFlags(Flags flags) { + _flags &= ~flags; + return *this; + } + private: Flags _flags; }; +CORRADE_ENUMSET_OPERATORS(WindowlessGlxContext::Configuration::Flags) + /** @brief Windowless GLX application diff --git a/src/Magnum/Platform/WindowlessWglApplication.cpp b/src/Magnum/Platform/WindowlessWglApplication.cpp index 414bdadf1..cebf80099 100644 --- a/src/Magnum/Platform/WindowlessWglApplication.cpp +++ b/src/Magnum/Platform/WindowlessWglApplication.cpp @@ -40,7 +40,6 @@ #define WGL_CONTEXT_FLAGS_ARB 0x2094 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #endif @@ -137,7 +136,7 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 1, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB|GLint(configuration.flags()), + WGL_CONTEXT_FLAGS_ARB, GLint(configuration.flags()), #endif 0 }; @@ -149,7 +148,8 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G Warning() << "Platform::WindowlessWglContext: cannot create core context, falling back to compatibility context:" << GetLastError(); const int fallbackContextAttributes[] = { - WGL_CONTEXT_FLAGS_ARB, int(configuration.flags()), + /** @todo or keep the fwcompat? */ + WGL_CONTEXT_FLAGS_ARB, GLint(configuration.flags() & ~Configuration::Flag::ForwardCompatible), 0 }; _context = wglCreateContextAttribsARB(_deviceContext, nullptr, fallbackContextAttributes); @@ -184,7 +184,8 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G /* Destroy the core context and create a compatibility one */ wglDeleteContext(_context); const int fallbackContextAttributes[] = { - WGL_CONTEXT_FLAGS_ARB, int(configuration.flags()), + /** @todo or keep the fwcompat? */ + WGL_CONTEXT_FLAGS_ARB, GLint(configuration.flags() & ~Configuration::Flag::ForwardCompatible), 0 }; _context = wglCreateContextAttribsARB(_deviceContext, nullptr, fallbackContextAttributes); @@ -234,6 +235,14 @@ bool WindowlessWglContext::makeCurrent() { return false; } +WindowlessWglContext::Configuration::Configuration(): + #ifndef MAGNUM_TARGET_GLES + _flags{Flag::ForwardCompatible} + #else + _flags{} + #endif + {} + #ifndef DOXYGEN_GENERATING_OUTPUT WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments): WindowlessWglApplication{arguments, Configuration{}} {} #endif diff --git a/src/Magnum/Platform/WindowlessWglApplication.h b/src/Magnum/Platform/WindowlessWglApplication.h index 1fb32dea2..07e59dbe0 100644 --- a/src/Magnum/Platform/WindowlessWglApplication.h +++ b/src/Magnum/Platform/WindowlessWglApplication.h @@ -46,6 +46,7 @@ /* Define stuff that we need because I can't be bothered with creating a new header just for a few defines */ #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #endif namespace Magnum { namespace Platform { @@ -147,6 +148,16 @@ class WindowlessWglContext::Configuration { * @see @ref Flags, @ref setFlags(), @ref Context::Flag */ enum class Flag: int { + #ifndef MAGNUM_TARGET_GLES + /** + * Forward compatible context + * + * @requires_gl Core/compatibility profile distinction and forward + * compatibility applies only to desktop GL. + */ + ForwardCompatible = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + #endif + Debug = WGL_CONTEXT_DEBUG_BIT_ARB /**< Create debug context */ }; @@ -156,12 +167,16 @@ class WindowlessWglContext::Configuration { * @see @ref setFlags(), @ref Context::Flags */ #ifndef DOXYGEN_GENERATING_OUTPUT - typedef Containers::EnumSet Flags; + typedef Containers::EnumSet Flags; #else typedef Containers::EnumSet Flags; #endif - constexpr /*implicit*/ Configuration() {} + /*implicit*/ Configuration(); /** @brief Context flags */ Flags flags() const { return _flags; } @@ -170,17 +185,47 @@ class WindowlessWglContext::Configuration { * @brief Set context flags * @return Reference to self (for method chaining) * - * Default is no flag. See also @ref GL::Context::flags(). + * Default is @ref Flag::ForwardCompatible on desktop GL and no flags + * on OpenGL ES. + * @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags() */ Configuration& setFlags(Flags flags) { _flags = flags; return *this; } + /** + * @brief Add context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ORs the flags with existing instead of + * replacing them. Useful for preserving the defaults. + * @see @ref clearFlags() + */ + Configuration& addFlags(Flags flags) { + _flags |= flags; + return *this; + } + + /** + * @brief Clear context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ANDs the inverse of @p flags with existing + * instead of replacing them. Useful for removing default flags. + * @see @ref addFlags() + */ + Configuration& clearFlags(Flags flags) { + _flags &= ~flags; + return *this; + } + private: Flags _flags; }; +CORRADE_ENUMSET_OPERATORS(WindowlessWglContext::Configuration::Flags) + /** @brief Windowless WGL application diff --git a/src/Magnum/Platform/WindowlessWindowsEglApplication.h b/src/Magnum/Platform/WindowlessWindowsEglApplication.h index 628ae728d..33a226de5 100644 --- a/src/Magnum/Platform/WindowlessWindowsEglApplication.h +++ b/src/Magnum/Platform/WindowlessWindowsEglApplication.h @@ -164,10 +164,38 @@ class WindowlessWindowsEglContext::Configuration { return *this; } + /** + * @brief Add context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ORs the flags with existing instead of + * replacing them. Useful for preserving the defaults. + * @see @ref clearFlags() + */ + Configuration& addFlags(Flags flags) { + _flags |= flags; + return *this; + } + + /** + * @brief Clear context flags + * @return Reference to self (for method chaining) + * + * Unlike @ref setFlags(), ANDs the inverse of @p flags with existing + * instead of replacing them. Useful for removing default flags. + * @see @ref addFlags() + */ + Configuration& clearFlags(Flags flags) { + _flags &= ~flags; + return *this; + } + private: Flags _flags; }; +CORRADE_ENUMSET_OPERATORS(WindowlessWindowsEglContext::Configuration::Flags) + /** @brief Windowless Windows/EGL application