diff --git a/doc/changelog-old.dox b/doc/changelog-old.dox index 3da518c52..8475c5dad 100644 --- a/doc/changelog-old.dox +++ b/doc/changelog-old.dox @@ -312,8 +312,8 @@ for a high-level overview. - @ref Math::Range::data() function, useful when querying range values from GL - Support for specifying context flags using - @ref Platform::Sdl2Application::Configuration::setFlags() "Platform::*Application::Configuration::setFlags()", - they are now also shown in @ref magnum-gl-info "magnum-info" + @cpp Platform::*Application::Configuration::setFlags() @ce, they are now + also shown in @ref magnum-gl-info "magnum-info" - More robust support for driver detection and driver bug workarounds. Driver can be detected using @cpp Context::detectedDriver() @ce, problematic extension disabled, which is then shown in @ref magnum-gl-info "magnum-info" diff --git a/doc/changelog.dox b/doc/changelog.dox index 188876e43..b85fe30de 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -146,6 +146,13 @@ See also: @ref GL::pixelFormat(), which unconditionally returns @ref GL::PixelFormat::Luminance for @ref PixelFormat::R8Unorm. +@subsubsection changelog-latest-changes-platform Platform libraries + +- Separated @ref Platform::Sdl2Application::Configuration "Platform::*Application::Configuration" + into @ref Platform::Sdl2Application::Configuration "Configuration" and + @ref Platform::Sdl2Application::GLConfiguration "GLConfiguration" to allow + creation of non-GL application instances in the future + @subsubsection changelog-latest-changes-plugins Plugins - @ref Trade::TgaImporter "TgaImporter" and @@ -208,6 +215,10 @@ See also: @ref MAGNUM_VERIFY_NO_GL_ERROR() instead - The `Platform::Context` class is deprecated, use @ref Platform::GLContext instead +- `Platform::*Application::createContext()` and + `Platform::*Application::tryCreateContext()` functions are deprecated for + being too GL-specific, use @ref Platform::Sdl2Application::create() "create()" + and @ref Platform::Sdl2Application::tryCreate() "tryCreate()" instead - The `Extensions::GL` namespace is deprecated, use @ref GL::Extensions instead - The @ref PixelFormat and @ref CompressedPixelFormat enum now contains @@ -729,7 +740,7 @@ a high-level overview. which allows the context to be destructed and created again in case the version is not what the application wants (as opposed to just aborting the application) (see [mosra/magnum#105](https://github.com/mosra/magnum/issues/105)) -- Added @ref Platform::Sdl2Application::Configuration::setSRGBCapable() +- Added @ref Platform::Sdl2Application::GLConfiguration::setSRGBCapable() "Platform::Sdl2Application::Configuration::setSRGBCapable()" - Added @ref Platform::Sdl2Application::Configuration::WindowFlag::Borderless and @ref Platform::Sdl2Application::Configuration::WindowFlag::AllowHighDpi for iOS and macOS diff --git a/doc/platform.dox b/doc/platform.dox index a0af44e6a..36bf03027 100644 --- a/doc/platform.dox +++ b/doc/platform.dox @@ -146,16 +146,16 @@ this: However, sometimes you would need to configure the application based on some configuration file or system introspection. In that case you can pass `nullptr` instead of @ref Platform::Sdl2Application::Configuration "Configuration" -instance and then specify it later with @ref Platform::Sdl2Application::createContext() "createContext()": +instance and then specify it later with @ref Platform::Sdl2Application::create() "create()": @snippet MagnumPlatform.cpp createcontext -If the context creation in constructor or @ref Platform::Sdl2Application::createContext() "createContext()" +If the context creation in constructor or @ref Platform::Sdl2Application::create() "create()" fails, the application exits. However, it is also possible to negotiate the -context using @ref Platform::Sdl2Application::tryCreateContext() "tryCreateContext()". -The only difference is that this function returns `false` instead of exiting. -You can for example try enabling MSAA and if the context creation fails, fall -back to no-AA rendering: +context using @ref Platform::Sdl2Application::tryCreate() "tryCreate()". The +only difference is that this function returns `false` instead of exiting. You +can for example try enabling MSAA and if the context creation fails, fall back +to no-AA rendering: @snippet MagnumPlatform.cpp trycreatecontext diff --git a/doc/snippets/MagnumPlatform.cpp b/doc/snippets/MagnumPlatform.cpp index 595c2e739..5a6cdf618 100644 --- a/doc/snippets/MagnumPlatform.cpp +++ b/doc/snippets/MagnumPlatform.cpp @@ -109,7 +109,7 @@ MyApplication::MyApplication(const Arguments& arguments): { // ... - createContext(Configuration{} + create(Configuration{} .setTitle("My Application") .setSize(size)); @@ -132,11 +132,12 @@ MyApplication::MyApplication(const Arguments& arguments): // ... Configuration conf; - conf.setTitle("My Application") - .setSampleCount(16); + conf.setTitle("My Application"); + GLConfiguration glConf; + glConf.setSampleCount(16); - if(!tryCreateContext(conf)) - createContext(conf.setSampleCount(0)); + if(!tryCreate(conf, glConf)) + create(conf, glConf.setSampleCount(0)); // ... } diff --git a/src/Magnum/GL/DebugOutput.h b/src/Magnum/GL/DebugOutput.h index bcbb29858..2ee407a53 100644 --- a/src/Magnum/GL/DebugOutput.h +++ b/src/Magnum/GL/DebugOutput.h @@ -62,7 +62,7 @@ provided also by @extension{EXT,debug_marker} (desktop/ES extensions) or With OpenGL 4.3 / OpenGL ES 3.2 or @extension{KHR,debug} desktop/ES extension, the debug output needs to be enabled first. It can be enabled globally using -@ref Platform::Sdl2Application::Configuration::Flag::Debug "Platform::*Application::Configuration::Flag::Debug" +@ref Platform::Sdl2Application::GLConfiguration::Flag::Debug "Platform::*Application::Configuration::Flag::Debug" when creating context or only for some portions of the code using @ref Renderer::Feature::DebugOutput. If enabled globally, some OpenGL drivers may provide additional debugging information. In addition to that you can diff --git a/src/Magnum/GL/Renderer.h b/src/Magnum/GL/Renderer.h index 42a5b7b7e..365bc3866 100644 --- a/src/Magnum/GL/Renderer.h +++ b/src/Magnum/GL/Renderer.h @@ -105,7 +105,7 @@ class MAGNUM_GL_EXPORT Renderer { * Debug output. Disabled by default unless the GL context was * created with debug output enabled. * @see @ref DebugOutput, @ref Feature::DebugOutputSynchronous, - * @ref Platform::Sdl2Application::Configuration::Flag::Debug "Platform::*Application::Configuration::Flag::Debug" + * @ref Platform::Sdl2Application::GLConfiguration::Flag::Debug "Platform::*Application::GLConfiguration::Flag::Debug" * @requires_gl43 Extension @extension{KHR,debug} * @requires_gles32 Extension @extension{ANDROID,extension_pack_es31a} / * @extension2{KHR,debug,debug} @@ -189,7 +189,7 @@ class MAGNUM_GL_EXPORT Renderer { /** * Multisampling. Enabled by default. Note that the actual presence * of this feature in default framebuffer depends on context - * configuration, see for example @ref Platform::Sdl2Application::Configuration::setSampleCount(). + * configuration, see for example @ref Platform::Sdl2Application::GLConfiguration::setSampleCount(). * @requires_gl Always enabled in OpenGL ES and WebGL. */ Multisampling = GL_MULTISAMPLE, @@ -1531,7 +1531,7 @@ class MAGNUM_GL_EXPORT Renderer { * * For the reset notification to work, additionally to the extension * support the context must be created with - * @ref Platform::Sdl2Application::Configuration::Flag::RobustAccess "Platform::*Application::Configuration::Flag::RobustAccess" + * @ref Platform::Sdl2Application::GLConfiguration::Flag::RobustAccess "Platform::*Application::GLConfiguration::Flag::RobustAccess" * flag. * * @see @ref graphicsResetStatus(), @fn_gl_keyword{Get} with @@ -1596,12 +1596,12 @@ class MAGNUM_GL_EXPORT Renderer { * * For the reset notification to work, additionally to the extension * support the context must be created with - * @ref Platform::Sdl2Application::Configuration::Flag::RobustAccess "Platform::*Application::Configuration::Flag::RobustAccess" + * @ref Platform::Sdl2Application::GLConfiguration::Flag::RobustAccess "Platform::*Application::GLConfiguration::Flag::RobustAccess" * flag. * * If the reset occurs, @extension{ARB,robustness_isolation} * extension is supported and context is created with - * @ref Platform::Sdl2Application::Configuration::Flag::ResetIsolation "Platform::*Application::Configuration::Flag::ResetIsolation", + * @ref Platform::Sdl2Application::GLConfiguration::Flag::ResetIsolation "Platform::*Application::GLConfiguration::Flag::ResetIsolation", * advertised support for @extension{ARB,robustness_application_isolation} * indicates that no other application on the system will be affected * by the graphics reset. Advertised support for diff --git a/src/Magnum/Platform/AbstractXApplication.cpp b/src/Magnum/Platform/AbstractXApplication.cpp index d6f08e990..c9e815624 100644 --- a/src/Magnum/Platform/AbstractXApplication.cpp +++ b/src/Magnum/Platform/AbstractXApplication.cpp @@ -37,20 +37,42 @@ namespace Magnum { namespace Platform { -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, const Configuration& configuration): AbstractXApplication{contextHandler, arguments, NoCreate} { - createContext(configuration); +AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): AbstractXApplication{contextHandler, arguments, NoCreate} { + create(configuration, glConfiguration); } -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, NoCreateT): _contextHandler{contextHandler}, _context{new GLContext{NoCreate, arguments.argc, arguments.argv}}, _flags{Flag::Redraw} {} +AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, NoCreateT): _contextHandler{contextHandler}, _context{new GLContext{NoCreate, arguments.argc, arguments.argv}}, _flags{Flag::Redraw} {} -void AbstractXApplication::createContext() { createContext({}); } +void AbstractXApplication::create() { create({}); } -void AbstractXApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) std::exit(1); +void AbstractXApplication::create(const Configuration& configuration) { + create(configuration, GLConfiguration{}); } -bool AbstractXApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::AbstractXApplication::tryCreateContext(): context already created", false); +void AbstractXApplication::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { + if(!tryCreate(configuration, glConfiguration)) std::exit(1); +} + +bool AbstractXApplication::tryCreate(const Configuration& configuration) { + return tryCreate(configuration, GLConfiguration{}); +} + +bool AbstractXApplication::tryCreate(const Configuration& configuration, const GLConfiguration& + #ifndef MAGNUM_BUILD_DEPRECATED + glConfiguration + #else + _glConfiguration + #endif +) { + #ifdef MAGNUM_BUILD_DEPRECATED + GLConfiguration glConfiguration{_glConfiguration}; + CORRADE_IGNORE_DEPRECATED_PUSH + if(configuration.version() != GL::Version::None && glConfiguration.version() == GL::Version::None) + glConfiguration.setVersion(configuration.version()); + CORRADE_IGNORE_DEPRECATED_POP + #endif + + CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::AbstractXApplication::tryCreate(): context already created", false); _viewportSize = configuration.size(); @@ -66,7 +88,7 @@ bool AbstractXApplication::tryCreateContext(const Configuration& configuration) visTemplate.visualid = visualId; visInfo = XGetVisualInfo(_display, VisualIDMask, &visTemplate, &visualCount); if(!visInfo) { - Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot get X visual"; + Error() << "Platform::WindowlessGlxApplication::tryCreate(): cannot get X visual"; return false; } @@ -87,7 +109,7 @@ bool AbstractXApplication::tryCreateContext(const Configuration& configuration) XSetWMProtocols(_display, _window, &_deleteWindow, 1); /* Create context */ - _contextHandler->createContext(configuration, _window); + _contextHandler->createContext(glConfiguration, _window); /* Capture exposure, keyboard and mouse button events */ XSelectInput(_display, _window, INPUT_MASK); @@ -175,7 +197,12 @@ void AbstractXApplication::mousePressEvent(MouseEvent&) {} void AbstractXApplication::mouseReleaseEvent(MouseEvent&) {} void AbstractXApplication::mouseMoveEvent(MouseMoveEvent&) {} -AbstractXApplication::Configuration::Configuration(): _title("Magnum X Application"), _size(800, 600), _version(GL::Version::None) {} +AbstractXApplication::Configuration::Configuration(): + _title("Magnum X Application"), _size(800, 600) + #ifdef MAGNUM_BUILD_DEPRECATED + , _version(GL::Version::None) + #endif + {} AbstractXApplication::Configuration::~Configuration() = default; }} diff --git a/src/Magnum/Platform/AbstractXApplication.h b/src/Magnum/Platform/AbstractXApplication.h index a6f236a2a..17a5962d4 100644 --- a/src/Magnum/Platform/AbstractXApplication.h +++ b/src/Magnum/Platform/AbstractXApplication.h @@ -72,6 +72,7 @@ class AbstractXApplication { }; class Configuration; + class GLConfiguration; class InputEvent; class KeyEvent; class MouseEvent; @@ -106,17 +107,75 @@ class AbstractXApplication { this is faster than public pure virtual destructor */ ~AbstractXApplication(); - /** @copydoc Sdl2Application::createContext() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - void createContext(const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ - void createContext(const Configuration& configuration); - void createContext(); + /** + * @brief Create a window with given configuration for OpenGL context + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Must be called only if the context wasn't created by the constructor + * itself, i.e. when passing @ref NoCreate to it. Error message is + * printed and the program exits if the context cannot be created, see + * @ref tryCreate() for an alternative. + */ + void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Create a window with given configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ + void create(const Configuration& configuration); + + /** + * @brief Create a window with default configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&) with + * default-constructed @ref Configuration. + */ + void create(); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief create(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref create(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use create(const Configuration&, const GLConfiguration&) instead") void createContext(const Configuration& configuration) { + create(configuration); + } + + /** @brief @copybrief create() + * @deprecated Use @ref create() instead. + */ + CORRADE_DEPRECATED("use create() instead") void createContext() { + create(); + } #endif - /** @copydoc Sdl2Application::tryCreateContext() */ - bool tryCreateContext(const Configuration& configuration); + /** + * @brief Try to create context with given configuration for OpenGL context + * + * Unlike @ref create(const Configuration&, const GLConfiguration&) + * returns @cpp false @ce if the context cannot be created, + * @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Try to create context with given configuration and OpenGL context + * + * Unlike @ref create(const Configuration&) returns @cpp false @ce if + * the context cannot be created, @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief tryCreate(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref tryCreate(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use tryCreate(const Configuration&) instead") bool tryCreateContext(const Configuration& configuration) { + return tryCreate(configuration); + } + #endif /** @{ @name Screen handling */ @@ -171,9 +230,9 @@ 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, const GLConfiguration& glConfiguration); - explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, NoCreateT); + explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, NoCreateT); private: enum class Flag: unsigned int { @@ -188,7 +247,7 @@ class AbstractXApplication { Window _window; Atom _deleteWindow; - std::unique_ptr> _contextHandler; + std::unique_ptr> _contextHandler; std::unique_ptr _context; /** @todo Get this from the created window */ @@ -200,13 +259,37 @@ class AbstractXApplication { CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags) /** -@brief Configuration +@brief OpenGL context configuration Double-buffered OpenGL context. @see @ref GlxApplication::GlxApplication(), @ref XEglApplication::XEglApplication(), - @ref createContext(), @ref tryCreateContext() + @ref Configuration, @ref create(), @ref tryCreate() @todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness */ +class AbstractXApplication::GLConfiguration { + public: + explicit GLConfiguration(); + ~GLConfiguration(); + + /** @copydoc Sdl2Application::GLConfiguration::version() */ + GL::Version version() const { return _version; } + + /** @copydoc Sdl2Application::GLConfiguration::setVersion() */ + GLConfiguration& setVersion(GL::Version version) { + _version = version; + return *this; + } + + private: + GL::Version _version; +}; + +/** +@brief Configuration + +@see @ref GlxApplication::GlxApplication(), @ref XEglApplication::XEglApplication(), + @ref GLConfiguration, @ref create(), @ref tryCreate() +*/ class AbstractXApplication::Configuration { public: /*implicit*/ Configuration(); @@ -240,19 +323,27 @@ class AbstractXApplication::Configuration { return *this; } - /** @copydoc Sdl2Application::Configuration::version() */ - GL::Version version() const { return _version; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief GLConfiguration::version() + * @deprecated Use @ref GLConfiguration::version() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::version() instead") GL::Version version() const { return _version; } - /** @copydoc Sdl2Application::Configuration::setVersion() */ - Configuration& setVersion(GL::Version version) { + /** @brief @copybrief GLConfiguration::setVersion() + * @deprecated Use @ref GLConfiguration::setVersion() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::setVersion() instead") Configuration& setVersion(GL::Version version) { _version = version; return *this; } + #endif private: std::string _title; Vector2i _size; + #ifdef MAGNUM_BUILD_DEPRECATED GL::Version _version; + #endif }; /** diff --git a/src/Magnum/Platform/AndroidApplication.cpp b/src/Magnum/Platform/AndroidApplication.cpp index aa3b241a2..536a828f2 100644 --- a/src/Magnum/Platform/AndroidApplication.cpp +++ b/src/Magnum/Platform/AndroidApplication.cpp @@ -58,12 +58,12 @@ AndroidApplication::LogOutput::LogOutput(): redirectDebug{&debugStream}, redirectWarning{&warningStream}, redirectError{&errorStream} {} -#ifndef DOXYGEN_GENERATING_OUTPUT -AndroidApplication::AndroidApplication(const Arguments& arguments): AndroidApplication{arguments, Configuration{}} {} -#endif +AndroidApplication::AndroidApplication(const Arguments& arguments): AndroidApplication{arguments, Configuration{}, GLConfiguration{}} {} -AndroidApplication::AndroidApplication(const Arguments& arguments, const Configuration& configuration): AndroidApplication{arguments, NoCreate} { - createContext(configuration); +AndroidApplication::AndroidApplication(const Arguments& arguments, const Configuration& configuration): AndroidApplication{arguments, configuration, GLConfiguration{}} {} + +AndroidApplication::AndroidApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): AndroidApplication{arguments, NoCreate} { + create(configuration, glConfiguration); } AndroidApplication::AndroidApplication(const Arguments& arguments, NoCreateT): _state{arguments}, _context{new GLContext{NoCreate, 0, nullptr}} { @@ -82,19 +82,29 @@ ANativeActivity* AndroidApplication::nativeActivity() { return _state->activity; } -void AndroidApplication::createContext() { createContext({}); } +void AndroidApplication::create() { + create(Configuration{}, GLConfiguration{}); +} + +void AndroidApplication::create(const Configuration& configuration) { + create(configuration, GLConfiguration{}); +} + +void AndroidApplication::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { + if(!tryCreate(configuration, glConfiguration)) std::exit(32); +} -void AndroidApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) std::exit(32); +bool AndroidApplication::tryCreate(const Configuration& configuration) { + return tryCreate(configuration, GLConfiguration{}); } -bool AndroidApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(_context->version() == Version::None, "Platform::AndroidApplication::tryCreateContext(): context already created", false); +bool AndroidApplication::tryCreate(const Configuration& configuration, const GLConfiguration&) { + CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::AndroidApplication::tryCreate(): context already created", false); /* Initialize EGL */ _display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if(!eglInitialize(_display, nullptr, nullptr)) { - Error() << "Platform::AndroidApplication::tryCreateContext(): cannot initialize EGL:" + Error() << "Platform::AndroidApplication::tryCreate(): cannot initialize EGL:" << Implementation::eglErrorString(eglGetError()); return false; } @@ -111,7 +121,7 @@ bool AndroidApplication::tryCreateContext(const Configuration& configuration) { EGLint configCount; EGLConfig config; if(!eglChooseConfig(_display, configAttributes, &config, 1, &configCount)) { - Error() << "Platform::AndroidApplication::tryCreateContext(): cannot choose EGL config:" + Error() << "Platform::AndroidApplication::tryCreate(): cannot choose EGL config:" << Implementation::eglErrorString(eglGetError()); return false; } @@ -125,7 +135,7 @@ bool AndroidApplication::tryCreateContext(const Configuration& configuration) { /* Create surface and context */ if(!(_surface = eglCreateWindowSurface(_display, config, _state->window, nullptr))) { - Error() << "Platform::AndroidApplication::tryCreateContext(): cannot create EGL window surface:" + Error() << "Platform::AndroidApplication::tryCreate(): cannot create EGL window surface:" << Implementation::eglErrorString(eglGetError()); return false; } @@ -140,7 +150,7 @@ bool AndroidApplication::tryCreateContext(const Configuration& configuration) { EGL_NONE }; if(!(_glContext = eglCreateContext(_display, config, EGL_NO_CONTEXT, contextAttributes))) { - Error() << "Platform::AndroidApplication::tryCreateContext(): cannot create EGL context:" + Error() << "Platform::AndroidApplication::tryCreate(): cannot create EGL context:" << Implementation::eglErrorString(eglGetError()); return false; } diff --git a/src/Magnum/Platform/AndroidApplication.h b/src/Magnum/Platform/AndroidApplication.h index f731288a3..2019b2c72 100644 --- a/src/Magnum/Platform/AndroidApplication.h +++ b/src/Magnum/Platform/AndroidApplication.h @@ -141,6 +141,7 @@ class AndroidApplication { typedef android_app* Arguments; class Configuration; + class GLConfiguration; class InputEvent; class MouseEvent; class MouseMoveEvent; @@ -158,16 +159,42 @@ class AndroidApplication { } #endif - /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ - #ifdef DOXYGEN_GENERATING_OUTPUT - explicit AndroidApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ + /** + * @brief Construct with given configuration for OpenGL context + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Creates application with default or user-specified configuration. + * See @ref Configuration for more information. The program exits if + * the context cannot be created, see @ref tryCreate() for an + * alternative. + */ + explicit AndroidApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Construct with given configuration + * + * Equivalent to calling @ref AndroidApplication(const Arguments&, const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ explicit AndroidApplication(const Arguments& arguments, const Configuration& configuration); + + /** + * @brief Construct with default configuration + * + * Equivalent to calling @ref AndroidApplication(const Arguments&, const Configuration&) + * with default-constructed @ref Configuration. + */ explicit AndroidApplication(const Arguments& arguments); - #endif - /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, NoCreateT) */ + /** + * @brief Construct without creating a window + * @param arguments Application arguments + * + * Unlike above, the window is not created and must be created later + * with @ref create() or @ref tryCreate(). + */ explicit AndroidApplication(const Arguments& arguments, NoCreateT); #ifdef MAGNUM_BUILD_DEPRECATED @@ -200,17 +227,75 @@ class AndroidApplication { ANativeActivity* nativeActivity(); protected: - /** @copydoc Sdl2Application::createContext() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - void createContext(const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ - void createContext(const Configuration& configuration); - void createContext(); + /** + * @brief Create a window with given configuration for OpenGL context + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Must be called only if the context wasn't created by the constructor + * itself, i.e. when passing @ref NoCreate to it. Error message is + * printed and the program exits if the context cannot be created, see + * @ref tryCreate() for an alternative. + */ + void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Create a window with given configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ + void create(const Configuration& configuration); + + /** + * @brief Create a window with default configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&) with + * default-constructed @ref Configuration. + */ + void create(); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief create(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref create(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use create(const Configuration&, const GLConfiguration&) instead") void createContext(const Configuration& configuration) { + create(configuration); + } + + /** @brief @copybrief create() + * @deprecated Use @ref create() instead. + */ + CORRADE_DEPRECATED("use create() instead") void createContext() { + create(); + } #endif - /** @copydoc Sdl2Application::tryCreateContext() */ - bool tryCreateContext(const Configuration& configuration); + /** + * @brief Try to create context with given configuration for OpenGL context + * + * Unlike @ref create(const Configuration&, const GLConfiguration&) + * returns @cpp false @ce if the context cannot be created, + * @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Try to create context with given configuration and OpenGL context + * + * Unlike @ref create(const Configuration&) returns @cpp false @ce if + * the context cannot be created, @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief tryCreate(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref tryCreate(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use tryCreate(const Configuration&) instead") bool tryCreateContext(const Configuration& configuration) { + return tryCreate(configuration); + } + #endif /** @{ @name Screen handling */ @@ -290,7 +375,7 @@ class AndroidApplication { EGLSurface _surface; EGLContext _glContext; - std::unique_ptr _context; + std::unique_ptr _context; std::unique_ptr _logOutput; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) @@ -298,11 +383,34 @@ class AndroidApplication { CORRADE_ENUMSET_OPERATORS(AndroidApplication::Flags) +/** +@brief OpenGL context configuration + +Double-buffered RGBA canvas with depth and stencil buffers. +@see @ref AndroidApplication(), @ref Configuration, @ref create(), + @ref tryCreate() +*/ +class AndroidApplication::GLConfiguration { + public: + constexpr /*implicit*/ GLConfiguration() {} + + /** + * @brief Set context version + * + * @note This function does nothing and is included only for + * compatibility with other toolkits. @ref GL::Version::GLES200 or + * @ref GL::Version::GLES300 is used based on engine compile-time + * settings. + */ + GLConfiguration& setVersion(GL::Version) { return *this; } +}; + /** @brief Configuration Double-buffered RGBA canvas with depth and stencil buffers. -@see @ref AndroidApplication(), @ref createContext(), @ref tryCreateContext() +@see @ref AndroidApplication(), @ref GLConfiguration, @ref create(), + @ref tryCreate() */ class AndroidApplication::Configuration { public: @@ -334,15 +442,12 @@ class AndroidApplication::Configuration { return *this; } - /** - * @brief Set context version - * - * @note This function does nothing and is included only for - * compatibility with other toolkits. @ref GL::Version::GLES200 or - * @ref GL::Version::GLES300 is used based on engine compile-time - * settings. + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief GLConfiguration::setVersion() + * @deprecated Use @ref GLConfiguration::setVersion() instead. */ - Configuration& setVersion(Version) { return *this; } + CORRADE_DEPRECATED("use GLConfiguration::setVersion() instead") Configuration& setVersion(GL::Version) { return *this; } + #endif private: Vector2i _size; diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index 5950d0e41..3f0d73402 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -43,12 +43,14 @@ GlfwApplication* GlfwApplication::_instance = nullptr; static_assert(GLFW_TRUE == true && GLFW_FALSE == false, "GLFW does not have sane bool values"); #endif -#ifndef DOXYGEN_GENERATING_OUTPUT GlfwApplication::GlfwApplication(const Arguments& arguments): GlfwApplication{arguments, Configuration{}} {} -#endif GlfwApplication::GlfwApplication(const Arguments& arguments, const Configuration& configuration): GlfwApplication{arguments, NoCreate} { - createContext(configuration); + create(configuration); +} + +GlfwApplication::GlfwApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): GlfwApplication{arguments, NoCreate} { + create(configuration, glConfiguration); } GlfwApplication::GlfwApplication(const Arguments& arguments, NoCreateT): @@ -67,14 +69,44 @@ GlfwApplication::GlfwApplication(const Arguments& arguments, NoCreateT): } } -void GlfwApplication::createContext() { createContext({}); } +void GlfwApplication::create() { + create(Configuration{}); +} + +void GlfwApplication::create(const Configuration& configuration) { + if(!tryCreate(configuration)) std::exit(1); +} + +void GlfwApplication::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { + if(!tryCreate(configuration, glConfiguration)) std::exit(1); +} -void GlfwApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) std::exit(1); +bool GlfwApplication::tryCreate(const Configuration& configuration) { + return tryCreate(configuration, GLConfiguration{}); } -bool GlfwApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::GlfwApplication::tryCreateContext(): context already created", false); +bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConfiguration& + #ifndef MAGNUM_BUILD_DEPRECATED + glConfiguration + #else + _glConfiguration + #endif +) { + #ifdef MAGNUM_BUILD_DEPRECATED + GLConfiguration glConfiguration{_glConfiguration}; + CORRADE_IGNORE_DEPRECATED_PUSH + if(configuration.flags() && !glConfiguration.flags()) + glConfiguration.setFlags(configuration.flags()); + if(configuration.version() != GL::Version::None && glConfiguration.version() == GL::Version::None) + glConfiguration.setVersion(configuration.version()); + if(configuration.sampleCount() && !glConfiguration.sampleCount()) + glConfiguration.setSampleCount(configuration.sampleCount()); + if(configuration.isSRGBCapable() && !glConfiguration.isSRGBCapable()) + glConfiguration.setSRGBCapable(configuration.isSRGBCapable()); + CORRADE_IGNORE_DEPRECATED_POP + #endif + + CORRADE_ASSERT(!_window && _context->version() == GL::Version::None, "Platform::GlfwApplication::tryCreate(): context already created", false); /* Window flags */ GLFWmonitor* monitor = nullptr; /* Needed for setting fullscreen */ @@ -93,24 +125,24 @@ bool GlfwApplication::tryCreateContext(const Configuration& configuration) { glfwWindowHint(GLFW_FOCUSED, configuration.windowFlags() >= Configuration::WindowFlag::Focused); /* Context window hints */ - glfwWindowHint(GLFW_SAMPLES, configuration.sampleCount()); - glfwWindowHint(GLFW_SRGB_CAPABLE, configuration.isSRGBCapable()); + glfwWindowHint(GLFW_SAMPLES, glConfiguration.sampleCount()); + glfwWindowHint(GLFW_SRGB_CAPABLE, glConfiguration.isSRGBCapable()); - const Configuration::Flags& flags = configuration.flags(); + const GLConfiguration::Flags& flags = glConfiguration.flags(); #ifdef GLFW_CONTEXT_NO_ERROR - glfwWindowHint(GLFW_CONTEXT_NO_ERROR, flags >= Configuration::Flag::NoError); + glfwWindowHint(GLFW_CONTEXT_NO_ERROR, flags >= GLConfiguration::Flag::NoError); #endif - glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, flags >= Configuration::Flag::Debug); - glfwWindowHint(GLFW_STEREO, flags >= Configuration::Flag::Stereo); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, flags >= GLConfiguration::Flag::Debug); + glfwWindowHint(GLFW_STEREO, flags >= GLConfiguration::Flag::Stereo); /* Set context version, if requested */ - if(configuration.version() != GL::Version::None) { + if(glConfiguration.version() != GL::Version::None) { Int major, minor; - std::tie(major, minor) = version(configuration.version()); + std::tie(major, minor) = version(glConfiguration.version()); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor); #ifndef MAGNUM_TARGET_GLES - if(configuration.version() >= GL::Version::GL310) { + if(glConfiguration.version() >= GL::Version::GL310) { glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); } @@ -122,7 +154,7 @@ bool GlfwApplication::tryCreateContext(const Configuration& configuration) { /* Set context flags */ _window = glfwCreateWindow(configuration.size().x(), configuration.size().y(), configuration.title().c_str(), monitor, nullptr); if(!_window) { - Error() << "Platform::GlfwApplication::tryCreateContext(): cannot create context"; + Error() << "Platform::GlfwApplication::tryCreate(): cannot create context"; glfwTerminate(); return false; } @@ -262,10 +294,13 @@ void GlfwApplication::textInputEvent(TextInputEvent&) {} GlfwApplication::Configuration::Configuration(): _title{"Magnum GLFW Application"}, - _size{800, 600}, _sampleCount{0}, - _version{GL::Version::None}, + _size{800, 600}, _windowFlags{WindowFlag::Focused}, - _cursorMode{CursorMode::Normal} {} + _cursorMode{CursorMode::Normal} + #ifdef MAGNUM_BUILD_DEPRECATED + , _sampleCount{0}, _version{GL::Version::None} + #endif + {} GlfwApplication::Configuration::~Configuration() = default; diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index 6f77b66af..2ebb20ed6 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -123,6 +123,7 @@ class GlfwApplication { }; class Configuration; + class GLConfiguration; class InputEvent; class KeyEvent; class MouseEvent; @@ -130,16 +131,45 @@ class GlfwApplication { class MouseScrollEvent; class TextInputEvent; - /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ - #ifdef DOXYGEN_GENERATING_OUTPUT - explicit GlfwApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ + /** + * @brief Construct with given configuration for OpenGL context + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Creates application with default or user-specified configuration. + * See @ref Configuration for more information. The program exits if + * the context cannot be created, see @ref tryCreate() for an + * alternative. + */ + explicit GlfwApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Construct with given configuration and OpenGL context + * + * Equivalent to calling + * @ref GlfwApplication(const Arguments&, const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + * + * See also @ref building-features for more information. + */ explicit GlfwApplication(const Arguments& arguments, const Configuration& configuration); + + /** + * @brief Construct with default configuration + * + * Equivalent to calling @ref GlfwApplication(const Arguments&, const Configuration&) + * with default-constructed @ref Configuration. + */ explicit GlfwApplication(const Arguments& arguments); - #endif - /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, NoCreateT) */ + /** + * @brief Construct without creating a window + * @param arguments Application arguments + * + * Unlike above, the window is not created and must be created later + * with @ref create() or @ref tryCreate(). + */ explicit GlfwApplication(const Arguments& arguments, NoCreateT); #ifdef MAGNUM_BUILD_DEPRECATED @@ -187,17 +217,78 @@ class GlfwApplication { faster than public pure virtual destructor */ ~GlfwApplication(); - /** @copydoc Sdl2Application::createContext() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - void createContext(const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ - void createContext(const Configuration& configuration); - void createContext(); + /** + * @brief Create a window with given configuration for OpenGL context + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Must be called only if the context wasn't created by the constructor + * itself, i.e. when passing @ref NoCreate to it. Error message is + * printed and the program exits if the context cannot be created, see + * @ref tryCreate() for an alternative. + */ + void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Create a window with given configuration + * + * Equivalent to calling + * @ref create(const Configuration&, const GLConfiguration&) with + * default-constructed @ref GLConfiguration. + * + * See also @ref building-features for more information. + */ + void create(const Configuration& configuration); + + /** + * @brief Create a window with default configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&) with + * default-constructed @ref Configuration. + */ + void create(); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief create(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref create(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use create(const Configuration&, const GLConfiguration&) instead") void createContext(const Configuration& configuration) { + create(configuration); + } + + /** @brief @copybrief create() + * @deprecated Use @ref create() instead. + */ + CORRADE_DEPRECATED("use create() instead") void createContext() { + create(); + } #endif - /** @copydoc Sdl2Application::tryCreateContext() */ - bool tryCreateContext(const Configuration& configuration); + /** + * @brief Try to create context with given configuration for OpenGL context + * + * Unlike @ref create(const Configuration&, const GLConfiguration&) + * returns @cpp false @ce if the context cannot be created, + * @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Try to create context with given configuration + * + * Unlike @ref create(const Configuration&) returns @cpp false @ce if + * the context cannot be created, @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief tryCreate(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref tryCreate(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use tryCreate(const Configuration&) instead") bool tryCreateContext(const Configuration& configuration) { + return tryCreate(configuration); + } + #endif /** @{ @name Screen handling */ @@ -364,12 +455,12 @@ class GlfwApplication { CORRADE_ENUMSET_OPERATORS(GlfwApplication::Flags) /** -@brief Configuration +@brief OpenGL context configuration Double-buffered RGBA window with depth and stencil buffers. -@see @ref GlfwApplication(), @ref createContext(), @ref tryCreateContext() +@see @ref GlfwApplication(), @ref create(), @ref tryCreate() */ -class GlfwApplication::Configuration { +class GlfwApplication::GLConfiguration { public: /** * @brief Context flag @@ -399,6 +490,98 @@ class GlfwApplication::Configuration { */ typedef Containers::EnumSet Flags; + explicit GLConfiguration(); + ~GLConfiguration(); + + /** @brief Context flags */ + Flags flags() const { return _flags; } + + /** + * @brief Set context flags + * @return Reference to self (for method chaining) + * + * Default is no flag. + */ + GLConfiguration& setFlags(Flags flags) { + _flags = flags; + return *this; + } + + /** @brief Context version */ + GL::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 GL::Version::None, i.e. any provided version is used. + */ + GLConfiguration& setVersion(GL::Version version) { + _version = version; + return *this; + } + + /** @brief Sample count */ + Int sampleCount() const { return _sampleCount; } + + /** + * @brief Set sample count + * @return Reference to self (for method chaining) + * + * Default is @cpp 0 @ce, thus no multisampling. The actual sample + * count is ignored, GLFW either enables it or disables. See also + * @ref GL::Renderer::Feature::Multisampling. + */ + GLConfiguration& setSampleCount(Int count) { + _sampleCount = count; + return *this; + } + + /** @brief sRGB-capable default framebuffer */ + bool isSRGBCapable() const { + return _srgbCapable; + } + + /** + * @brief Set sRGB-capable default framebuffer + * @return Reference to self (for method chaining) + */ + GLConfiguration& setSRGBCapable(bool enabled) { + _srgbCapable = enabled; + return *this; + } + + private: + Int _sampleCount; + GL::Version _version; + Flags _flags; + bool _srgbCapable; +}; + +CORRADE_ENUMSET_OPERATORS(GlfwApplication::GLConfiguration::Flags) + +/** +@brief Configuration + +Double-buffered RGBA window with depth and stencil buffers. +@see @ref GlfwApplication(), @ref create(), @ref tryCreate() +*/ +class GlfwApplication::Configuration { + public: + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief GLConfiguration::Flag + * @deprecated Use @ref GLConfiguration::Flag instead. + */ + typedef GLConfiguration::Flag Flag; + + /** @brief @copybrief GLConfiguration::Flags + * @deprecated Use @ref GLConfiguration::Flags instead. + */ + typedef GLConfiguration::Flags Flags; + #endif + /** * @brief Window flag * @@ -488,20 +671,6 @@ class GlfwApplication::Configuration { return *this; } - /** @brief Context flags */ - Flags flags() const { return _flags; } - - /** - * @brief Set context flags - * @return Reference to self (for method chaining) - * - * Default is no flag. - */ - Configuration& setFlags(Flags flags) { - _flags = flags; - return *this; - } - /** @brief Window flags */ WindowFlags windowFlags() const { return _windowFlags; @@ -534,64 +703,75 @@ class GlfwApplication::Configuration { return *this; } - /** @brief Context version */ - GL::Version version() const { return _version; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief GLConfiguration::flags() + * @deprecated Use @ref GLConfiguration::flags() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::flags() instead") GLConfiguration::Flags flags() const { return _flags; } - /** - * @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 GL::Version::None, i.e. any provided version is used. + /** @brief @copybrief GLConfiguration::setFlags() + * @deprecated Use @ref GLConfiguration::setFlags() instead. */ - Configuration& setVersion(GL::Version version) { + CORRADE_DEPRECATED("use GLConfiguration::setFlags() instead") Configuration& setFlags(GLConfiguration::Flags flags) { + _flags = flags; + return *this; + } + + /** @brief @copybrief GLConfiguration::version() + * @deprecated Use @ref GLConfiguration::version() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::version() instead") GL::Version version() const { return _version; } + + /** @brief @copybrief GLConfiguration::setVersion() + * @deprecated Use @ref GLConfiguration::setVersion() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::setVersion() instead") Configuration& setVersion(GL::Version version) { _version = version; return *this; } - /** @brief Sample count */ - Int sampleCount() const { return _sampleCount; } + /** @brief @copybrief GLConfiguration::sampleCount() + * @deprecated Use @ref GLConfiguration::sampleCount() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::sampleCount() instead") Int sampleCount() const { return _sampleCount; } - /** - * @brief Set sample count - * @return Reference to self (for method chaining) - * - * Default is @cpp 0 @ce, thus no multisampling. The actual sample - * count is ignored, GLFW either enables it or disables. See also - * @ref GL::Renderer::Feature::Multisampling. + /** @brief @copybrief GLConfiguration::setSampleCount() + * @deprecated Use @ref GLConfiguration::setSampleCount() instead. */ - Configuration& setSampleCount(Int count) { + CORRADE_DEPRECATED("use GLConfiguration::setSampleCount() instead") Configuration& setSampleCount(Int count) { _sampleCount = count; return *this; } - /** @brief sRGB-capable default framebuffer */ - bool isSRGBCapable() const { + /** @brief @copybrief GLConfiguration::isSRGBCapable() + * @deprecated Use @ref GLConfiguration::isSRGBCapable() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::isSRGBCapable() instead") bool isSRGBCapable() const { return _srgbCapable; } - /** - * @brief Set sRGB-capable default framebuffer - * @return Reference to self (for method chaining) + /** @brief @copybrief GLConfiguration::setSRGBCapable() + * @deprecated Use @ref GLConfiguration::setSRGBCapable() instead. */ - Configuration& setSRGBCapable(bool enabled) { + CORRADE_DEPRECATED("use GLConfiguration::setSRGBCapable() instead") Configuration& setSRGBCapable(bool enabled) { _srgbCapable = enabled; return *this; } + #endif private: std::string _title; Vector2i _size; + WindowFlags _windowFlags; + CursorMode _cursorMode; + #ifdef MAGNUM_BUILD_DEPRECATED Int _sampleCount; GL::Version _version; Flags _flags; - WindowFlags _windowFlags; - CursorMode _cursorMode; bool _srgbCapable; + #endif }; -CORRADE_ENUMSET_OPERATORS(GlfwApplication::Configuration::Flags) CORRADE_ENUMSET_OPERATORS(GlfwApplication::Configuration::WindowFlags) /** diff --git a/src/Magnum/Platform/GlutApplication.cpp b/src/Magnum/Platform/GlutApplication.cpp index 76271d786..a9d53b6cb 100644 --- a/src/Magnum/Platform/GlutApplication.cpp +++ b/src/Magnum/Platform/GlutApplication.cpp @@ -35,12 +35,12 @@ namespace Magnum { namespace Platform { GlutApplication* GlutApplication::_instance = nullptr; -#ifndef DOXYGEN_GENERATING_OUTPUT -GlutApplication::GlutApplication(const Arguments& arguments): GlutApplication{arguments, Configuration{}} {} -#endif +GlutApplication::GlutApplication(const Arguments& arguments): GlutApplication{arguments, Configuration{}, GLConfiguration{}} {} -GlutApplication::GlutApplication(const Arguments& arguments, const Configuration& configuration): GlutApplication{arguments, NoCreate} { - createContext(configuration); +GlutApplication::GlutApplication(const Arguments& arguments, const Configuration& configuration): GlutApplication{arguments, configuration, GLConfiguration{}} {} + +GlutApplication::GlutApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): GlutApplication{arguments, NoCreate} { + create(configuration, glConfiguration); } GlutApplication::GlutApplication(const Arguments& arguments, NoCreateT): _context{new GLContext{NoCreate, arguments.argc, arguments.argv}} { @@ -52,39 +52,67 @@ GlutApplication::GlutApplication(const Arguments& arguments, NoCreateT): _contex glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); } -void GlutApplication::createContext() { createContext({}); } +void GlutApplication::create() { + create(Configuration{}, GLConfiguration{}); +} + +void GlutApplication::create(const Configuration& configuration) { + create(configuration, GLConfiguration{}); +} + +void GlutApplication::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { + if(!tryCreate(configuration, glConfiguration)) std::exit(1); +} -void GlutApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) std::exit(1); +bool GlutApplication::tryCreate(const Configuration& configuration) { + return tryCreate(configuration, GLConfiguration{}); } -bool GlutApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::GlutApplication::tryCreateContext(): context already created", false); +bool GlutApplication::tryCreate(const Configuration& configuration, const GLConfiguration& + #ifndef MAGNUM_BUILD_DEPRECATED + glConfiguration + #else + _glConfiguration + #endif +) { + #ifdef MAGNUM_BUILD_DEPRECATED + GLConfiguration glConfiguration{_glConfiguration}; + CORRADE_IGNORE_DEPRECATED_PUSH + if(configuration.flags() && !glConfiguration.flags()) + glConfiguration.setFlags(configuration.flags()); + if(configuration.version() != GL::Version::None && glConfiguration.version() == GL::Version::None) + glConfiguration.setVersion(configuration.version()); + if(configuration.sampleCount() && !glConfiguration.sampleCount()) + glConfiguration.setSampleCount(configuration.sampleCount()); + CORRADE_IGNORE_DEPRECATED_POP + #endif + + CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::GlutApplication::tryCreate(): context already created", false); unsigned int flags = GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL; /* Multisampling */ - if(configuration.sampleCount()) flags |= GLUT_MULTISAMPLE; + if(glConfiguration.sampleCount()) flags |= GLUT_MULTISAMPLE; glutInitDisplayMode(flags); glutInitWindowSize(configuration.size().x(), configuration.size().y()); /* Set context version, if requested */ - if(configuration.version() != GL::Version::None) { + if(glConfiguration.version() != GL::Version::None) { Int major, minor; - std::tie(major, minor) = version(configuration.version()); + std::tie(major, minor) = version(glConfiguration.version()); glutInitContextVersion(major, minor); #ifndef MAGNUM_TARGET_GLES - if(configuration.version() >= GL::Version::GL310) + if(glConfiguration.version() >= GL::Version::GL310) glutInitContextProfile(GLUT_CORE_PROFILE); #endif } /* Set context flags */ - glutInitContextFlags(int(configuration.flags())); + glutInitContextFlags(int(glConfiguration.flags())); if(!glutCreateWindow(configuration.title().data())) { - Error() << "Platform::GlutApplication::tryCreateContext(): cannot create context"; + Error() << "Platform::GlutApplication::tryCreate(): cannot create context"; return false; } glutReshapeFunc(staticViewportEvent); @@ -142,7 +170,12 @@ void GlutApplication::mousePressEvent(MouseEvent&) {} void GlutApplication::mouseReleaseEvent(MouseEvent&) {} void GlutApplication::mouseMoveEvent(MouseMoveEvent&) {} -GlutApplication::Configuration::Configuration(): _title("Magnum GLUT Application"), _size(800, 600), _sampleCount(0), _version(GL::Version::None) {} +GlutApplication::Configuration::Configuration(): + _title("Magnum GLUT Application"), _size(800, 600) + #ifdef MAGNUM_BUILD_DEPRECATED + , _sampleCount(0), _version(GL::Version::None) + #endif + {} GlutApplication::Configuration::~Configuration() = default; template class BasicScreen; diff --git a/src/Magnum/Platform/GlutApplication.h b/src/Magnum/Platform/GlutApplication.h index 8702d3813..71b7b9188 100644 --- a/src/Magnum/Platform/GlutApplication.h +++ b/src/Magnum/Platform/GlutApplication.h @@ -120,21 +120,48 @@ class GlutApplication { }; class Configuration; + class GLConfiguration; class InputEvent; class KeyEvent; class MouseEvent; class MouseMoveEvent; - /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ - #ifdef DOXYGEN_GENERATING_OUTPUT - explicit GlutApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ + /** + * @brief Construct with given configuration for OpenGL context + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Creates application with default or user-specified configuration. + * See @ref Configuration for more information. The program exits if + * the context cannot be created, see @ref tryCreate() for an + * alternative. + */ + explicit GlutApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Construct with given configuration + * + * Equivalent to calling @ref GlutApplication(const Arguments&, const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ explicit GlutApplication(const Arguments& arguments, const Configuration& configuration); + + /** + * @brief Construct with default configuration + * + * Equivalent to calling @ref GlutApplication(const Arguments&, const Configuration&) + * with default-constructed @ref Configuration. + */ explicit GlutApplication(const Arguments& arguments); - #endif - /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, NoCreateT) */ + /** + * @brief Construct without creating a window + * @param arguments Application arguments + * + * Unlike above, the window is not created and must be created later + * with @ref create() or @ref tryCreate(). + */ explicit GlutApplication(const Arguments& arguments, NoCreateT); #ifdef MAGNUM_BUILD_DEPRECATED @@ -173,17 +200,75 @@ class GlutApplication { faster than public pure virtual destructor */ ~GlutApplication(); - /** @copydoc Sdl2Application::createContext() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - void createContext(const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ - void createContext(const Configuration& configuration); - void createContext(); + /** + * @brief Create a window with given configuration for OpenGL context + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration + * + * Must be called only if the context wasn't created by the constructor + * itself, i.e. when passing @ref NoCreate to it. Error message is + * printed and the program exits if the context cannot be created, see + * @ref tryCreate() for an alternative. + */ + void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Create a window with given configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ + void create(const Configuration& configuration); + + /** + * @brief Create a window with default configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&) with + * default-constructed @ref Configuration. + */ + void create(); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief create(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref create(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use create(const Configuration&, const GLConfiguration&) instead") void createContext(const Configuration& configuration) { + create(configuration); + } + + /** @brief @copybrief create() + * @deprecated Use @ref create() instead. + */ + CORRADE_DEPRECATED("use create() instead") void createContext() { + create(); + } #endif - /** @copydoc Sdl2Application::tryCreateContext() */ - bool tryCreateContext(const Configuration& configuration); + /** + * @brief Try to create context with given configuration for OpenGL context + * + * Unlike @ref create(const Configuration&, const GLConfiguration&) + * returns @cpp false @ce if the context cannot be created, + * @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Try to create context with given configuration and OpenGL context + * + * Unlike @ref create(const Configuration&) returns @cpp false @ce if + * the context cannot be created, @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief tryCreate(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref tryCreate(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use tryCreate(const Configuration&) instead") bool tryCreateContext(const Configuration& configuration) { + return tryCreate(configuration); + } + #endif /** @{ @name Screen handling */ @@ -300,12 +385,13 @@ class GlutApplication { }; /** -@brief Configuration +@brief OpenGL context configuration Double-buffered RGBA window with depth and stencil buffers. -@see @ref GlutApplication(), @ref createContext(), @ref tryCreateContext() +@see @ref GlutApplication(), @ref Configuration, @ref create(), + @ref tryCreate() */ -class GlutApplication::Configuration { +class GlutApplication::GLConfiguration { public: /** * @brief Context flag @@ -327,6 +413,85 @@ class GlutApplication::Configuration { typedef Containers::EnumSet Flags; #endif + /*implicit*/ GLConfiguration(); + ~GLConfiguration(); + + /** @brief Context flags */ + Flags flags() const { return _flags; } + + /** + * @brief Set context flags + * @return Reference to self (for method chaining) + * + * Default is no flag. + */ + GLConfiguration& setFlags(Flags flags) { + _flags = flags; + return *this; + } + + /** @brief Context version */ + GL::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 GL::Version::None, i.e. any provided version is used. + */ + GLConfiguration& setVersion(GL::Version version) { + _version = version; + return *this; + } + + /** @brief Sample count */ + Int sampleCount() const { return _sampleCount; } + + /** + * @brief Set sample count + * @return Reference to self (for method chaining) + * + * Default is @cpp 0 @ce, thus no multisampling. The actual sample + * count is ignored, GLUT either enables it or disables. See also + * @ref GL::Renderer::Feature::Multisampling. + */ + GLConfiguration& setSampleCount(Int count) { + _sampleCount = count; + return *this; + } + + private: + std::string _title; + Vector2i _size; + Int _sampleCount; + GL::Version _version; + Flags _flags; +}; + +CORRADE_ENUMSET_OPERATORS(GlutApplication::GLConfiguration::Flags) + +/** +@brief Configuration + +@see @ref GlutApplication(), @ref GLConfiguration, @ref create(), + @ref tryCreate() +*/ +class GlutApplication::Configuration { + public: + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief GLConfiguration::Flag + * @deprecated Use @ref GLConfiguration::Flag instead. + */ + typedef GLConfiguration::Flag Flag; + + /** @brief @copybrief GLConfiguration::Flags + * @deprecated Use @ref GLConfiguration::Flags instead. + */ + typedef GLConfiguration::Flags Flags; + #endif + /*implicit*/ Configuration(); ~Configuration(); @@ -358,62 +523,57 @@ class GlutApplication::Configuration { return *this; } - /** @brief Context flags */ - Flags flags() const { return _flags; } + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief GLConfiguration::flags() + * @deprecated Use @ref GLConfiguration::flags() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::flags() instead") GLConfiguration::Flags flags() const { return _flags; } - /** - * @brief Set context flags - * @return Reference to self (for method chaining) - * - * Default is no flag. + /** @brief @copybrief GLConfiguration::setFlags() + * @deprecated Use @ref GLConfiguration::setFlags() instead. */ - Configuration& setFlags(Flags flags) { + CORRADE_DEPRECATED("use GLConfiguration::setFlags() instead") Configuration& setFlags(GLConfiguration::Flags flags) { _flags = flags; return *this; } - /** @brief Context version */ - GL::Version version() const { return _version; } + /** @brief @copybrief GLConfiguration::version() + * @deprecated Use @ref GLConfiguration::version() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::version() instead") GL::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 GL::Version::None, i.e. any provided version is used. + /** @brief @copybrief GLConfiguration::setVersion() + * @deprecated Use @ref GLConfiguration::setVersion() instead. */ - Configuration& setVersion(GL::Version version) { + CORRADE_DEPRECATED("use GLConfiguration::setVersion() instead") Configuration& setVersion(GL::Version version) { _version = version; return *this; } - /** @brief Sample count */ - Int sampleCount() const { return _sampleCount; } + /** @brief @copybrief GLConfiguration::sampleCount() + * @deprecated Use @ref GLConfiguration::sampleCount() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::sampleCount() instead") Int sampleCount() const { return _sampleCount; } - /** - * @brief Set sample count - * @return Reference to self (for method chaining) - * - * Default is @cpp 0 @ce, thus no multisampling. The actual sample - * count is ignored, GLUT either enables it or disables. See also - * @ref GL::Renderer::Feature::Multisampling. + /** @brief @copybrief GLConfiguration::setSampleCount() + * @deprecated Use @ref GLConfiguration::setSampleCount() instead. */ - Configuration& setSampleCount(Int count) { + CORRADE_DEPRECATED("use GLConfiguration::setSampleCount() instead") Configuration& setSampleCount(Int count) { _sampleCount = count; return *this; } + #endif private: std::string _title; Vector2i _size; + #ifdef MAGNUM_BUILD_DEPRECATED Int _sampleCount; GL::Version _version; Flags _flags; + #endif }; -CORRADE_ENUMSET_OPERATORS(GlutApplication::Configuration::Flags) - /** @brief Base for input events diff --git a/src/Magnum/Platform/GlxApplication.cpp b/src/Magnum/Platform/GlxApplication.cpp index bc1300451..080ed907e 100644 --- a/src/Magnum/Platform/GlxApplication.cpp +++ b/src/Magnum/Platform/GlxApplication.cpp @@ -30,7 +30,7 @@ namespace Magnum { namespace Platform { -GlxApplication::GlxApplication(const Arguments& arguments, const Configuration& configuration): AbstractXApplication(new Implementation::GlxContextHandler, arguments, configuration) {} +GlxApplication::GlxApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): AbstractXApplication{new Implementation::GlxContextHandler, arguments, configuration, glConfiguration} {} GlxApplication::GlxApplication(const Arguments& arguments, NoCreateT): AbstractXApplication{new Implementation::GlxContextHandler, arguments, NoCreate} {} diff --git a/src/Magnum/Platform/GlxApplication.h b/src/Magnum/Platform/GlxApplication.h index b5bf3c7ce..558b765b9 100644 --- a/src/Magnum/Platform/GlxApplication.h +++ b/src/Magnum/Platform/GlxApplication.h @@ -86,18 +86,18 @@ If no other application header is included, this class is also aliased to class GlxApplication: public AbstractXApplication { public: /** - * @brief Default constructor - * @param arguments Application arguments - * @param configuration Configuration + * @brief Construct with given configuration for OpenGL context + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration * * Creates application with default or user-specified configuration. - * See @ref AbstractXApplication::Configuration "Configuration" for + * See @ref AbstractXApplication::Configuration "Configuration" and + * @ref AbstractXApplication::GLConfiguration "GLConfiguration" for * more information. The program exits if the context cannot be - * created, see below for an alternative. - * @todoc make this copydoc from Sdl2Application when Doxygen is able - * to find Configuration subclass + * created, see @ref tryCreate() for an alternative. */ - explicit GlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); + explicit GlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration{}, const GLConfiguration& glConfiguration = GLConfiguration{}); /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, NoCreateT) */ explicit GlxApplication(const Arguments& arguments, NoCreateT); diff --git a/src/Magnum/Platform/Implementation/EglContextHandler.cpp b/src/Magnum/Platform/Implementation/EglContextHandler.cpp index 81d2276e4..b1ff4c832 100644 --- a/src/Magnum/Platform/Implementation/EglContextHandler.cpp +++ b/src/Magnum/Platform/Implementation/EglContextHandler.cpp @@ -98,7 +98,7 @@ VisualId EglContextHandler::getVisualId(EGLNativeDisplayType nativeDisplay) { return visualId; } -void EglContextHandler::createContext(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType window) { +void EglContextHandler::createContext(const AbstractXApplication::GLConfiguration& glConfiguration, EGLNativeWindowType window) { EGLint attributes[] = { /* Leave some space for optional attributes below */ EGL_NONE, EGL_NONE, @@ -111,9 +111,9 @@ void EglContextHandler::createContext(const AbstractXApplication::Configuration& /* 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() != GL::Version::None) { + if(glConfiguration.version() != GL::Version::None) { Int major, minor; - std::tie(major, minor) = version(configuration.version()); + std::tie(major, minor) = version(glConfiguration.version()); attributes[0] = EGL_CONTEXT_MAJOR_VERSION_KHR; attributes[1] = major; @@ -121,7 +121,7 @@ void EglContextHandler::createContext(const AbstractXApplication::Configuration& attributes[3] = minor; #ifndef MAGNUM_TARGET_GLES - if(configuration.version() >= GL::Version::GL310) { + if(glConfiguration.version() >= GL::Version::GL310) { attributes[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; attributes[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; } diff --git a/src/Magnum/Platform/Implementation/EglContextHandler.h b/src/Magnum/Platform/Implementation/EglContextHandler.h index aa6b34fb9..005970e98 100644 --- a/src/Magnum/Platform/Implementation/EglContextHandler.h +++ b/src/Magnum/Platform/Implementation/EglContextHandler.h @@ -53,13 +53,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(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType nativeWindow) override; + void createContext(const AbstractXApplication::GLConfiguration& glConfiguration, EGLNativeWindowType nativeWindow) override; void makeCurrent() override { eglMakeCurrent(display, surface, surface, context); diff --git a/src/Magnum/Platform/Implementation/GlxContextHandler.cpp b/src/Magnum/Platform/Implementation/GlxContextHandler.cpp index a4be7b8cb..c0fabbb1d 100644 --- a/src/Magnum/Platform/Implementation/GlxContextHandler.cpp +++ b/src/Magnum/Platform/Implementation/GlxContextHandler.cpp @@ -72,7 +72,7 @@ VisualID GlxContextHandler::getVisualId(Display* nativeDisplay) { return visualId; } -void GlxContextHandler::createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) { +void GlxContextHandler::createContext(const AbstractXApplication::GLConfiguration& glConfiguration, Window nativeWindow) { window = nativeWindow; GLint attributes[] = { @@ -85,9 +85,9 @@ void GlxContextHandler::createContext(const AbstractXApplication::Configuration& }; /* Set context version, if requested */ - if(configuration.version() != GL::Version::None) { + if(glConfiguration.version() != GL::Version::None) { Int major, minor; - std::tie(major, minor) = version(configuration.version()); + std::tie(major, minor) = version(glConfiguration.version()); attributes[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; attributes[1] = major; @@ -95,7 +95,7 @@ void GlxContextHandler::createContext(const AbstractXApplication::Configuration& attributes[3] = minor; #ifndef MAGNUM_TARGET_GLES - if(configuration.version() >= GL::Version::GL310) { + if(glConfiguration.version() >= GL::Version::GL310) { attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB; attributes[5] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; } diff --git a/src/Magnum/Platform/Implementation/GlxContextHandler.h b/src/Magnum/Platform/Implementation/GlxContextHandler.h index ce127ba17..aed2dc96b 100644 --- a/src/Magnum/Platform/Implementation/GlxContextHandler.h +++ b/src/Magnum/Platform/Implementation/GlxContextHandler.h @@ -46,13 +46,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() = default; ~GlxContextHandler(); VisualID getVisualId(Display* nativeDisplay) override; - void createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) override; + void createContext(const AbstractXApplication::GLConfiguration& glConfiguration, Window nativeWindow) override; void makeCurrent() override { glXMakeCurrent(display, window, context); diff --git a/src/Magnum/Platform/ScreenedApplication.h b/src/Magnum/Platform/ScreenedApplication.h index a9dd05662..58236bce7 100644 --- a/src/Magnum/Platform/ScreenedApplication.h +++ b/src/Magnum/Platform/ScreenedApplication.h @@ -100,23 +100,24 @@ template class BasicScreenedApplication: public Application, public: /** * @brief Default constructor - * @param arguments Application arguments - * @param configuration Configuration + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration * * Creates application with default or user-specified configuration. * See @ref Sdl2Application::Configuration "Configuration" for more * information. The program exits if the context cannot be created, see * below for an alternative. */ - explicit BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration = Application::Configuration()); + explicit BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration = typename Application::Configuration{}, const typename Application::GLConfiguration& glConfiguration = typename Application::GLConfiguration{}); /** * @brief Constructor - * @param arguments Application arguments + * @param arguments Application arguments * * Unlike above, the context is not created and must be created later - * with @ref Sdl2Application::createContext() "createContext()" or - * @ref Sdl2Application::tryCreateContext() "tryCreateContext()". + * with @ref Sdl2Application::create() "create()" or + * @ref Sdl2Application::tryCreate() "tryCreate()". */ explicit BasicScreenedApplication(const typename Application::Arguments& arguments, NoCreateT); diff --git a/src/Magnum/Platform/ScreenedApplication.hpp b/src/Magnum/Platform/ScreenedApplication.hpp index 068c1fdec..c06e4e686 100644 --- a/src/Magnum/Platform/ScreenedApplication.hpp +++ b/src/Magnum/Platform/ScreenedApplication.hpp @@ -43,7 +43,7 @@ template void BasicScreen::mousePressEvent(Mouse template void BasicScreen::mouseReleaseEvent(MouseEvent&) {} template void BasicScreen::mouseMoveEvent(MouseMoveEvent&) {} -template BasicScreenedApplication::BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration): Application(arguments, configuration) {} +template BasicScreenedApplication::BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration, const typename Application::GLConfiguration& glConfiguration): Application(arguments, configuration, glConfiguration) {} template BasicScreenedApplication::BasicScreenedApplication(const typename Application::Arguments& arguments, NoCreateT): Application(arguments, NoCreate) {} diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 799ac165e..e28367ff7 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -58,12 +58,14 @@ Sdl2Application::InputEvent::Modifiers fixedModifiers(Uint16 mod) { } -#ifndef DOXYGEN_GENERATING_OUTPUT -Sdl2Application::Sdl2Application(const Arguments& arguments): Sdl2Application{arguments, Configuration{}} {} -#endif +Sdl2Application::Sdl2Application(const Arguments& arguments): Sdl2Application{arguments, Configuration{}, GLConfiguration{}} {} Sdl2Application::Sdl2Application(const Arguments& arguments, const Configuration& configuration): Sdl2Application{arguments, NoCreate} { - createContext(configuration); + create(configuration); +} + +Sdl2Application::Sdl2Application(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): Sdl2Application{arguments, NoCreate} { + create(configuration, glConfiguration); } Sdl2Application::Sdl2Application(const Arguments& arguments, NoCreateT): _glContext{nullptr}, @@ -78,45 +80,79 @@ Sdl2Application::Sdl2Application(const Arguments& arguments, NoCreateT): _glCont } } -void Sdl2Application::createContext() { createContext({}); } +void Sdl2Application::create() { + create(Configuration{}); +} + +void Sdl2Application::create(const Configuration& configuration) { + if(!tryCreate(configuration)) std::exit(1); +} -void Sdl2Application::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) std::exit(1); +void Sdl2Application::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { + if(!tryCreate(configuration, glConfiguration)) std::exit(1); } -bool Sdl2Application::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::Sdl2Application::tryCreateContext(): context already created", false); +bool Sdl2Application::tryCreate(const Configuration& configuration) { + return tryCreate(configuration, GLConfiguration{}); +} + +bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConfiguration& + #ifndef MAGNUM_BUILD_DEPRECATED + glConfiguration + #else + _glConfiguration + #endif +) { + #ifdef MAGNUM_BUILD_DEPRECATED + GLConfiguration glConfiguration{_glConfiguration}; + CORRADE_IGNORE_DEPRECATED_PUSH + #ifndef CORRADE_TARGET_EMSCRIPTEN + if(configuration.flags() && !glConfiguration.flags()) + glConfiguration.setFlags(configuration.flags()); + if(configuration.version() != GL::Version::None && glConfiguration.version() == GL::Version::None) + glConfiguration.setVersion(configuration.version()); + #endif + if(configuration.sampleCount() && !glConfiguration.sampleCount()) + glConfiguration.setSampleCount(configuration.sampleCount()); + #ifndef CORRADE_TARGET_EMSCRIPTEN + if(configuration.isSRGBCapable() && !glConfiguration.isSRGBCapable()) + glConfiguration.setSRGBCapable(configuration.isSRGBCapable()); + #endif + CORRADE_IGNORE_DEPRECATED_POP + #endif + + CORRADE_ASSERT(_context->version() == GL::Version::None, "Platform::Sdl2Application::tryCreate(): context already created", false); /* Enable double buffering and 24bt depth buffer */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); /* Multisampling */ - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, configuration.sampleCount() > 1 ? 1 : 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, configuration.sampleCount()); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, glConfiguration.sampleCount() > 1 ? 1 : 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, glConfiguration.sampleCount()); #ifndef CORRADE_TARGET_EMSCRIPTEN /* sRGB */ - SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, configuration.isSRGBCapable()); + SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, glConfiguration.isSRGBCapable()); #endif /** @todo Remove when Emscripten has proper SDL2 support */ #ifndef CORRADE_TARGET_EMSCRIPTEN /* Set context version, if user-specified */ - if(configuration.version() != GL::Version::None) { + if(glConfiguration.version() != GL::Version::None) { Int major, minor; - std::tie(major, minor) = version(configuration.version()); + std::tie(major, minor) = version(glConfiguration.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() >= GL::Version::GL310 ? + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, glConfiguration.version() >= GL::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 - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(configuration.flags())); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags())); /* Request usable version otherwise */ } else { @@ -133,7 +169,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { 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(configuration.flags())|SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags())|SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); #else /* For ES the major context version is compile-time constant */ #ifdef MAGNUM_TARGET_GLES3 @@ -160,7 +196,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { configuration.size().x(), configuration.size().y(), SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN|Uint32(configuration.windowFlags())))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); + Error() << "Platform::Sdl2Application::tryCreate(): cannot create window:" << SDL_GetError(); return false; } @@ -181,7 +217,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { constexpr static const char amdVendorString[] = "ATI Technologies Inc."; const char* vendorString; #endif - if(configuration.version() == GL::Version::None && (!_glContext + if(glConfiguration.version() == GL::Version::None && (!_glContext #ifndef CORRADE_TARGET_APPLE /* Sorry about the UGLY code, HOPEFULLY THERE WON'T BE MORE WORKAROUNDS */ || (vendorString = reinterpret_cast(glGetString(GL_VENDOR)), @@ -196,7 +232,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { /* Don't print any warning when doing the NV workaround, because the bug will be there probably forever */ if(!_glContext) Warning() - << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:" + << "Platform::Sdl2Application::tryCreate(): cannot create core context:" << SDL_GetError() << "(falling back to compatibility context)"; else SDL_GL_DeleteContext(_glContext); @@ -205,14 +241,14 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { 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(configuration.flags())); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, int(glConfiguration.flags())); if(!(_window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, configuration.size().x(), configuration.size().y(), SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN|Uint32(configuration.windowFlags())))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); + Error() << "Platform::Sdl2Application::tryCreate(): cannot create window:" << SDL_GetError(); return false; } @@ -223,7 +259,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { /* Cannot create context (or fallback compatibility context on desktop) */ if(!_glContext) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create context:" << SDL_GetError(); + Error() << "Platform::Sdl2Application::tryCreate(): cannot create context:" << SDL_GetError(); SDL_DestroyWindow(_window); _window = nullptr; return false; @@ -241,7 +277,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { #else /* Emscripten-specific initialization */ if(!(_glContext = SDL_SetVideoMode(configuration.size().x(), configuration.size().y(), 24, SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF))) { - Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create context:" << SDL_GetError(); + Error() << "Platform::Sdl2Application::tryCreate(): cannot create context:" << SDL_GetError(); return false; } #endif @@ -525,21 +561,32 @@ void Sdl2Application::multiGestureEvent(MultiGestureEvent&) {} void Sdl2Application::textInputEvent(TextInputEvent&) {} void Sdl2Application::textEditingEvent(TextEditingEvent&) {} +Sdl2Application::GLConfiguration::GLConfiguration(): + _sampleCount(0) + #ifndef CORRADE_TARGET_EMSCRIPTEN + , _version(GL::Version::None), _sRGBCapable{false} + #endif + {} + +Sdl2Application::GLConfiguration::~GLConfiguration() = default; + Sdl2Application::Configuration::Configuration(): #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_IOS) _title("Magnum SDL2 Application"), #endif #ifdef CORRADE_TARGET_EMSCRIPTEN - _size{640, 480}, + _size{640, 480} #elif !defined(CORRADE_TARGET_IOS) - _size{800, 600}, + _size{800, 600} #else - _size{}, /* SDL2 detects someting for us */ + _size{} /* SDL2 detects someting for us */ #endif - _windowFlags{}, _sampleCount(0) + #ifdef MAGNUM_BUILD_DEPRECATED + , _sampleCount(0) #ifndef CORRADE_TARGET_EMSCRIPTEN , _version(GL::Version::None), _sRGBCapable{false} #endif + #endif {} Sdl2Application::Configuration::~Configuration() = default; diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index ee2b809a6..e2cf54de7 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -363,6 +363,7 @@ class Sdl2Application { }; class Configuration; + class GLConfiguration; class InputEvent; class KeyEvent; class MouseEvent; @@ -373,29 +374,40 @@ class Sdl2Application { class TextEditingEvent; /** - * @brief Default constructor - * @param arguments Application arguments - * @param configuration Configuration + * @brief Construct with given configuration for OpenGL context + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration * * Creates application with default or user-specified configuration. * See @ref Configuration for more information. The program exits if - * the context cannot be created, see @ref tryCreateContext() for an + * the context cannot be created, see @ref tryCreate() for an * alternative. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ + explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Construct with given configuration and default OpenGL context + * + * Equivalent to calling @ref Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration); + + /** + * @brief Construct with default configuration + * + * Equivalent to calling @ref Sdl2Application(const Arguments&, const Configuration&) + * with default-constructed @ref Configuration. + */ explicit Sdl2Application(const Arguments& arguments); - #endif /** - * @brief Constructor + * @brief Construct without creating a window * @param arguments Application arguments * - * Unlike above, the context is not created and must be created later - * with @ref createContext() or @ref tryCreateContext(). + * Unlike above, the window is not created and must be created later + * with @ref create() or @ref tryCreate(). */ explicit Sdl2Application(const Arguments& arguments, NoCreateT); @@ -462,33 +474,78 @@ class Sdl2Application { ~Sdl2Application(); /** - * @brief Create context with given configuration + * @brief Create a window with given configuration for OpenGL context + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration * - * Must be called if and only if the context wasn't created by the - * constructor itself. Error message is printed and the program exits - * if the context cannot be created, see @ref tryCreateContext() for an - * alternative. + * Must be called only if the context wasn't created by the constructor + * itself, i.e. when passing @ref NoCreate to it. Error message is + * printed and the program exits if the context cannot be created, see + * @ref tryCreate() for an alternative. * - * On desktop GL, if version is not specified in @p configuration, the - * application first tries to create core context (OpenGL 3.2+ on + * On desktop GL, if version is not specified in @p glConfiguration, + * the application first tries to create core context (OpenGL 3.2+ on * macOS, OpenGL 3.1+ elsewhere) and if that fails, falls back to * compatibility OpenGL 2.1 context. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - void createContext(const Configuration& configuration = Configuration()); - #else - /* To avoid "invalid use of incomplete type" */ - void createContext(const Configuration& configuration); - void createContext(); + void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + + /** + * @brief Create a window with given configuration and default OpenGL context + * + * Equivalent to calling @ref create(const Configuration&, const GLConfiguration&) + * with default-constructed @ref GLConfiguration. + */ + void create(const Configuration& configuration); + + /** + * @brief Create a window with default configuration and OpenGL context + * + * Equivalent to calling @ref create(const Configuration&) with + * default-constructed @ref Configuration. + */ + void create(); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief create(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref create(const Configuration&, const GLConfiguration&) instead. + */ + CORRADE_DEPRECATED("use create(const Configuration&, const GLConfiguration&) instead") void createContext(const Configuration& configuration) { + create(configuration); + } + + /** @brief @copybrief create() + * @deprecated Use @ref create() instead. + */ + CORRADE_DEPRECATED("use create() instead") void createContext() { + create(); + } #endif + /** + * @brief Try to create context with given configuration for OpenGL context + * + * Unlike @ref create() returns @cpp false @ce if the context cannot be + * created, @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + /** * @brief Try to create context with given configuration * - * Unlike @ref createContext() returns @cpp false @ce if the context - * cannot be created, @cpp true @ce otherwise. + * Unlike @ref create(const Configuration&) returns @cpp false @ce if + * the context cannot be created, @cpp true @ce otherwise. + */ + bool tryCreate(const Configuration& configuration); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @brief @copybrief tryCreate(const Configuration&, const GLConfiguration&) + * @deprecated Use @ref tryCreate(const Configuration&, const GLConfiguration&) instead. */ - bool tryCreateContext(const Configuration& configuration); + CORRADE_DEPRECATED("use tryCreate(const Configuration&, const GLConfiguration&) instead") bool tryCreateContext(const Configuration& configuration) { + return tryCreate(configuration); + } + #endif /** @{ @name Screen handling */ @@ -773,13 +830,13 @@ class Sdl2Application { }; /** -@brief Configuration +@brief OpenGL context configuration The created window is always with double-buffered OpenGL context and 24bit depth buffer. -@see @ref Sdl2Application(), @ref createContext(), @ref tryCreateContext() +@see @ref Sdl2Application(), @ref create(), @ref tryCreate() */ -class Sdl2Application::Configuration { +class Sdl2Application::GLConfiguration { public: #ifndef CORRADE_TARGET_EMSCRIPTEN /** @@ -813,6 +870,124 @@ class Sdl2Application::Configuration { #endif #endif + explicit GLConfiguration(); + ~GLConfiguration(); + + #ifndef CORRADE_TARGET_EMSCRIPTEN + /** + * @brief Context flags + * + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + Flags flags() const { return _flags; } + + /** + * @brief Set context flags + * @return Reference to self (for method chaining) + * + * Default is no flag. See also @ref GL::Context::flags(). + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + GLConfiguration& setFlags(Flags flags) { + _flags = flags; + return *this; + } + + /** + * @brief Context version + * + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + GL::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 GL::Version::None, i.e. any provided version is used. + * @note In @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" this function + * does nothing (@ref GL::Version::GLES200 or + * @ref GL::Version::GLES300 is used implicitly based on the + * target). + */ + GLConfiguration& setVersion(GL::Version version) { + #ifndef CORRADE_TARGET_EMSCRIPTEN + _version = version; + #else + static_cast(version); + #endif + return *this; + } + + /** @brief Sample count */ + Int sampleCount() const { return _sampleCount; } + + /** + * @brief Set sample count + * @return Reference to self (for method chaining) + * + * Default is @cpp 0 @ce, thus no multisampling. See also + * @ref GL::Renderer::Feature::Multisampling. + */ + GLConfiguration& setSampleCount(Int count) { + _sampleCount = count; + return *this; + } + + #ifndef CORRADE_TARGET_EMSCRIPTEN + /** + * @brief sRGB-capable default framebuffer + * + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + bool isSRGBCapable() const { return _sRGBCapable; } + + /** + * @brief Set sRGB-capable default framebuffer + * @return Reference to self (for method chaining) + * + * Default is @cpp false @ce. See also + * @ref GL::Renderer::Feature::FramebufferSRGB. + * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + */ + GLConfiguration& setSRGBCapable(bool enabled) { + _sRGBCapable = enabled; + return *this; + } + #endif + + private: + Int _sampleCount; + #ifndef CORRADE_TARGET_EMSCRIPTEN + GL::Version _version; + Flags _flags; + bool _sRGBCapable; + #endif +}; + +/** +@brief Configuration + +@see @ref Sdl2Application(), @ref GLConfiguration, @ref create(), + @ref tryCreate() +*/ +class Sdl2Application::Configuration { + public: + #if defined(MAGNUM_BUILD_DEPRECATED) && !defined(CORRADE_TARGET_EMSCRIPTEN) + /** @brief @copybrief GLConfiguration::Flag + * @deprecated Use @ref GLConfiguration::Flag instead. + */ + typedef GLConfiguration::Flag Flag; + + /** @brief @copybrief GLConfiguration::Flags + * @deprecated Use @ref GLConfiguration::Flags instead. + */ + typedef GLConfiguration::Flags Flags; + #endif + /** * @brief Window flag * @@ -924,47 +1099,31 @@ class Sdl2Application::Configuration { return *this; } + #ifdef MAGNUM_BUILD_DEPRECATED #ifndef CORRADE_TARGET_EMSCRIPTEN - /** - * @brief Context flags - * - * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + /** @brief @copybrief GLConfiguration::flags() + * @deprecated Use @ref GLConfiguration::flags() instead. */ - Flags flags() const { return _flags; } + CORRADE_DEPRECATED("use GLConfiguration::flags() instead") GLConfiguration::Flags flags() const { return _flags; } - /** - * @brief Set context flags - * @return Reference to self (for method chaining) - * - * Default is no flag. See also @ref GL::Context::flags(). - * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + /** @brief @copybrief GLConfiguration::setFlags() + * @deprecated Use @ref GLConfiguration::setFlags() instead. */ - Configuration& setFlags(Flags flags) { + CORRADE_DEPRECATED("use GLConfiguration::setFlags() instead") Configuration& setFlags(GLConfiguration::Flags flags) { _flags = flags; return *this; } - /** - * @brief Context version - * - * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + /** @brief @copybrief GLConfiguration::version() + * @deprecated Use @ref GLConfiguration::version() instead. */ - GL::Version version() const { return _version; } + CORRADE_DEPRECATED("use GLConfiguration::version() instead") GL::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 GL::Version::None, i.e. any provided version is used. - * @note In @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" this function - * does nothing (@ref GL::Version::GLES200 or - * @ref GL::Version::GLES300 is used implicitly based on the - * target). + /** @brief @copybrief GLConfiguration::setVersion() + * @deprecated Use @ref GLConfiguration::setVersion() instead. */ - Configuration& setVersion(GL::Version version) { + CORRADE_DEPRECATED("use GLConfiguration::setVersion() instead") Configuration& setVersion(GL::Version version) { #ifndef CORRADE_TARGET_EMSCRIPTEN _version = version; #else @@ -973,42 +1132,34 @@ class Sdl2Application::Configuration { return *this; } - /** @brief Sample count */ - Int sampleCount() const { return _sampleCount; } + /** @brief @copybrief GLConfiguration::sampleCount() + * @deprecated Use @ref GLConfiguration::sampleCount() instead. + */ + CORRADE_DEPRECATED("use GLConfiguration::sampleCount() instead") Int sampleCount() const { return _sampleCount; } - /** - * @brief Set sample count - * @return Reference to self (for method chaining) - * - * Default is @cpp 0 @ce, thus no multisampling. See also - * @ref GL::Renderer::Feature::Multisampling. + /** @brief @copybrief GLConfiguration::setSampleCount() + * @deprecated Use @ref GLConfiguration::setSampleCount() instead. */ - Configuration& setSampleCount(Int count) { + CORRADE_DEPRECATED("use GLConfiguration::setSampleCount() instead") Configuration& setSampleCount(Int count) { _sampleCount = count; return *this; } #ifndef CORRADE_TARGET_EMSCRIPTEN - /** - * @brief sRGB-capable default framebuffer - * - * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + /** @brief @copybrief GLConfiguration::isSRGBCapable() + * @deprecated Use @ref GLConfiguration::isSRGBCapable() instead. */ - bool isSRGBCapable() const { return _sRGBCapable; } + CORRADE_DEPRECATED("use GLConfiguration::isSRGBCapable() instead") bool isSRGBCapable() const { return _sRGBCapable; } - /** - * @brief Set sRGB-capable default framebuffer - * @return Reference to self (for method chaining) - * - * Default is @cpp false @ce. See also - * @ref GL::Renderer::Feature::FramebufferSRGB. - * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". + /** @brief @copybrief GLConfiguration::setSRGBCapable() + * @deprecated Use @ref GLConfiguration::setSRGBCapable() instead. */ - Configuration& setSRGBCapable(bool enabled) { + CORRADE_DEPRECATED("use GLConfiguration::setSRGBCapable() instead") Configuration& setSRGBCapable(bool enabled) { _sRGBCapable = enabled; return *this; } #endif + #endif private: #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_IOS) @@ -1016,12 +1167,14 @@ class Sdl2Application::Configuration { #endif Vector2i _size; WindowFlags _windowFlags; + #ifdef MAGNUM_BUILD_DEPRECATED Int _sampleCount; #ifndef CORRADE_TARGET_EMSCRIPTEN GL::Version _version; Flags _flags; bool _sRGBCapable; #endif + #endif }; /** @@ -1719,7 +1872,7 @@ typedef BasicScreenedApplication ScreenedApplication; CORRADE_ENUMSET_OPERATORS(Sdl2Application::Flags) #ifndef CORRADE_TARGET_EMSCRIPTEN -CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::Flags) +CORRADE_ENUMSET_OPERATORS(Sdl2Application::GLConfiguration::Flags) #endif CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::WindowFlags) CORRADE_ENUMSET_OPERATORS(Sdl2Application::InputEvent::Modifiers) diff --git a/src/Magnum/Platform/XEglApplication.cpp b/src/Magnum/Platform/XEglApplication.cpp index df7a247f8..8d52d41e0 100644 --- a/src/Magnum/Platform/XEglApplication.cpp +++ b/src/Magnum/Platform/XEglApplication.cpp @@ -30,7 +30,7 @@ namespace Magnum { namespace Platform { -XEglApplication::XEglApplication(const Arguments& arguments, const Configuration& configuration): AbstractXApplication(new Implementation::EglContextHandler, arguments, configuration) {} +XEglApplication::XEglApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): AbstractXApplication{new Implementation::EglContextHandler, arguments, configuration, glConfiguration} {} XEglApplication::XEglApplication(const Arguments& arguments, NoCreateT): AbstractXApplication{new Implementation::EglContextHandler, arguments, NoCreate} {} diff --git a/src/Magnum/Platform/XEglApplication.h b/src/Magnum/Platform/XEglApplication.h index 52ffd7c77..8c2d3609a 100644 --- a/src/Magnum/Platform/XEglApplication.h +++ b/src/Magnum/Platform/XEglApplication.h @@ -87,18 +87,18 @@ If no other application header is included, this class is also aliased to class XEglApplication: public AbstractXApplication { public: /** - * @brief Default constructor - * @param arguments Application arguments - * @param configuration Configuration + * @brief Construct with given configuration for OpenGL context + * @param arguments Application arguments + * @param configuration Application configuration + * @param glConfiguration OpenGL context configuration * * Creates application with default or user-specified configuration. - * See @ref AbstractXApplication::Configuration "Configuration" for + * See @ref AbstractXApplication::Configuration "Configuration" and + * @ref AbstractXApplication::GLConfiguration "GLConfiguration" for * more information. The program exits if the context cannot be - * created, see below for an alternative. - * @todoc make this copydoc from Sdl2Application when Doxygen is able - * to find Configuration subclass + * created, see @ref tryCreate() for an alternative. */ - explicit XEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); + explicit XEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration{}, const GLConfiguration& glConfiguration = GLConfiguration{}); /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, NoCreateT) */ explicit XEglApplication(const Arguments& arguments, NoCreateT);