diff --git a/CMakeLists.txt b/CMakeLists.txt index 3908b08b7..07db61be9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ option(WITH_SHADERS "Build Shaders library" ON) cmake_dependent_option(WITH_TEXT "Build Text library" ON "NOT WITH_FONTCONVERTER;NOT WITH_MAGNUMFONT;NOT WITH_MAGNUMFONTCONVERTER" ON) cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT WITH_TEXT;NOT WITH_DISTANCEFIELDCONVERTER" ON) cmake_dependent_option(WITH_TRADE "Build Trade library" ON "NOT WITH_MESHTOOLS;NOT WITH_PRIMITIVES;NOT WITH_IMAGECONVERTER;NOT WITH_ANYIMAGEIMPORTER;NOT WITH_ANYIMAGECONVERTER;NOT WITH_ANYSCENEIMPORTER;NOT WITH_OBJIMPORTER;NOT WITH_TGAIMAGECONVERTER;NOT WITH_TGAIMPORTER" ON) -cmake_dependent_option(WITH_GL "Build GL library" ON "NOT WITH_SHADERS;NOT WITH_TEXT;NOT WITH_GL_INFO;NOT WITH_ANDROIDAPPLICATION;NOT WITH_WINDOWLESSIOSAPPLICATION;NOT WITH_CGLCONTEXT;NOT WITH_GLXAPPLICATION;NOT WITH_GLXCONTEXT;NOT WITH_XEGLAPPLICATION;NOT WITH_WINDOWLESSWGLAPPLICATION;NOT WITH_GLXCONTEXT;NOT WITH_XEGLAPPLICATION;NOT WITH_WINDOWLESSWGLAPPLICATION;NOT WITH_WGLCONTEXT;NOT WITH_WINDOWLESSWINDOWSEGLAPPLICATION;NOT WITH_GLFWAPPLICATION;NOT WITH_GLUTAPPLICATION;NOT WITH_SDL2APPLICATION;NOT WITH_DISTANCEFIELDCONVERTER;NOT WITH_FONTCONVERTER;NOT WITH_IMAGECONVERTER" ON) +cmake_dependent_option(WITH_GL "Build GL library" ON "NOT WITH_SHADERS;NOT WITH_TEXT;NOT WITH_GL_INFO;NOT WITH_ANDROIDAPPLICATION;NOT WITH_WINDOWLESSIOSAPPLICATION;NOT WITH_CGLCONTEXT;NOT WITH_GLXAPPLICATION;NOT WITH_GLXCONTEXT;NOT WITH_XEGLAPPLICATION;NOT WITH_WINDOWLESSWGLAPPLICATION;NOT WITH_GLXCONTEXT;NOT WITH_XEGLAPPLICATION;NOT WITH_WINDOWLESSWGLAPPLICATION;NOT WITH_WGLCONTEXT;NOT WITH_WINDOWLESSWINDOWSEGLAPPLICATION;NOT WITH_GLUTAPPLICATION;NOT WITH_DISTANCEFIELDCONVERTER;NOT WITH_FONTCONVERTER;NOT WITH_IMAGECONVERTER" ON) option(WITH_PRIMITIVES "Builf Primitives library" ON) cmake_dependent_option(TARGET_GL "Build libraries with OpenGL interoperability" ON "WITH_GL" OFF) diff --git a/doc/building.dox b/doc/building.dox index 28c14e6a3..4111fb3d1 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -456,7 +456,7 @@ your platform best: GL library. - `WITH_GLFWAPPLICATION` --- Build the @ref Platform::GlfwApplication "GlfwApplication" library. Depends on - [GLFW](http://glfw.org). Enables also building of the GL library. + [GLFW](http://glfw.org). - `WITH_GLUTAPPLICATION` --- Build the @ref Platform::GlutApplication "GlutApplication" library. Depends on [GLUT](http://freeglut.sourceforge.net/). Enables also building of the GL @@ -466,7 +466,7 @@ your platform best: Enables also building of the GL library. - `WITH_SDL2APPLICATION` --- Build the @ref Platform::Sdl2Application "Sdl2Application" library. Depends on - [SDL2](http://www.libsdl.org). Enables also building of the GL library. + [SDL2](http://www.libsdl.org). - `WITH_XEGLAPPLICATION` --- Build the @ref Platform::XEglApplication "XEglApplication" library. Enables also building of the GL library. diff --git a/doc/changelog.dox b/doc/changelog.dox index b85fe30de..236252472 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -101,6 +101,10 @@ See also: @subsubsection changelog-latest-new-platform Platform libraries +- Ability to create @ref Platform::Sdl2Application and + @ref Platform::GlfwApplication classes without implicitly created OpenGL + context by passing @ref Platform::Sdl2Application::Configuration::WindowFlag::Contextless "Configuration::WindowFlag::Contextless" + to them. These two can be now also built completely without the GL library. - Added @ref Platform::AndroidApplication::windowSize() - Added @ref Platform::AndroidApplication::nativeActivity() to access underlying `ANativeActivity` structure for calling various Android APIs diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 90cc5ebb4..c57a51c11 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -395,10 +395,20 @@ endif() set(_MAGNUM_Trade_DEPENDENCIES ) set(_MAGNUM_AndroidApplication_DEPENDENCIES GL) -set(_MAGNUM_GlfwApplication_DEPENDENCIES GL) + +set(_MAGNUM_GlfwApplication_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + list(APPEND _MAGNUM_GlfwApplication_DEPENDENCIES GL) +endif() + set(_MAGNUM_GlutApplication_DEPENDENCIES GL) set(_MAGNUM_GlxApplication_DEPENDENCIES GL) -set(_MAGNUM_Sdl2Application_DEPENDENCIES GL) + +set(_MAGNUM_Sdl2Application_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + list(APPEND _MAGNUM_Sdl2Application_DEPENDENCIES GL) +endif() + set(_MAGNUM_WindowlessCglApplication_DEPENDENCIES GL) set(_MAGNUM_WindowlessEglApplication_DEPENDENCIES GL) set(_MAGNUM_WindowlessGlxApplication_DEPENDENCIES GL) diff --git a/src/Magnum/Platform/CMakeLists.txt b/src/Magnum/Platform/CMakeLists.txt index b65b520e8..05943e11b 100644 --- a/src/Magnum/Platform/CMakeLists.txt +++ b/src/Magnum/Platform/CMakeLists.txt @@ -41,7 +41,7 @@ set(MagnumPlatform_FILES ) install(FILES ${MagnumPlatform_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) # Decide about platform-specific context for cross-platform toolkits -if(WITH_GLFWAPPLICATION OR WITH_GLUTAPPLICATION OR WITH_SDL2APPLICATION) +if((WITH_GLFWAPPLICATION OR WITH_GLUTAPPLICATION OR WITH_SDL2APPLICATION) AND TARGET_GL) if(CORRADE_TARGET_APPLE AND NOT MAGNUM_TARGET_GLES) set(NEED_CGLCONTEXT 1) set(MagnumSomeContext_OBJECTS $) @@ -111,10 +111,11 @@ if(WITH_GLFWAPPLICATION) message(FATAL_ERROR "GLFW library, required by GlfwApplication, was not found. Set WITH_GLFWAPPLICATION to OFF to skip building it.") endif() - set(MagnumGlfwApplication_SRCS - GlfwApplication.cpp - ${MagnumSomeContext_OBJECTS}) + set(MagnumGlfwApplication_SRCS GlfwApplication.cpp) set(MagnumGlfwApplication_HEADERS GlfwApplication.h) + if(TARGET_GL) + list(APPEND MagnumGlfwApplication_SRCS ${MagnumSomeContext_OBJECTS}) + endif() add_library(MagnumGlfwApplication STATIC ${MagnumGlfwApplication_SRCS} @@ -124,7 +125,10 @@ if(WITH_GLFWAPPLICATION) FOLDER "Magnum/Platform") # Assuming that PIC is not needed because the Application lib is always # linked to the executable and not to any intermediate shared lib - target_link_libraries(MagnumGlfwApplication PUBLIC MagnumGL GLFW::GLFW) + target_link_libraries(MagnumGlfwApplication PUBLIC Magnum GLFW::GLFW) + if(TARGET_GL) + target_link_libraries(MagnumGlfwApplication PUBLIC MagnumGL) + endif() install(FILES ${MagnumGlfwApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumGlfwApplication @@ -176,10 +180,11 @@ if(WITH_SDL2APPLICATION) message(FATAL_ERROR "SDL2 library, required by Sdl2Application, was not found. Set WITH_SDL2APPLICATION to OFF to skip building it.") endif() - set(MagnumSdl2Application_SRCS - Sdl2Application.cpp - ${MagnumSomeContext_OBJECTS}) + set(MagnumSdl2Application_SRCS Sdl2Application.cpp) set(MagnumSdl2Application_HEADERS Sdl2Application.h) + if(TARGET_GL) + list(APPEND MagnumSdl2Application_SRCS ${MagnumSomeContext_OBJECTS}) + endif() add_library(MagnumSdl2Application STATIC ${MagnumSdl2Application_SRCS} @@ -189,7 +194,10 @@ if(WITH_SDL2APPLICATION) FOLDER "Magnum/Platform") # Assuming that PIC is not needed because the Application lib is always # linked to the executable and not to any intermediate shared lib - target_link_libraries(MagnumSdl2Application PUBLIC MagnumGL SDL2::SDL2) + target_link_libraries(MagnumSdl2Application PUBLIC Magnum SDL2::SDL2) + if(TARGET_GL) + target_link_libraries(MagnumSdl2Application PUBLIC MagnumGL) + endif() install(FILES ${MagnumSdl2Application_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) install(TARGETS MagnumSdl2Application diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index 3f0d73402..d1c31a17c 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -30,9 +30,12 @@ #include #include +#include "Magnum/Platform/ScreenedApplication.hpp" + +#ifdef MAGNUM_TARGET_GL #include "Magnum/GL/Version.h" #include "Magnum/Platform/GLContext.h" -#include "Magnum/Platform/ScreenedApplication.hpp" +#endif namespace Magnum { namespace Platform { @@ -49,13 +52,17 @@ GlfwApplication::GlfwApplication(const Arguments& arguments, const Configuration create(configuration); } +#ifdef MAGNUM_TARGET_GL GlfwApplication::GlfwApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): GlfwApplication{arguments, NoCreate} { create(configuration, glConfiguration); } +#endif GlfwApplication::GlfwApplication(const Arguments& arguments, NoCreateT): - _context{new GLContext{NoCreate, arguments.argc, arguments.argv}}, _flags{Flag::Redraw} + #ifdef MAGNUM_TARGET_GL + , _context{new GLContext{NoCreate, arguments.argc, arguments.argv}} + #endif { /* Save global instance */ _instance = this; @@ -67,6 +74,10 @@ GlfwApplication::GlfwApplication(const Arguments& arguments, NoCreateT): Error() << "Could not initialize GLFW"; std::exit(8); } + + #ifndef MAGNUM_TARGET_GL + static_cast(arguments); + #endif } void GlfwApplication::create() { @@ -77,14 +88,71 @@ void GlfwApplication::create(const Configuration& configuration) { if(!tryCreate(configuration)) std::exit(1); } +#ifdef MAGNUM_TARGET_GL void GlfwApplication::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { if(!tryCreate(configuration, glConfiguration)) std::exit(1); } +#endif bool GlfwApplication::tryCreate(const Configuration& configuration) { - return tryCreate(configuration, GLConfiguration{}); + #ifdef MAGNUM_TARGET_GL + #ifdef GLFW_NO_API + if(!(configuration.windowFlags() & Configuration::WindowFlag::Contextless)) + #endif + { + return tryCreate(configuration, GLConfiguration{}); + } + #endif + + CORRADE_ASSERT(!_window, "Platform::GlfwApplication::tryCreate(): window already created", false); + + /* Window flags */ + GLFWmonitor* monitor = nullptr; /* Needed for setting fullscreen */ + if (configuration.windowFlags() >= Configuration::WindowFlag::Fullscreen) { + monitor = glfwGetPrimaryMonitor(); + glfwWindowHint(GLFW_AUTO_ICONIFY, configuration.windowFlags() >= Configuration::WindowFlag::AutoIconify); + } else { + const Configuration::WindowFlags& flags = configuration.windowFlags(); + glfwWindowHint(GLFW_RESIZABLE, flags >= Configuration::WindowFlag::Resizable); + glfwWindowHint(GLFW_VISIBLE, !(flags >= Configuration::WindowFlag::Hidden)); + #ifdef GLFW_MAXIMIZED + glfwWindowHint(GLFW_MAXIMIZED, flags >= Configuration::WindowFlag::Maximized); + #endif + glfwWindowHint(GLFW_FLOATING, flags >= Configuration::WindowFlag::Floating); + } + glfwWindowHint(GLFW_FOCUSED, configuration.windowFlags() >= Configuration::WindowFlag::Focused); + + #ifdef GLFW_NO_API + /* Disable implicit GL context c/reation */ + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NO_API); + #endif + + /* Create the window */ + _window = glfwCreateWindow(configuration.size().x(), configuration.size().y(), configuration.title().c_str(), monitor, nullptr); + if(!_window) { + Error() << "Platform::GlfwApplication::tryCreate(): cannot create window"; + glfwTerminate(); + return false; + } + + /* Proceed with configuring other stuff that couldn't be done with window + hints */ + if(configuration.windowFlags() >= Configuration::WindowFlag::Minimized) + glfwIconifyWindow(_window); + glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode())); + + /* Set callbacks */ + glfwSetFramebufferSizeCallback(_window, staticViewportEvent); + glfwSetKeyCallback(_window, staticKeyEvent); + glfwSetCursorPosCallback(_window, staticMouseMoveEvent); + glfwSetMouseButtonCallback(_window, staticMouseEvent); + glfwSetScrollCallback(_window, staticMouseScrollEvent); + glfwSetCharCallback(_window, staticTextInputEvent); + + return true; } +#ifdef MAGNUM_TARGET_GL bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConfiguration& #ifndef MAGNUM_BUILD_DEPRECATED glConfiguration @@ -178,6 +246,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf /* Return true if the initialization succeeds */ return _context->tryCreate(); } +#endif GlfwApplication::~GlfwApplication() { glfwDestroyWindow(_window); @@ -292,12 +361,18 @@ void GlfwApplication::mouseMoveEvent(MouseMoveEvent&) {} void GlfwApplication::mouseScrollEvent(MouseScrollEvent&) {} void GlfwApplication::textInputEvent(TextInputEvent&) {} +#ifdef MAGNUM_TARGET_GL +GlfwApplication::GLConfiguration::GLConfiguration(): _sampleCount{0}, _version{GL::Version::None} {} + +GlfwApplication::GLConfiguration::~GLConfiguration() = default; +#endif + GlfwApplication::Configuration::Configuration(): _title{"Magnum GLFW Application"}, _size{800, 600}, _windowFlags{WindowFlag::Focused}, _cursorMode{CursorMode::Normal} - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) , _sampleCount{0}, _version{GL::Version::None} #endif {} diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index 2ebb20ed6..eccc2a956 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -36,12 +36,14 @@ #include "Magnum/Magnum.h" #include "Magnum/Tags.h" -#include "Magnum/GL/GL.h" #include "Magnum/Math/Vector2.h" #include "Magnum/Platform/Platform.h" +#ifdef MAGNUM_TARGET_GL +#include "Magnum/GL/GL.h" /* We must include our own GL headers first to avoid conflicts */ #include "Magnum/GL/OpenGL.h" +#endif #include @@ -123,7 +125,9 @@ class GlfwApplication { }; class Configuration; + #ifdef MAGNUM_TARGET_GL class GLConfiguration; + #endif class InputEvent; class KeyEvent; class MouseEvent; @@ -131,6 +135,7 @@ class GlfwApplication { class MouseScrollEvent; class TextInputEvent; + #ifdef MAGNUM_TARGET_GL /** * @brief Construct with given configuration for OpenGL context * @param arguments Application arguments @@ -141,13 +146,23 @@ class GlfwApplication { * See @ref Configuration for more information. The program exits if * the context cannot be created, see @ref tryCreate() for an * alternative. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. */ explicit GlfwApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration); + #endif /** - * @brief Construct with given configuration and OpenGL context + * @brief Construct with given configuration + * + * If @ref Configuration::WindowFlag::Contextless is present or Magnum + * was not built with @ref MAGNUM_TARGET_GL, this creates a window + * without any GPU context attached, leaving that part on the user. * - * Equivalent to calling + * If none of the flags is present and Magnum was built with + * @ref MAGNUM_TARGET_GL, this is equivalent to calling * @ref GlfwApplication(const Arguments&, const Configuration&, const GLConfiguration&) * with default-constructed @ref GLConfiguration. * @@ -217,6 +232,7 @@ class GlfwApplication { faster than public pure virtual destructor */ ~GlfwApplication(); + #ifdef MAGNUM_TARGET_GL /** * @brief Create a window with given configuration for OpenGL context * @param configuration Application configuration @@ -226,13 +242,23 @@ class GlfwApplication { * 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. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. */ void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + #endif /** * @brief Create a window with given configuration * - * Equivalent to calling + * If @ref Configuration::WindowFlag::Contextless is present or Magnum + * was not built with @ref MAGNUM_TARGET_GL, this creates a window + * without any GPU context attached, leaving that part on the user. + * + * If none of the flags is present and Magnum was built with + * @ref MAGNUM_TARGET_GL, this is equivalent to calling * @ref create(const Configuration&, const GLConfiguration&) with * default-constructed @ref GLConfiguration. * @@ -264,14 +290,20 @@ class GlfwApplication { } #endif + #ifdef MAGNUM_TARGET_GL /** * @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. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. */ bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + #endif /** * @brief Try to create context with given configuration @@ -448,12 +480,15 @@ class GlfwApplication { static GlfwApplication* _instance; GLFWwindow* _window; - std::unique_ptr _context; Flags _flags; + #ifdef MAGNUM_TARGET_GL + std::unique_ptr _context; + #endif }; CORRADE_ENUMSET_OPERATORS(GlfwApplication::Flags) +#ifdef MAGNUM_TARGET_GL /** @brief OpenGL context configuration @@ -561,6 +596,7 @@ class GlfwApplication::GLConfiguration { }; CORRADE_ENUMSET_OPERATORS(GlfwApplication::GLConfiguration::Flags) +#endif /** @brief Configuration @@ -570,7 +606,7 @@ Double-buffered RGBA window with depth and stencil buffers. */ class GlfwApplication::Configuration { public: - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) /** @brief @copybrief GLConfiguration::Flag * @deprecated Use @ref GLConfiguration::Flag instead. */ @@ -618,7 +654,21 @@ class GlfwApplication::Configuration { */ AutoIconify = 1 << 6, - Focused = 1 << 7 /**< Window has input focus */ + Focused = 1 << 7, /**< Window has input focus */ + + #if defined(DOXYGEN_GENERATING_OUTPUT) || defined(GLFW_NO_API) + /** + * Do not create any GPU context. Use together with + * @ref GlfwApplication(const Arguments&), + * @ref GlfwApplication(const Arguments&, const Configuration&), + * @ref create(const Configuration&) or + * @ref tryCreate(const Configuration&) to prevent implicit + * creation of an OpenGL context. + * + * @note Supported since GLFW 3.2. + */ + Contextless = 1 << 8 + #endif }; /** @@ -703,7 +753,7 @@ class GlfwApplication::Configuration { return *this; } - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) /** @brief @copybrief GLConfiguration::flags() * @deprecated Use @ref GLConfiguration::flags() instead. */ @@ -764,7 +814,7 @@ class GlfwApplication::Configuration { Vector2i _size; WindowFlags _windowFlags; CursorMode _cursorMode; - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) Int _sampleCount; GL::Version _version; Flags _flags; diff --git a/src/Magnum/Platform/ScreenedApplication.h b/src/Magnum/Platform/ScreenedApplication.h index 58236bce7..551001bec 100644 --- a/src/Magnum/Platform/ScreenedApplication.h +++ b/src/Magnum/Platform/ScreenedApplication.h @@ -98,18 +98,27 @@ The following specialization are explicitly compiled into each particular */ template class BasicScreenedApplication: public Application, private Containers::LinkedList> { public: + #ifdef MAGNUM_TARGET_GL /** - * @brief Default constructor - * @param arguments Application arguments - * @param configuration Application configuration - * @param glConfiguration OpenGL context configuration + * @brief Construct with given configuration for OpenGL context + * + * Passes the arguments through to a particular application + * constructor. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. + */ + explicit BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration, const typename Application::GLConfiguration& glConfiguration); + #endif + + /** + * @brief Construct with given 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. + * Passes the arguments through to a particular application + * constructor. */ - explicit BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration = typename Application::Configuration{}, const typename Application::GLConfiguration& glConfiguration = typename Application::GLConfiguration{}); + explicit BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration = typename Application::Configuration{}); /** * @brief Constructor diff --git a/src/Magnum/Platform/ScreenedApplication.hpp b/src/Magnum/Platform/ScreenedApplication.hpp index c06e4e686..e1fb5c1b2 100644 --- a/src/Magnum/Platform/ScreenedApplication.hpp +++ b/src/Magnum/Platform/ScreenedApplication.hpp @@ -43,7 +43,11 @@ template void BasicScreen::mousePressEvent(Mouse template void BasicScreen::mouseReleaseEvent(MouseEvent&) {} template void BasicScreen::mouseMoveEvent(MouseMoveEvent&) {} +#ifdef MAGNUM_TARGET_GL template BasicScreenedApplication::BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration, const typename Application::GLConfiguration& glConfiguration): Application(arguments, configuration, glConfiguration) {} +#endif + +template BasicScreenedApplication::BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration): Application(arguments, configuration) {} 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 e28367ff7..c0922ebd5 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -32,11 +32,14 @@ #include #endif -#include "Magnum/GL/Version.h" #include "Magnum/Math/Range.h" -#include "Magnum/Platform/GLContext.h" #include "Magnum/Platform/ScreenedApplication.hpp" +#ifdef MAGNUM_TARGET_GL +#include "Magnum/GL/Version.h" +#include "Magnum/Platform/GLContext.h" +#endif + namespace Magnum { namespace Platform { namespace { @@ -58,26 +61,35 @@ Sdl2Application::InputEvent::Modifiers fixedModifiers(Uint16 mod) { } -Sdl2Application::Sdl2Application(const Arguments& arguments): Sdl2Application{arguments, Configuration{}, GLConfiguration{}} {} +Sdl2Application::Sdl2Application(const Arguments& arguments): Sdl2Application{arguments, Configuration{}} {} Sdl2Application::Sdl2Application(const Arguments& arguments, const Configuration& configuration): Sdl2Application{arguments, NoCreate} { create(configuration); } +#ifdef MAGNUM_TARGET_GL Sdl2Application::Sdl2Application(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration): Sdl2Application{arguments, NoCreate} { create(configuration, glConfiguration); } +#endif -Sdl2Application::Sdl2Application(const Arguments& arguments, NoCreateT): _glContext{nullptr}, +Sdl2Application::Sdl2Application(const Arguments& arguments, NoCreateT): #ifndef CORRADE_TARGET_EMSCRIPTEN _minimalLoopPeriod{0}, #endif - _context{new GLContext{NoCreate, arguments.argc, arguments.argv}}, _flags{Flag::Redraw} + #ifdef MAGNUM_TARGET_GL + _glContext{nullptr}, _context{new GLContext{NoCreate, arguments.argc, arguments.argv}}, + #endif + _flags{Flag::Redraw} { if(SDL_Init(SDL_INIT_VIDEO) < 0) { Error() << "Cannot initialize SDL."; std::exit(1); } + + #ifndef MAGNUM_TARGET_GL + static_cast(arguments); + #endif } void Sdl2Application::create() { @@ -88,14 +100,45 @@ void Sdl2Application::create(const Configuration& configuration) { if(!tryCreate(configuration)) std::exit(1); } +#ifdef MAGNUM_TARGET_GL void Sdl2Application::create(const Configuration& configuration, const GLConfiguration& glConfiguration) { if(!tryCreate(configuration, glConfiguration)) std::exit(1); } +#endif bool Sdl2Application::tryCreate(const Configuration& configuration) { - return tryCreate(configuration, GLConfiguration{}); + #ifdef MAGNUM_TARGET_GL + if(!(configuration.windowFlags() & Configuration::WindowFlag::Contextless)) + return tryCreate(configuration, GLConfiguration{}); + #endif + + #ifndef CORRADE_TARGET_EMSCRIPTEN + /* Create window */ + if(!(_window = SDL_CreateWindow( + #ifndef CORRADE_TARGET_IOS + configuration.title().data(), + #else + nullptr, + #endif + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + configuration.size().x(), configuration.size().y(), + Uint32(configuration.windowFlags()&~Configuration::WindowFlag::Contextless)))) + { + Error() << "Platform::Sdl2Application::tryCreate(): cannot create window:" << SDL_GetError(); + return false; + } + #else + /* Emscripten-specific initialization */ + if(!(_glContext = SDL_SetVideoMode(configuration.size().x(), configuration.size().y(), 24, SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF))) { + Error() << "Platform::Sdl2Application::tryCreate(): cannot create window:" << SDL_GetError(); + return false; + } + #endif + + return true; } +#ifdef MAGNUM_TARGET_GL bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConfiguration& #ifndef MAGNUM_BUILD_DEPRECATED glConfiguration @@ -246,7 +289,7 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf 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())))) + SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN|Uint32(configuration.windowFlags()&~Configuration::WindowFlag::Contextless)))) { Error() << "Platform::Sdl2Application::tryCreate(): cannot create window:" << SDL_GetError(); return false; @@ -303,6 +346,7 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf /* Return true if the initialization succeeds */ return true; } +#endif Vector2i Sdl2Application::windowSize() { #ifndef CORRADE_TARGET_EMSCRIPTEN @@ -344,14 +388,19 @@ bool Sdl2Application::setSwapInterval(const Int interval) { } Sdl2Application::~Sdl2Application() { + #ifdef MAGNUM_TARGET_GL _context.reset(); #ifndef CORRADE_TARGET_EMSCRIPTEN SDL_GL_DeleteContext(_glContext); - SDL_DestroyWindow(_window); #else SDL_FreeSurface(_glContext); #endif + #endif + + #ifndef CORRADE_TARGET_EMSCRIPTEN + SDL_DestroyWindow(_window); + #endif SDL_Quit(); } @@ -561,6 +610,7 @@ void Sdl2Application::multiGestureEvent(MultiGestureEvent&) {} void Sdl2Application::textInputEvent(TextInputEvent&) {} void Sdl2Application::textEditingEvent(TextEditingEvent&) {} +#ifdef MAGNUM_TARGET_GL Sdl2Application::GLConfiguration::GLConfiguration(): _sampleCount(0) #ifndef CORRADE_TARGET_EMSCRIPTEN @@ -569,6 +619,7 @@ Sdl2Application::GLConfiguration::GLConfiguration(): {} Sdl2Application::GLConfiguration::~GLConfiguration() = default; +#endif Sdl2Application::Configuration::Configuration(): #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_IOS) @@ -581,7 +632,7 @@ Sdl2Application::Configuration::Configuration(): #else _size{} /* SDL2 detects someting for us */ #endif - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) , _sampleCount(0) #ifndef CORRADE_TARGET_EMSCRIPTEN , _version(GL::Version::None), _sRGBCapable{false} diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index e2cf54de7..6c32b0adb 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -36,10 +36,13 @@ #include "Magnum/Magnum.h" #include "Magnum/Tags.h" -#include "Magnum/GL/GL.h" #include "Magnum/Math/Vector2.h" #include "Magnum/Platform/Platform.h" +#ifdef MAGNUM_TARGET_GL +#include "Magnum/GL/GL.h" +#endif + #ifdef CORRADE_TARGET_WINDOWS /* Windows version of SDL2 redefines main(), we don't want that */ #define SDL_MAIN_HANDLED #endif @@ -363,7 +366,9 @@ class Sdl2Application { }; class Configuration; + #ifdef MAGNUM_TARGET_GL class GLConfiguration; + #endif class InputEvent; class KeyEvent; class MouseEvent; @@ -373,6 +378,7 @@ class Sdl2Application { class TextInputEvent; class TextEditingEvent; + #ifdef MAGNUM_TARGET_GL /** * @brief Construct with given configuration for OpenGL context * @param arguments Application arguments @@ -383,14 +389,27 @@ class Sdl2Application { * See @ref Configuration for more information. The program exits if * the context cannot be created, see @ref tryCreate() for an * alternative. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. */ explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration); + #endif /** - * @brief Construct with given configuration and default OpenGL context + * @brief Construct with given configuration + * + * If @ref Configuration::WindowFlag::Contextless is present or Magnum + * was not built with @ref MAGNUM_TARGET_GL, this creates a window + * without any GPU context attached, leaving that part on the user. * - * Equivalent to calling @ref Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&) + * If none of the flags is present and Magnum was built with + * @ref MAGNUM_TARGET_GL, this is equivalent to calling + * @ref Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&) * with default-constructed @ref GLConfiguration. + * + * See also @ref building-features for more information. */ explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration); @@ -473,6 +492,7 @@ class Sdl2Application { faster than public pure virtual destructor */ ~Sdl2Application(); + #ifdef MAGNUM_TARGET_GL /** * @brief Create a window with given configuration for OpenGL context * @param configuration Application configuration @@ -487,14 +507,27 @@ class Sdl2Application { * 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. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. */ void create(const Configuration& configuration, const GLConfiguration& glConfiguration); + #endif /** - * @brief Create a window with given configuration and default OpenGL context + * @brief Create a window with given configuration * - * Equivalent to calling @ref create(const Configuration&, const GLConfiguration&) - * with default-constructed @ref GLConfiguration. + * If @ref Configuration::WindowFlag::Contextless is present or Magnum + * was not built with @ref MAGNUM_TARGET_GL, this creates a window + * without any GPU context attached, leaving that part on the user. + * + * If none of the flags is present and Magnum was built with + * @ref MAGNUM_TARGET_GL, this is 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); @@ -506,7 +539,7 @@ class Sdl2Application { */ void create(); - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) /** @brief @copybrief create(const Configuration&, const GLConfiguration&) * @deprecated Use @ref create(const Configuration&, const GLConfiguration&) instead. */ @@ -522,13 +555,20 @@ class Sdl2Application { } #endif + #ifdef MAGNUM_TARGET_GL /** * @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. + * Unlike @ref create(const Configuration&, const GLConfiguration&) + * returns @cpp false @ce if the context cannot be created, + * @cpp true @ce otherwise. + * + * @note This function is available only if Magnum is compiled with + * @ref MAGNUM_TARGET_GL enabled (done by default). See + * @ref building-features for more information. */ bool tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration); + #endif /** * @brief Try to create context with given configuration @@ -538,7 +578,7 @@ class Sdl2Application { */ bool tryCreate(const Configuration& configuration); - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) /** @brief @copybrief tryCreate(const Configuration&, const GLConfiguration&) * @deprecated Use @ref tryCreate(const Configuration&, const GLConfiguration&) instead. */ @@ -818,22 +858,32 @@ class Sdl2Application { #ifndef CORRADE_TARGET_EMSCRIPTEN SDL_Window* _window; - SDL_GLContext _glContext; UnsignedInt _minimalLoopPeriod; + #endif + + #ifdef MAGNUM_TARGET_GL + #ifndef CORRADE_TARGET_EMSCRIPTEN + SDL_GLContext _glContext; #else SDL_Surface* _glContext; #endif - std::unique_ptr _context; + #endif Flags _flags; }; +#ifdef MAGNUM_TARGET_GL /** @brief OpenGL context configuration The created window is always with double-buffered OpenGL context and 24bit depth buffer. + +@note This function is available only if Magnum is compiled with + @ref MAGNUM_TARGET_GL enabled (done by default). See @ref building-features + for more information. + @see @ref Sdl2Application(), @ref create(), @ref tryCreate() */ class Sdl2Application::GLConfiguration { @@ -968,6 +1018,11 @@ class Sdl2Application::GLConfiguration { #endif }; +#ifndef CORRADE_TARGET_EMSCRIPTEN +CORRADE_ENUMSET_OPERATORS(Sdl2Application::GLConfiguration::Flags) +#endif +#endif + /** @brief Configuration @@ -976,7 +1031,7 @@ class Sdl2Application::GLConfiguration { */ class Sdl2Application::Configuration { public: - #if defined(MAGNUM_BUILD_DEPRECATED) && !defined(CORRADE_TARGET_EMSCRIPTEN) + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(CORRADE_TARGET_EMSCRIPTEN) /** @brief @copybrief GLConfiguration::Flag * @deprecated Use @ref GLConfiguration::Flag instead. */ @@ -1019,7 +1074,16 @@ class Sdl2Application::Configuration { Hidden = SDL_WINDOW_HIDDEN, /**< Hidden window */ Maximized = SDL_WINDOW_MAXIMIZED, /**< Maximized window */ Minimized = SDL_WINDOW_MINIMIZED, /**< Minimized window */ - MouseLocked = SDL_WINDOW_INPUT_GRABBED /**< Window with mouse locked */ + MouseLocked = SDL_WINDOW_INPUT_GRABBED, /**< Window with mouse locked */ + + /** + * Do not create any GPU context. Use together with + * @ref Sdl2Application(const Arguments&, const Configuration&), + * @ref create(const Configuration&) or + * @ref tryCreate(const Configuration&) to prevent implicit + * creation of an OpenGL context. + */ + Contextless = 1u << 31 /* Hope this won't ever conflict with anything */ }; /** @@ -1099,7 +1163,7 @@ class Sdl2Application::Configuration { return *this; } - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) #ifndef CORRADE_TARGET_EMSCRIPTEN /** @brief @copybrief GLConfiguration::flags() * @deprecated Use @ref GLConfiguration::flags() instead. @@ -1167,7 +1231,7 @@ class Sdl2Application::Configuration { #endif Vector2i _size; WindowFlags _windowFlags; - #ifdef MAGNUM_BUILD_DEPRECATED + #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) Int _sampleCount; #ifndef CORRADE_TARGET_EMSCRIPTEN GL::Version _version; @@ -1871,9 +1935,6 @@ typedef BasicScreenedApplication ScreenedApplication; #endif CORRADE_ENUMSET_OPERATORS(Sdl2Application::Flags) -#ifndef CORRADE_TARGET_EMSCRIPTEN -CORRADE_ENUMSET_OPERATORS(Sdl2Application::GLConfiguration::Flags) -#endif CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::WindowFlags) CORRADE_ENUMSET_OPERATORS(Sdl2Application::InputEvent::Modifiers) CORRADE_ENUMSET_OPERATORS(Sdl2Application::MouseMoveEvent::Buttons)