diff --git a/doc/platform.dox b/doc/platform.dox index 6323bc516..54798e3df 100644 --- a/doc/platform.dox +++ b/doc/platform.dox @@ -263,25 +263,25 @@ MyApplication::MyApplication(int& argc, char** argv): Platform::Application(argc @section platform-custom Using custom platform toolkits In case you want to use some not-yet-supported toolkit or you don't want to use -the wrappers in @ref Platform namespace, you can initialize %Magnum manually. -All you need is to create OpenGL context and then create instance of -@ref Context class, which will take care of proper initialization and feature -detection. The instance must be alive for whole application lifetime. Example -`main()` function with manual initialization: +the application wrappers in @ref Platform namespace, you can initialize %Magnum +manually. First create OpenGL context and then create instance of +@ref Platform::Context class, which will take care of proper initialization and +feature detection. The instance must be alive for whole application lifetime. +Example `main()` function with manual initialization: @code int main(int argc, char** argv) { // Create OpenGL context ... { // Initialize Magnum - Context context; + Platform::Context context; - // open window, enter main loop... + // Open window, enter main loop ... // Magnum context gets destroyed } - // delete OpenGL context ... + // Delete OpenGL context ... return 0; } diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp index e3aeb3fd4..5f4c25dc2 100644 --- a/src/Magnum/Context.cpp +++ b/src/Magnum/Context.cpp @@ -294,17 +294,9 @@ const std::vector& Extension::extensions(Version version) { Context* Context::_current = nullptr; -Context::Context() { - #ifndef MAGNUM_TARGET_GLES - /* Init glLoadGen. Ignore functions that failed to load (described by - `ogl_LOAD_SUCCEEDED + n` return code), as we requested the latest OpenGL - with many vendor extensions and there won't ever be a driver supporting - everything possible. */ - if(ogl_LoadFunctions() == ogl_LOAD_FAILED) { - Error() << "ExtensionWrangler: cannot initialize glLoadGen"; - std::exit(64); - } - #endif +Context::Context(void functionLoader()) { + /* Load GL function pointers */ + if(functionLoader) functionLoader(); /* Get version */ #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) diff --git a/src/Magnum/Context.h b/src/Magnum/Context.h index 6399b6597..434bdf7f4 100644 --- a/src/Magnum/Context.h +++ b/src/Magnum/Context.h @@ -42,9 +42,8 @@ namespace Magnum { -namespace Implementation { - struct State; -} +namespace Implementation { struct State; } +namespace Platform { class Context; } /** @brief Run-time information about OpenGL extension @@ -88,11 +87,15 @@ class MAGNUM_EXPORT Extension { Provides access to version and extension information. Instance available through @ref Context::current() is automatically created during construction of -*Application classes in @ref Platform namespace. You can safely assume that the -instance is available during whole lifetime of *Application object. See -@ref platform documentation for more information about engine setup. +`*Application` classes in @ref Platform namespace. You can safely assume that +the instance is available during whole lifetime of `*Application` object. It's +also possible to create the context without using any `*Application` class +using @ref Platform::Context subclass, see @ref platform documentation for more +information. */ class MAGNUM_EXPORT Context { + friend class Platform::Context; + public: /** * @brief %Context flag @@ -199,17 +202,6 @@ class MAGNUM_EXPORT Context { */ typedef Containers::EnumSet DetectedDrivers; - /** - * @brief Constructor - * - * Does initial setup, detects available features and enables them - * throughout the engine. - * @see @fn_gl{Get} with @def_gl{MAJOR_VERSION}, @def_gl{MINOR_VERSION}, - * @def_gl{CONTEXT_FLAGS}, @def_gl{NUM_EXTENSIONS}, - * @fn_gl{GetString} with @def_gl{EXTENSIONS} - */ - explicit Context(); - /** @brief Copying is not allowed */ Context(const Context&) = delete; @@ -478,6 +470,8 @@ class MAGNUM_EXPORT Context { private: static Context* _current; + explicit Context(void functionLoader()); + MAGNUM_LOCAL void setupDriverWorkarounds(); Version _version; diff --git a/src/Magnum/Platform/AbstractXApplication.cpp b/src/Magnum/Platform/AbstractXApplication.cpp index 8d8bfd018..3a7866e00 100644 --- a/src/Magnum/Platform/AbstractXApplication.cpp +++ b/src/Magnum/Platform/AbstractXApplication.cpp @@ -27,7 +27,7 @@ #include -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" #include "Magnum/Version.h" #include "Implementation/AbstractContextHandler.h" @@ -95,7 +95,7 @@ bool AbstractXApplication::tryCreateContext(const Configuration& configuration) /* Set OpenGL context as current */ contextHandler->makeCurrent(); - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/AbstractXApplication.h b/src/Magnum/Platform/AbstractXApplication.h index 89ef9b35a..3bb224402 100644 --- a/src/Magnum/Platform/AbstractXApplication.h +++ b/src/Magnum/Platform/AbstractXApplication.h @@ -41,6 +41,7 @@ #include "Magnum/Magnum.h" #include "Magnum/Math/Vector2.h" +#include "Magnum/Platform/Platform.h" namespace Magnum { @@ -183,7 +184,7 @@ class AbstractXApplication { Implementation::AbstractContextHandler* contextHandler; - Context* c; + Platform::Context* c; /** @todo Get this from the created window */ Vector2i viewportSize; diff --git a/src/Magnum/Platform/AndroidApplication.cpp b/src/Magnum/Platform/AndroidApplication.cpp index 57b511687..81cb52aa5 100644 --- a/src/Magnum/Platform/AndroidApplication.cpp +++ b/src/Magnum/Platform/AndroidApplication.cpp @@ -28,7 +28,7 @@ #include #include -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" #include "Implementation/Egl.h" @@ -136,7 +136,7 @@ bool AndroidApplication::tryCreateContext(const Configuration& configuration) { /* Make the context current */ CORRADE_INTERNAL_ASSERT_OUTPUT(eglMakeCurrent(_display, _surface, _surface, _context)); - _c.reset(new Context); + _c.reset(new Platform::Context); return true; } diff --git a/src/Magnum/Platform/AndroidApplication.h b/src/Magnum/Platform/AndroidApplication.h index 2d887d1e9..0660734cf 100644 --- a/src/Magnum/Platform/AndroidApplication.h +++ b/src/Magnum/Platform/AndroidApplication.h @@ -306,7 +306,7 @@ class AndroidApplication { EGLSurface _surface; EGLContext _context; - std::unique_ptr _c; + std::unique_ptr _c; std::unique_ptr _logOutput; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) diff --git a/src/Magnum/Platform/CMakeLists.txt b/src/Magnum/Platform/CMakeLists.txt index 94c68ceec..14b26ee10 100644 --- a/src/Magnum/Platform/CMakeLists.txt +++ b/src/Magnum/Platform/CMakeLists.txt @@ -25,6 +25,7 @@ # Headers set(MagnumPlatform_HEADERS + Context.h Platform.h Screen.h ScreenedApplication.h diff --git a/src/Magnum/Platform/Context.h b/src/Magnum/Platform/Context.h new file mode 100644 index 000000000..70eb8646e --- /dev/null +++ b/src/Magnum/Platform/Context.h @@ -0,0 +1,79 @@ +#ifndef Magnum_Platform_Context_h +#define Magnum_Platform_Context_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/Context.h" +#include "Magnum/OpenGL.h" + +namespace Magnum { namespace Platform { + +/** +@brief Platform-specific context + +In most cases not needed to be used directly as the initialization is done +automatically in `*Application` classes. See @ref platform for more +information. +*/ +class Context: public Magnum::Context { + public: + /** + * @brief Constructor + * + * Does initial setup, loads OpenGL function pointers using + * platform-specific API, detects available features and enables them + * throughout the engine. + * @see @fn_gl{Get} with @def_gl{MAJOR_VERSION}, @def_gl{MINOR_VERSION}, + * @def_gl{CONTEXT_FLAGS}, @def_gl{NUM_EXTENSIONS}, + * @fn_gl{GetString} with @def_gl{EXTENSIONS} + */ + explicit Context(): + #ifndef MAGNUM_TARGET_GLES + Magnum::Context{functionLoader} {} + #else + Magnum::Context{nullptr} {} + #endif + + private: + #ifndef MAGNUM_TARGET_GLES + void functionLoader() { + /* Init glLoadGen. Ignore functions that failed to load (described + by `ogl_LOAD_SUCCEEDED + n` return code), as we requested the + latest OpenGL with many vendor extensions and there won't ever + everything possible. */ + if(ogl_LoadFunctions() == ogl_LOAD_FAILED) { + Error() << "ExtensionWrangler: cannot initialize glLoadGen"; + std::exit(64); + } + } + #endif + +}; + +}} + +#endif diff --git a/src/Magnum/Platform/GlutApplication.cpp b/src/Magnum/Platform/GlutApplication.cpp index a576d8ab2..2677ee025 100644 --- a/src/Magnum/Platform/GlutApplication.cpp +++ b/src/Magnum/Platform/GlutApplication.cpp @@ -27,8 +27,8 @@ #include -#include "Magnum/Context.h" #include "Magnum/Version.h" +#include "Magnum/Platform/Context.h" #include "Magnum/Platform/ScreenedApplication.hpp" namespace Magnum { namespace Platform { @@ -96,7 +96,7 @@ bool GlutApplication::tryCreateContext(const Configuration& configuration) { glutMotionFunc(staticMouseMoveEvent); glutDisplayFunc(staticDrawEvent); - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/GlutApplication.h b/src/Magnum/Platform/GlutApplication.h index 68aa18ffc..1bab6db64 100644 --- a/src/Magnum/Platform/GlutApplication.h +++ b/src/Magnum/Platform/GlutApplication.h @@ -267,7 +267,7 @@ class GlutApplication { static GlutApplication* instance; - Context* c; + Platform::Context* c; }; /** diff --git a/src/Magnum/Platform/NaClApplication.cpp b/src/Magnum/Platform/NaClApplication.cpp index a0a7db690..e88b59d34 100644 --- a/src/Magnum/Platform/NaClApplication.cpp +++ b/src/Magnum/Platform/NaClApplication.cpp @@ -114,7 +114,7 @@ bool NaClApplication::tryCreateContext(const Configuration& configuration) { RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE|PP_INPUTEVENT_CLASS_WHEEL); RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/NaClApplication.h b/src/Magnum/Platform/NaClApplication.h index f867cd832..247b7cf7c 100644 --- a/src/Magnum/Platform/NaClApplication.h +++ b/src/Magnum/Platform/NaClApplication.h @@ -379,7 +379,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public pp::Graphics3D* graphics; pp::Fullscreen* fullscreen; - Context* c; + Platform::Context* c; Vector2i viewportSize; Flags flags; diff --git a/src/Magnum/Platform/Platform.h b/src/Magnum/Platform/Platform.h index 407586e2d..41e25dd0e 100644 --- a/src/Magnum/Platform/Platform.h +++ b/src/Magnum/Platform/Platform.h @@ -33,6 +33,7 @@ namespace Magnum { namespace Platform { template class BasicScreen; template class BasicScreenedApplication; +class Context; }} diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 026ca4a76..b2b4a5794 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -31,7 +31,7 @@ #include #endif -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" #include "Magnum/Version.h" #include "Magnum/Platform/ScreenedApplication.hpp" @@ -198,7 +198,7 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { context = SDL_SetVideoMode(configuration.size().x(), configuration.size().y(), 24, SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF); #endif - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index b4a12743e..52b43cfe6 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -406,7 +406,7 @@ class Sdl2Application { SDL_Surface* context; #endif - Context* c; + Platform::Context* c; Flags flags; }; diff --git a/src/Magnum/Platform/WindowlessCglApplication.cpp b/src/Magnum/Platform/WindowlessCglApplication.cpp index e96596b4a..baa7c6190 100644 --- a/src/Magnum/Platform/WindowlessCglApplication.cpp +++ b/src/Magnum/Platform/WindowlessCglApplication.cpp @@ -30,7 +30,7 @@ #include #include -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" namespace Magnum { namespace Platform { @@ -113,7 +113,7 @@ bool WindowlessCglApplication::tryCreateContext(const Configuration&) { } cglError = CGLSetCurrentContext(context); - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/WindowlessCglApplication.h b/src/Magnum/Platform/WindowlessCglApplication.h index f86274ac1..225ed3a53 100644 --- a/src/Magnum/Platform/WindowlessCglApplication.h +++ b/src/Magnum/Platform/WindowlessCglApplication.h @@ -151,7 +151,7 @@ class WindowlessCglApplication { CGLContextObj context; CGLPixelFormatObj pixelFormat; - Context* c; + Platform::Context* c; }; /** diff --git a/src/Magnum/Platform/WindowlessGlxApplication.cpp b/src/Magnum/Platform/WindowlessGlxApplication.cpp index 3d0943d30..3b5a4bb7a 100644 --- a/src/Magnum/Platform/WindowlessGlxApplication.cpp +++ b/src/Magnum/Platform/WindowlessGlxApplication.cpp @@ -28,7 +28,7 @@ #include #include -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" #define None 0L // redef Xlib nonsense @@ -111,7 +111,7 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { return false; } - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/WindowlessGlxApplication.h b/src/Magnum/Platform/WindowlessGlxApplication.h index 90d183d0f..90eb770fb 100644 --- a/src/Magnum/Platform/WindowlessGlxApplication.h +++ b/src/Magnum/Platform/WindowlessGlxApplication.h @@ -40,6 +40,7 @@ #undef Status #include "Magnum/Magnum.h" +#include "Magnum/Platform/Context.h" namespace Magnum { namespace Platform { @@ -157,7 +158,7 @@ class WindowlessGlxApplication { GLXContext context; GLXPbuffer pbuffer; - Context* c; + Platform::Context* c; }; /** diff --git a/src/Magnum/Platform/WindowlessNaClApplication.cpp b/src/Magnum/Platform/WindowlessNaClApplication.cpp index d2a28d95d..063425d55 100644 --- a/src/Magnum/Platform/WindowlessNaClApplication.cpp +++ b/src/Magnum/Platform/WindowlessNaClApplication.cpp @@ -30,7 +30,7 @@ #include #include -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" namespace Magnum { namespace Platform { @@ -97,7 +97,7 @@ bool WindowlessNaClApplication::tryCreateContext(const Configuration&) { glSetCurrentContextPPAPI(graphics->pp_resource()); - c = new Context; + c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/WindowlessNaClApplication.h b/src/Magnum/Platform/WindowlessNaClApplication.h index c4cddee81..920c53bc0 100644 --- a/src/Magnum/Platform/WindowlessNaClApplication.h +++ b/src/Magnum/Platform/WindowlessNaClApplication.h @@ -171,7 +171,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien bool Init(std::uint32_t, const char*, const char*) override; pp::Graphics3D* graphics; - Context* c; + Platform::Context* c; ConsoleDebugOutput* debugOutput; }; diff --git a/src/Magnum/Platform/WindowlessWglApplication.cpp b/src/Magnum/Platform/WindowlessWglApplication.cpp index 0a3eeb742..fa17e0ca8 100644 --- a/src/Magnum/Platform/WindowlessWglApplication.cpp +++ b/src/Magnum/Platform/WindowlessWglApplication.cpp @@ -29,7 +29,7 @@ #include #include -#include "Magnum/Context.h" +#include "Magnum/Platform/Context.h" namespace Magnum { namespace Platform { @@ -114,7 +114,7 @@ bool WindowlessWglApplication::tryCreateContext(const Configuration&) { return false; } - _c = new Context; + _c = new Platform::Context; return true; } diff --git a/src/Magnum/Platform/WindowlessWglApplication.h b/src/Magnum/Platform/WindowlessWglApplication.h index b151f1180..20210935e 100644 --- a/src/Magnum/Platform/WindowlessWglApplication.h +++ b/src/Magnum/Platform/WindowlessWglApplication.h @@ -154,7 +154,7 @@ class WindowlessWglApplication { HDC _deviceContext; HGLRC _renderingContext; - Context* _c; + Platform::Context* _c; }; /**