From 19029d97c6fa5df28af5e5e4a99946a50067a8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 16 Dec 2012 17:05:03 +0100 Subject: [PATCH] Tracking viewport state in Framebuffer. Viewport position and size is managed separately for each framebuffer and glViewport() is called in bind() (and also from setViewport(), if the framebuffer is currently bound) if the viewport differs from current state. If used only one framebuffer size through whole application lifetime, glViewport() doesn't need to be called at all. --- src/AbstractFramebuffer.cpp | 58 +++++++++++++++- src/AbstractFramebuffer.h | 57 +++++++--------- src/Context.cpp | 5 +- src/DefaultFramebuffer.cpp | 27 +++++++- src/DefaultFramebuffer.h | 15 ++--- src/Framebuffer.cpp | 97 ++++++++++++++++++++++++++- src/Framebuffer.h | 88 ++++-------------------- src/Implementation/FramebufferState.h | 2 + 8 files changed, 228 insertions(+), 121 deletions(-) diff --git a/src/AbstractFramebuffer.cpp b/src/AbstractFramebuffer.cpp index 9f2f1904b..079d9321f 100644 --- a/src/AbstractFramebuffer.cpp +++ b/src/AbstractFramebuffer.cpp @@ -31,6 +31,12 @@ AbstractFramebuffer::Target AbstractFramebuffer::drawTarget = AbstractFramebuffe #endif void AbstractFramebuffer::bind(Target target) { + bindInternal(target); + setViewportInternal(); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +void AbstractFramebuffer::bindInternal(Target target) { Implementation::FramebufferState* state = Context::current()->state()->framebuffer; /* If already bound, done, otherwise update tracked state */ @@ -47,9 +53,57 @@ void AbstractFramebuffer::bind(Target target) { glBindFramebuffer(static_cast(target), _id); } +#endif + +void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Vector2i& sourceBottomLeft, const Vector2i& sourceTopRight, const Vector2i& destinationBottomLeft, const Vector2i& destinationTopRight, AbstractFramebuffer::BlitMask mask, AbstractFramebuffer::BlitFilter filter) { + source.bindInternal(AbstractFramebuffer::Target::Read); + destination.bindInternal(AbstractFramebuffer::Target::Draw); + /** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 + glBlitFramebuffer(sourceBottomLeft.x(), sourceBottomLeft.y(), sourceTopRight.x(), sourceTopRight.y(), destinationBottomLeft.x(), destinationBottomLeft.y(), destinationTopRight.x(), destinationTopRight.y(), static_cast(mask), static_cast(filter)); + #else + static_cast(sourceBottomLeft); + static_cast(sourceTopRight); + static_cast(destinationBottomLeft); + static_cast(destinationTopRight); + static_cast(mask); + static_cast(filter); + #endif +} + +void AbstractFramebuffer::setViewport(const Vector2i& position, const Vector2i& size) { + _viewportPosition = position; + _viewportSize = size; + + /* Update the viewport if the framebuffer is currently bound */ + if(Context::current()->state()->framebuffer->drawBinding == _id) + setViewportInternal(); +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +void AbstractFramebuffer::setViewportInternal() { + Implementation::FramebufferState* state = Context::current()->state()->framebuffer; + + CORRADE_INTERNAL_ASSERT(state->drawBinding == _id); + + /* Already up-to-date, nothing to do */ + if(state->viewportPosition == _viewportPosition && state->viewportSize == _viewportSize) + return; + + /* Update the state and viewport */ + state->viewportPosition = _viewportPosition; + state->viewportSize = _viewportSize; + glViewport(_viewportPosition.x(), _viewportPosition.y(), _viewportSize.x(), _viewportSize.y()); +} +#endif + +void AbstractFramebuffer::clear(ClearMask mask) { + bindInternal(drawTarget); + glClear(static_cast(mask)); +} void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, Image2D* image) { - bind(readTarget); + bindInternal(readTarget); char* data = new char[AbstractImage::pixelSize(format, type)*size.product()]; glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast(format), static_cast(type), data); image->setData(size, format, type, data); @@ -57,7 +111,7 @@ void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, Abs #ifndef MAGNUM_TARGET_GLES2 void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, BufferImage2D* image, Buffer::Usage usage) { - bind(readTarget); + bindInternal(readTarget); /* If the buffer doesn't have sufficient size, resize it */ /** @todo Explicitly reset also when buffer usage changes */ if(image->size() != size || image->format() != format || image->type() != type) diff --git a/src/AbstractFramebuffer.h b/src/AbstractFramebuffer.h index 28a8d307c..a18b1f303 100644 --- a/src/AbstractFramebuffer.h +++ b/src/AbstractFramebuffer.h @@ -34,8 +34,9 @@ See DefaultFramebuffer and Framebuffer for more information. @section AbstractFramebuffer-performance-optimization Performance optimizations -The engine tracks currently bound framebuffer to avoid unnecessary calls to -@fn_gl{BindFramebuffer}. +The engine tracks currently bound framebuffer and current viewport to avoid +unnecessary calls to @fn_gl{BindFramebuffer} and @fn_gl{Viewport} when +switching framebuffers. @todo @extension{ARB,viewport_array} */ @@ -156,21 +157,7 @@ class MAGNUM_EXPORT AbstractFramebuffer { * @requires_gl30 %Extension @extension{EXT,framebuffer_blit} * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} */ - inline static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Vector2i& sourceBottomLeft, const Vector2i& sourceTopRight, const Vector2i& destinationBottomLeft, const Vector2i& destinationTopRight, BlitMask mask, BlitFilter filter) { - source.bind(AbstractFramebuffer::Target::Read); - destination.bind(AbstractFramebuffer::Target::Draw); - /** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */ - #ifndef MAGNUM_TARGET_GLES2 - glBlitFramebuffer(sourceBottomLeft.x(), sourceBottomLeft.y(), sourceTopRight.x(), sourceTopRight.y(), destinationBottomLeft.x(), destinationBottomLeft.y(), destinationTopRight.x(), destinationTopRight.y(), static_cast(mask), static_cast(filter)); - #else - static_cast(sourceBottomLeft); - static_cast(sourceTopRight); - static_cast(destinationBottomLeft); - static_cast(destinationTopRight); - static_cast(mask); - static_cast(filter); - #endif - } + static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Vector2i& sourceBottomLeft, const Vector2i& sourceTopRight, const Vector2i& destinationBottomLeft, const Vector2i& destinationTopRight, BlitMask mask, BlitFilter filter); /** * @brief Copy block of pixels @@ -199,24 +186,31 @@ class MAGNUM_EXPORT AbstractFramebuffer { virtual ~AbstractFramebuffer() = 0; /** - * @brief Bind framebuffer + * @brief Bind framebuffer for rendering * - * @see DefaultFramebuffer::mapForRead(), Framebuffer::mapForRead(), - * DefaultFramebuffer::mapForDraw(), Framebuffer::mapForDraw(), - * @fn_gl{BindFramebuffer} + * Binds the framebuffer and updates viewport to saved dimensions. + * @see setViewport(), DefaultFramebuffer::mapForRead(), + * Framebuffer::mapForRead(), DefaultFramebuffer::mapForDraw(), + * Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer}, + * @fn_gl{Viewport} */ void bind(Target target); + /** @brief Viewport position */ + inline Vector2i viewportPosition() const { return _viewportPosition; } + + /** @brief Viewport size */ + inline Vector2i viewportSize() const { return _viewportSize; } + /** * @brief Set viewport size * - * Call when window size changes. - * @see @fn_gl{BindFramebuffer}, @fn_gl{Viewport} + * Saves the viewport size to be used at later time in bind(). If the + * framebuffer is currently bound, updates the viewport to given + * dimensions. + * @see @fn_gl{Viewport} */ - inline void setViewport(const Vector2i& position, const Vector2i& size) { - bind(drawTarget); - glViewport(position.x(), position.y(), size.x(), size.y()); - } + void setViewport(const Vector2i& position, const Vector2i& size); /** * @brief Clear specified buffers in framebuffer @@ -226,10 +220,7 @@ class MAGNUM_EXPORT AbstractFramebuffer { * Renderer::setClearStencil(), @fn_gl{BindFramebuffer}, * @fn_gl{Clear} */ - inline void clear(ClearMask mask) { - bind(drawTarget); - glClear(static_cast(mask)); - } + void clear(ClearMask mask); /** * @brief Read block of pixels from framebuffer to image @@ -261,9 +252,13 @@ class MAGNUM_EXPORT AbstractFramebuffer { #ifndef DOXYGEN_GENERATING_OUTPUT protected: + void MAGNUM_LOCAL bindInternal(Target target); + void MAGNUM_LOCAL setViewportInternal(); + static Target readTarget, drawTarget; GLuint _id; + Vector2i _viewportPosition, _viewportSize; #endif private: diff --git a/src/Context.cpp b/src/Context.cpp index ff45c6d71..8aaaf98ed 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -25,11 +25,13 @@ #include "AbstractTexture.h" #include "Buffer.h" #include "BufferTexture.h" +#include "DebugMarker.h" +#include "DefaultFramebuffer.h" #include "Extensions.h" #include "IndexedMesh.h" #include "Mesh.h" + #include "Implementation/State.h" -#include "DebugMarker.h" namespace Magnum { @@ -301,6 +303,7 @@ Context::Context() { BufferTexture::initializeContextBasedFunctionality(this); #endif DebugMarker::initializeContextBasedFunctionality(this); + DefaultFramebuffer::initializeContextBasedFunctionality(this); IndexedMesh::initializeContextBasedFunctionality(this); Mesh::initializeContextBasedFunctionality(this); } diff --git a/src/DefaultFramebuffer.cpp b/src/DefaultFramebuffer.cpp index 07f8a392d..d4a267f54 100644 --- a/src/DefaultFramebuffer.cpp +++ b/src/DefaultFramebuffer.cpp @@ -15,6 +15,11 @@ #include "DefaultFramebuffer.h" +#include "Context.h" + +#include "Implementation/State.h" +#include "Implementation/FramebufferState.h" + namespace Magnum { DefaultFramebuffer defaultFramebuffer; @@ -27,10 +32,30 @@ void DefaultFramebuffer::mapForDraw(std::initializer_list attach for(auto it = attachments.begin(); it != attachments.end(); ++it) _attachments[it-attachments.begin()] = static_cast(*it); - bind(drawTarget); + bindInternal(drawTarget); glDrawBuffers(attachments.size(), _attachments); delete[] _attachments; } #endif +void DefaultFramebuffer::mapForRead(ReadAttachment attachment) { + bindInternal(readTarget); + /** @todo Get some extension wrangler instead to avoid undeclared glReadBuffer() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 + glReadBuffer(static_cast(attachment)); + #else + static_cast(attachment); + #endif +} + +void DefaultFramebuffer::initializeContextBasedFunctionality(Context* context) { + Implementation::FramebufferState* state = context->state()->framebuffer; + + /* Initial framebuffer size */ + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + defaultFramebuffer._viewportPosition = state->viewportPosition = {viewport[0], viewport[1]}; + defaultFramebuffer._viewportSize = state->viewportSize = {viewport[2], viewport[3]}; +} + } diff --git a/src/DefaultFramebuffer.h b/src/DefaultFramebuffer.h index 6e5b478d4..1798c4138 100644 --- a/src/DefaultFramebuffer.h +++ b/src/DefaultFramebuffer.h @@ -29,6 +29,8 @@ namespace Magnum { @see @ref defaultFramebuffer, Framebuffer */ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { + friend class Context; + public: #ifndef MAGNUM_TARGET_GLES2 /** @@ -185,15 +187,10 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer} * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} */ - inline void mapForRead(ReadAttachment attachment) { - bind(readTarget); - /** @todo Get some extension wrangler instead to avoid undeclared glReadBuffer() on ES2 */ - #ifndef MAGNUM_TARGET_GLES2 - glReadBuffer(static_cast(attachment)); - #else - static_cast(attachment); - #endif - } + void mapForRead(ReadAttachment attachment); + + private: + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); }; /** @brief Default framebuffer instance */ diff --git a/src/Framebuffer.cpp b/src/Framebuffer.cpp index 2aff2474a..ebb0d175d 100644 --- a/src/Framebuffer.cpp +++ b/src/Framebuffer.cpp @@ -18,12 +18,21 @@ #include "BufferImage.h" #include "Context.h" #include "Image.h" +#include "Renderbuffer.h" +#include "Texture.h" #include "Implementation/State.h" #include "Implementation/FramebufferState.h" namespace Magnum { +Framebuffer::Framebuffer(const Vector2i& viewportPosition, const Vector2i& viewportSize) { + _viewportPosition = viewportPosition; + _viewportSize = viewportSize; + + glGenFramebuffers(1, &_id); +} + Framebuffer::~Framebuffer() { /* If bound, remove itself from state */ Implementation::FramebufferState* state = Context::current()->state()->framebuffer; @@ -38,7 +47,7 @@ void Framebuffer::mapForDraw(std::initializer_list colorAttachments for(auto it = colorAttachments.begin(); it != colorAttachments.end(); ++it) attachments[it-colorAttachments.begin()] = *it + GL_COLOR_ATTACHMENT0; - bind(Target::Draw); + bindInternal(Target::Draw); /** @todo Re-enable when extension wrangler is available for ES2 */ #ifndef MAGNUM_TARGET_GLES2 glDrawBuffers(colorAttachments.size(), attachments); @@ -46,4 +55,90 @@ void Framebuffer::mapForDraw(std::initializer_list colorAttachments delete[] attachments; } +void Framebuffer::mapForRead(std::uint8_t colorAttachment) { + bindInternal(Target::Read); + /** @todo Get some extension wrangler instead to avoid undeclared glReadBuffer() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 + glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachment); + #else + static_cast(colorAttachment); + #endif +} + +void Framebuffer::attachRenderbuffer(Target target, DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer) { + bindInternal(target); + glFramebufferRenderbuffer(static_cast(target), static_cast(depthStencilAttachment), GL_RENDERBUFFER, renderbuffer->id()); +} + +void Framebuffer::attachRenderbuffer(Target target, std::uint8_t colorAttachment, Renderbuffer* renderbuffer) { + bindInternal(target); + glFramebufferRenderbuffer(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, GL_RENDERBUFFER, renderbuffer->id()); +} + +#ifndef MAGNUM_TARGET_GLES +void Framebuffer::attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) { + /** @todo Check for texture target compatibility */ + bindInternal(target); + glFramebufferTexture1D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel); +} + +void Framebuffer::attachTexture1D(Target target, std::uint8_t colorAttachment, Texture1D* texture, GLint mipLevel) { + /** @todo Check for texture target compatibility */ + bindInternal(target); + glFramebufferTexture1D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel); +} +#endif + +void Framebuffer::attachTexture2D(Target target, DepthStencilAttachment depthStencilAttachment, Texture2D* texture, GLint mipLevel) { + /** @todo Check for texture target compatibility */ + bindInternal(target); + glFramebufferTexture2D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel); +} + +void Framebuffer::attachTexture2D(Target target, std::uint8_t colorAttachment, Texture2D* texture, GLint mipLevel) { + /** @todo Check for texture target compatibility */ + bindInternal(target); + glFramebufferTexture2D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel); +} + +void Framebuffer::attachCubeMapTexture(Target target, DepthStencilAttachment depthStencilAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { + /** @todo Check for internal format compatibility */ + bindInternal(target); + glFramebufferTexture2D(static_cast(target), static_cast(depthStencilAttachment), static_cast(coordinate), texture->id(), mipLevel); +} + +void Framebuffer::attachCubeMapTexture(Target target, std::uint8_t colorAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { + /** @todo Check for internal format compatibility */ + bindInternal(target); + glFramebufferTexture2D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(coordinate), texture->id(), mipLevel); +} + +void Framebuffer::attachTexture3D(Target target, DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { + /** @todo Check for texture target compatibility */ + bindInternal(target); + /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ + #ifndef MAGNUM_TARGET_GLES + glFramebufferTexture3D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel, layer); + #else + static_cast(depthStencilAttachment); + static_cast(texture); + static_cast(mipLevel); + static_cast(layer); + #endif +} + +void Framebuffer::attachTexture3D(Target target, std::uint8_t colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { + /** @todo Check for texture target compatibility */ + bindInternal(target); + /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ + #ifndef MAGNUM_TARGET_GLES + glFramebufferTexture3D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel, layer); + #else + static_cast(colorAttachment); + static_cast(texture); + static_cast(mipLevel); + static_cast(layer); + #endif +} + } diff --git a/src/Framebuffer.h b/src/Framebuffer.h index 781596363..6ab19eec1 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -21,8 +21,6 @@ #include "AbstractFramebuffer.h" #include "CubeMapTexture.h" -#include "Texture.h" -#include "Renderbuffer.h" namespace Magnum { @@ -40,7 +38,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * Generates new OpenGL framebuffer. * @see @fn_gl{GenFramebuffers} */ - inline Framebuffer() { glGenFramebuffers(1, &_id); } + Framebuffer(const Vector2i& viewportPosition, const Vector2i& viewportSize); /** * @brief Destructor @@ -67,15 +65,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer} * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} */ - inline void mapForRead(std::uint8_t colorAttachment) { - bind(Target::Read); - /** @todo Get some extension wrangler instead to avoid undeclared glReadBuffer() on ES2 */ - #ifndef MAGNUM_TARGET_GLES2 - glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachment); - #else - static_cast(colorAttachment); - #endif - } + void mapForRead(std::uint8_t colorAttachment); /** * @brief Attachment for depth/stencil part of fragment shader output @@ -107,10 +97,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} */ - inline void attachRenderbuffer(Target target, DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer) { - bind(target); - glFramebufferRenderbuffer(static_cast(target), static_cast(depthStencilAttachment), GL_RENDERBUFFER, renderbuffer->id()); - } + void attachRenderbuffer(Target target, DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer); /** * @brief Attach renderbuffer to given framebuffer color attachment @@ -120,10 +107,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} */ - inline void attachRenderbuffer(Target target, std::uint8_t colorAttachment, Renderbuffer* renderbuffer) { - bind(target); - glFramebufferRenderbuffer(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, GL_RENDERBUFFER, renderbuffer->id()); - } + void attachRenderbuffer(Target target, std::uint8_t colorAttachment, Renderbuffer* renderbuffer); #ifndef MAGNUM_TARGET_GLES /** @@ -136,11 +120,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @requires_gl Only 2D and 3D textures are available in OpenGL ES. */ - inline void attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) { - /** @todo Check for texture target compatibility */ - bind(target); - glFramebufferTexture1D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel); - } + void attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel); /** * @brief Attach 1D texture to given framebuffer color attachment @@ -152,11 +132,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @requires_gl Only 2D and 3D textures are available in OpenGL ES. */ - inline void attachTexture1D(Target target, std::uint8_t colorAttachment, Texture1D* texture, GLint mipLevel) { - /** @todo Check for texture target compatibility */ - bind(target); - glFramebufferTexture1D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel); - } + void attachTexture1D(Target target, std::uint8_t colorAttachment, Texture1D* texture, GLint mipLevel); #endif /** @@ -170,11 +146,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see attachCubeMapTexture(), @fn_gl{BindFramebuffer}, * @fn_gl{FramebufferTexture} */ - inline void attachTexture2D(Target target, DepthStencilAttachment depthStencilAttachment, Texture2D* texture, GLint mipLevel) { - /** @todo Check for texture target compatibility */ - bind(target); - glFramebufferTexture2D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel); - } + void attachTexture2D(Target target, DepthStencilAttachment depthStencilAttachment, Texture2D* texture, GLint mipLevel); /** * @brief Attach 2D texture to given framebuffer color attachment @@ -187,11 +159,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see attachCubeMapTexture(), @fn_gl{BindFramebuffer}, * @fn_gl{FramebufferTexture} */ - inline void attachTexture2D(Target target, std::uint8_t colorAttachment, Texture2D* texture, GLint mipLevel) { - /** @todo Check for texture target compatibility */ - bind(target); - glFramebufferTexture2D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel); - } + void attachTexture2D(Target target, std::uint8_t colorAttachment, Texture2D* texture, GLint mipLevel); /** * @brief Attach cube map texture to given framebuffer depth/stencil attachment @@ -204,11 +172,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see attachTexture2D(), @fn_gl{BindFramebuffer}, * @fn_gl{FramebufferTexture} */ - inline void attachCubeMapTexture(Target target, DepthStencilAttachment depthStencilAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { - /** @todo Check for internal format compatibility */ - bind(target); - glFramebufferTexture2D(static_cast(target), static_cast(depthStencilAttachment), static_cast(coordinate), texture->id(), mipLevel); - } + void attachCubeMapTexture(Target target, DepthStencilAttachment depthStencilAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel); /** * @brief Attach cube map texture to given framebuffer color attachment @@ -221,11 +185,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see attachTexture2D(), @fn_gl{BindFramebuffer}, * @fn_gl{FramebufferTexture} */ - inline void attachCubeMapTexture(Target target, std::uint8_t colorAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { - /** @todo Check for internal format compatibility */ - bind(target); - glFramebufferTexture2D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(coordinate), texture->id(), mipLevel); - } + void attachCubeMapTexture(Target target, std::uint8_t colorAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel); /** * @brief Attach 3D texture to given framebuffer depth/stencil attachment @@ -238,19 +198,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @requires_es_extension %Extension @es_extension{OES,texture_3D} */ - inline void attachTexture3D(Target target, DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { - /** @todo Check for texture target compatibility */ - bind(target); - /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ - #ifndef MAGNUM_TARGET_GLES - glFramebufferTexture3D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel, layer); - #else - static_cast(depthStencilAttachment); - static_cast(texture); - static_cast(mipLevel); - static_cast(layer); - #endif - } + void attachTexture3D(Target target, DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer); /** * @brief Attach 3D texture to given framebuffer color attachment @@ -263,19 +211,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @requires_es_extension %Extension @es_extension{OES,texture_3D} */ - inline void attachTexture3D(Target target, std::uint8_t colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { - /** @todo Check for texture target compatibility */ - bind(target); - /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ - #ifndef MAGNUM_TARGET_GLES - glFramebufferTexture3D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel, layer); - #else - static_cast(colorAttachment); - static_cast(texture); - static_cast(mipLevel); - static_cast(layer); - #endif - } + void attachTexture3D(Target target, std::uint8_t colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer); }; } diff --git a/src/Implementation/FramebufferState.h b/src/Implementation/FramebufferState.h index 43e496040..f6c0b5a19 100644 --- a/src/Implementation/FramebufferState.h +++ b/src/Implementation/FramebufferState.h @@ -15,6 +15,7 @@ GNU Lesser General Public License version 3 for more details. */ +#include "Math/Vector2.h" #include "Magnum.h" namespace Magnum { namespace Implementation { @@ -23,6 +24,7 @@ struct FramebufferState { inline FramebufferState(): readBinding(0), drawBinding(0) {} GLuint readBinding, drawBinding; + Vector2i viewportPosition, viewportSize; }; }}