diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index b80bff4cb..9b619b6f9 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -56,6 +56,7 @@ set(Magnum_SRCS Implementation/DebugState.cpp Implementation/FramebufferState.cpp Implementation/MeshState.cpp + Implementation/RendererState.cpp Implementation/ShaderProgramState.cpp Implementation/State.cpp Implementation/TextureState.cpp diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp index b4f8a5102..8cd802928 100644 --- a/src/Magnum/Context.cpp +++ b/src/Magnum/Context.cpp @@ -448,8 +448,9 @@ Context::Context() { _state = new Implementation::State(*this); /* Initialize functionality based on current OpenGL version and extensions */ + /** @todo Get rid of these */ DefaultFramebuffer::initializeContextBasedFunctionality(*this); - Renderer::initializeContextBasedFunctionality(*this); + Renderer::initializeContextBasedFunctionality(); } Context::~Context() { diff --git a/src/Magnum/Implementation/RendererState.cpp b/src/Magnum/Implementation/RendererState.cpp new file mode 100644 index 000000000..9c4a932d1 --- /dev/null +++ b/src/Magnum/Implementation/RendererState.cpp @@ -0,0 +1,64 @@ +/* + 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 "RendererState.h" + +#include "Magnum/Context.h" +#include "Magnum/Extensions.h" + +namespace Magnum { namespace Implementation { + +RendererState::RendererState(Context& context, std::vector& extensions): resetNotificationStrategy() { + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES + extensions.push_back(Extensions::GL::ARB::ES2_compatibility::string()); + #endif + + clearDepthfImplementation = &Renderer::clearDepthfImplementationES; + } + #ifndef MAGNUM_TARGET_GLES + else clearDepthfImplementation = &Renderer::clearDepthfImplementationDefault; + #endif + + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported()) + #else + if(context.isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES + extensions.push_back(Extensions::GL::ARB::robustness::string()); + #else + extensions.push_back(Extensions::GL::EXT::robustness::string()); + #endif + + graphicsResetStatusImplementation = &Renderer::graphicsResetStatusImplementationRobustness; + } else graphicsResetStatusImplementation = &Renderer::graphicsResetStatusImplementationDefault; +} + +}} diff --git a/src/Magnum/Implementation/RendererState.h b/src/Magnum/Implementation/RendererState.h index 962fa0587..33483e632 100644 --- a/src/Magnum/Implementation/RendererState.h +++ b/src/Magnum/Implementation/RendererState.h @@ -25,12 +25,18 @@ DEALINGS IN THE SOFTWARE. */ +#include +#include + #include "Magnum/Renderer.h" namespace Magnum { namespace Implementation { struct RendererState { - constexpr RendererState(): resetNotificationStrategy() {} + explicit RendererState(Context& context, std::vector& extensions); + + void(*clearDepthfImplementation)(GLfloat); + Renderer::GraphicsResetStatus(*graphicsResetStatusImplementation)(); Renderer::ResetNotificationStrategy resetNotificationStrategy; }; diff --git a/src/Magnum/Implementation/State.cpp b/src/Magnum/Implementation/State.cpp index bb5b0c1be..82354e734 100644 --- a/src/Magnum/Implementation/State.cpp +++ b/src/Magnum/Implementation/State.cpp @@ -55,7 +55,7 @@ State::State(Context& context) { debug = new DebugState(context, extensions); framebuffer = new FramebufferState(context, extensions); mesh = new MeshState(context, extensions); - renderer = new RendererState; + renderer = new RendererState(context, extensions); shader = new ShaderState; shaderProgram = new ShaderProgramState(context, extensions); texture = new TextureState(context, extensions); diff --git a/src/Magnum/Renderer.cpp b/src/Magnum/Renderer.cpp index 78e0933b7..2020d6775 100644 --- a/src/Magnum/Renderer.cpp +++ b/src/Magnum/Renderer.cpp @@ -28,20 +28,12 @@ #include "Magnum/Math/Range.h" #include "Magnum/Color.h" #include "Magnum/Context.h" -#include "Magnum/Extensions.h" #include "Implementation/State.h" #include "Implementation/RendererState.h" namespace Magnum { -#ifndef MAGNUM_TARGET_GLES -Renderer::ClearDepthfImplementation Renderer::clearDepthfImplementation = &Renderer::clearDepthfImplementationDefault; -#else -Renderer::ClearDepthfImplementation Renderer::clearDepthfImplementation = &Renderer::clearDepthfImplementationES; -#endif -Renderer::GraphicsResetStatusImplementation Renderer::graphicsResetStatusImplementation = &Renderer::graphicsResetStatusImplementationDefault; - void Renderer::setFeature(const Feature feature, const bool enabled) { enabled ? glEnable(GLenum(feature)) : glDisable(GLenum(feature)); } @@ -60,6 +52,10 @@ void Renderer::setClearDepth(const Double depth) { } #endif +void Renderer::setClearDepth(Float depth) { + Context::current()->state().renderer->clearDepthfImplementation(depth); +} + void Renderer::setClearStencil(const Int stencil) { glClearStencil(stencil); } @@ -176,30 +172,11 @@ Renderer::ResetNotificationStrategy Renderer::resetNotificationStrategy() { return strategy; } -void Renderer::initializeContextBasedFunctionality(Context& context) { - #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { - Debug() << "Renderer: using" << Extensions::GL::ARB::ES2_compatibility::string() << "features"; - - clearDepthfImplementation = &Renderer::clearDepthfImplementationES; - } - #endif - - #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) - #else - if(context.isExtensionSupported()) - #endif - { - #ifndef MAGNUM_TARGET_GLES - Debug() << "Renderer: using" << Extensions::GL::ARB::robustness::string() << "features"; - #else - Debug() << "Renderer: using" << Extensions::GL::EXT::robustness::string() << "features"; - #endif - - graphicsResetStatusImplementation = &Renderer::graphicsResetStatusImplementationRobustness; - } +Renderer::GraphicsResetStatus Renderer::graphicsResetStatus() { + return Context::current()->state().renderer->graphicsResetStatusImplementation(); +} +void Renderer::initializeContextBasedFunctionality() { /* Set some "corporate identity" */ setClearColor(Color3(0.125f)); } diff --git a/src/Magnum/Renderer.h b/src/Magnum/Renderer.h index f09d271f2..9040c6411 100644 --- a/src/Magnum/Renderer.h +++ b/src/Magnum/Renderer.h @@ -37,6 +37,8 @@ namespace Magnum { +namespace Implementation { struct RendererState; } + /** @nosubgrouping @brief Global renderer configuration. @@ -46,6 +48,7 @@ namespace Magnum { @todo `GL_MAX_CLIP_DISTANCES`... */ class MAGNUM_EXPORT Renderer { + friend class Implementation::RendererState; friend class Context; public: @@ -287,9 +290,7 @@ class MAGNUM_EXPORT Renderer { * If OpenGL ES, OpenGL 4.1 or extension @extension{ARB,ES2_compatibility} * is not available, this function behaves exactly as setClearDepth(Double). */ - static void setClearDepth(Float depth) { - clearDepthfImplementation(depth); - } + static void setClearDepth(Float depth); /** * @brief Set clear stencil @@ -1037,26 +1038,20 @@ class MAGNUM_EXPORT Renderer { * is not available, this function always returns @ref GraphicsResetStatus::NoError. * @see @ref resetNotificationStrategy(), @fn_gl_extension{GetGraphicsResetStatus,ARB,robustness} */ - static GraphicsResetStatus graphicsResetStatus() { - return graphicsResetStatusImplementation(); - } + static GraphicsResetStatus graphicsResetStatus(); /*@}*/ private: - static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context); + static void MAGNUM_LOCAL initializeContextBasedFunctionality(); - typedef void(*ClearDepthfImplementation)(GLfloat); #ifndef MAGNUM_TARGET_GLES static void MAGNUM_LOCAL clearDepthfImplementationDefault(GLfloat depth); #endif static void MAGNUM_LOCAL clearDepthfImplementationES(GLfloat depth); - static ClearDepthfImplementation clearDepthfImplementation; - typedef GraphicsResetStatus(*GraphicsResetStatusImplementation)(); static GraphicsResetStatus MAGNUM_LOCAL graphicsResetStatusImplementationDefault(); static GraphicsResetStatus MAGNUM_LOCAL graphicsResetStatusImplementationRobustness(); - static GraphicsResetStatusImplementation graphicsResetStatusImplementation; }; /** @debugoperator{Renderer} */