diff --git a/doc/changelog.dox b/doc/changelog.dox index 958ab8235..f92a88e62 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -138,6 +138,11 @@ See also: parameters consistent across the implementations. - Added numpad keys to @ref Platform::Sdl2Application::KeyEvent::Key, consistent with GLFW key mapping +- Exposed enabled-by-default @ref Platform::Sdl2Application::GLConfiguration::Flag::ForwardCompatible "GLConfiguration::Flag::ForwardCompatible" + flag in @ref Platform::Sdl2Application and @ref Platform::GlfwApplication, + added @ref Platform::Sdl2Application::GLConfiguration::addFlags() "GLConfiguration::addFlags()" + and @ref Platform::Sdl2Application::GLConfiguration::clearFlags() "GLConfiguration::clearFlags()" + for easier flag handling @subsubsection changelog-latest-new-primitives Primitives library diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index 952c34695..f2139b633 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -339,7 +339,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf #ifndef MAGNUM_TARGET_GLES if(glConfiguration.version() >= GL::Version::GL320) { glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, flags >= GLConfiguration::Flag::ForwardCompatible); } #else glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); @@ -355,7 +355,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, flags >= GLConfiguration::Flag::ForwardCompatible); #else /* For ES the major context version is compile-time constant */ #ifdef MAGNUM_TARGET_GLES3 @@ -413,6 +413,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); + /** @todo or keep the fwcompat? */ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, false); _window = glfwCreateWindow(scaledWindowSize.x(), scaledWindowSize.y(), configuration.title().c_str(), monitor, nullptr); @@ -620,7 +621,13 @@ void GlfwApplication::textInputEvent(TextInputEvent&) {} #ifdef MAGNUM_TARGET_GL GlfwApplication::GLConfiguration::GLConfiguration(): _colorBufferSize{8, 8, 8, 0}, _depthBufferSize{24}, _stencilBufferSize{0}, - _sampleCount{0}, _version{GL::Version::None}, _srgbCapable{false} {} + _sampleCount{0}, _version{GL::Version::None}, + #ifndef MAGNUM_TARGET_GLES + _flags{Flag::ForwardCompatible}, + #else + _flags{}, + #endif + _srgbCapable{false} {} GlfwApplication::GLConfiguration::~GLConfiguration() = default; #endif @@ -632,6 +639,9 @@ GlfwApplication::Configuration::Configuration(): _dpiScalingPolicy{DpiScalingPolicy::Default}, _cursorMode{CursorMode::Normal} #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) + /* Deliberately not setting _flags to ForwardCompatible to avoid them + having higher priority over GLConfiguration flags, appending that flag + later */ , _sampleCount{0}, _version{GL::Version::None}, _srgbCapable{false} #endif {} diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index 38c687475..05e2c39ab 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -587,6 +587,16 @@ class GlfwApplication::GLConfiguration { * @see @ref Flags, @ref setFlags(), @ref Context::Flag */ enum class Flag: UnsignedByte { + #ifndef MAGNUM_TARGET_GLES + /** + * Forward compatible context + * + * @requires_gl Core/compatibility profile distinction and forward + * compatibility applies only to desktop GL. + */ + ForwardCompatible = 1 << 0, + #endif + #if defined(DOXYGEN_GENERATING_OUTPUT) || defined(GLFW_CONTEXT_NO_ERROR) /** * Specifies whether errors should be generated by the context. @@ -619,13 +629,41 @@ class GlfwApplication::GLConfiguration { * @brief Set context flags * @return Reference to self (for method chaining) * - * Default is no flag. + * Default is @ref Flag::ForwardCompatible on desktop GL and no flags + * on OpenGL ES. + * @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags() */ GLConfiguration& 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() + */ + GLConfiguration& 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() + */ + GLConfiguration& clearFlags(Flags flags) { + _flags &= ~flags; + return *this; + } + /** @brief Context version */ GL::Version version() const { return _version; } diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 5b701f057..9406d11a6 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -272,8 +272,13 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf GLConfiguration glConfiguration{_glConfiguration}; CORRADE_IGNORE_DEPRECATED_PUSH #ifndef CORRADE_TARGET_EMSCRIPTEN + #ifndef MAGNUM_TARGET_GLES + if(configuration.flags() && glConfiguration.flags() == GLConfiguration::Flag::ForwardCompatible) + glConfiguration.setFlags(configuration.flags()|GLConfiguration::Flag::ForwardCompatible); + #else if(configuration.flags() && !glConfiguration.flags()) glConfiguration.setFlags(configuration.flags()); + #endif if(configuration.version() != GL::Version::None && glConfiguration.version() == GL::Version::None) glConfiguration.setVersion(configuration.version()); #endif @@ -343,7 +348,7 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags())|SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags())); #else /* For ES the major context version is compile-time constant */ #ifdef MAGNUM_TARGET_GLES3 @@ -416,7 +421,8 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags())); + /** @todo or keep the fwcompat? */ + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags() & ~GLConfiguration::Flag::ForwardCompatible)); if(!(_window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -839,7 +845,13 @@ Sdl2Application::GLConfiguration::GLConfiguration(): _colorBufferSize{8, 8, 8, 0}, _depthBufferSize{24}, _stencilBufferSize{0}, _sampleCount(0) #ifndef CORRADE_TARGET_EMSCRIPTEN - , _version(GL::Version::None), _srgbCapable{false} + , _version(GL::Version::None), + #ifndef MAGNUM_TARGET_GLES + _flags{Flag::ForwardCompatible}, + #else + _flags{}, + #endif + _srgbCapable{false} #endif {} @@ -859,6 +871,9 @@ Sdl2Application::Configuration::Configuration(): #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) , _sampleCount(0) #ifndef CORRADE_TARGET_EMSCRIPTEN + /* Deliberately not setting _flags to ForwardCompatible to avoid them + having higher priority over GLConfiguration flags, appending that flag + later */ , _version(GL::Version::None), _srgbCapable{false} #endif #endif diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index 039dafa62..084b95065 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -981,7 +981,18 @@ class Sdl2Application::GLConfiguration { * @requires_gles Context flags are not available in WebGL. */ enum class Flag: int { - Debug = SDL_GL_CONTEXT_DEBUG_FLAG, /**< Create debug context */ + #ifndef MAGNUM_TARGET_GLES + /** + * Forward compatible context + * + * @requires_gl Core/compatibility profile distinction and forward + * compatibility applies only to desktop GL. + */ + ForwardCompatible = SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG, + #endif + + /** Create debug context */ + Debug = SDL_GL_CONTEXT_DEBUG_FLAG, /** Create context with robust access */ RobustAccess = SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG, @@ -998,7 +1009,11 @@ class Sdl2Application::GLConfiguration { */ #ifndef DOXYGEN_GENERATING_OUTPUT typedef Containers::EnumSet Flags; + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG|SDL_GL_CONTEXT_RESET_ISOLATION_FLAG + #ifndef MAGNUM_TARGET_GLES + |SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG + #endif + > Flags; #else typedef Containers::EnumSet Flags; #endif @@ -1019,7 +1034,9 @@ class Sdl2Application::GLConfiguration { * @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. */ GLConfiguration& setFlags(Flags flags) { @@ -1027,6 +1044,34 @@ class Sdl2Application::GLConfiguration { 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. + */ + GLConfiguration& 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. + */ + GLConfiguration& clearFlags(Flags flags) { + _flags &= ~flags; + return *this; + } + /** * @brief Context version *