diff --git a/src/AbstractFramebuffer.cpp b/src/AbstractFramebuffer.cpp index 9e7147c8e..979576fe9 100644 --- a/src/AbstractFramebuffer.cpp +++ b/src/AbstractFramebuffer.cpp @@ -57,6 +57,25 @@ void AbstractFramebuffer::bindInternal(Target target) { glBindFramebuffer(static_cast(target), _id); } + +AbstractFramebuffer::Target AbstractFramebuffer::bindInternal() { + Implementation::FramebufferState* state = Context::current()->state()->framebuffer; + + /* Return target to which the framebuffer is already bound */ + if(state->readBinding == _id && state->drawBinding == _id) + return Target::ReadDraw; + if(state->readBinding == _id) + return Target::Read; + if(state->drawBinding == _id) + return Target::Draw; + + /* Or bind it, if not already */ + state->readBinding = _id; + if(readTarget == Target::ReadDraw) state->drawBinding = _id; + + glBindFramebuffer(GLenum(readTarget), _id); + return readTarget; +} #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) { diff --git a/src/AbstractFramebuffer.h b/src/AbstractFramebuffer.h index 777ed7dc6..c6f34a106 100644 --- a/src/AbstractFramebuffer.h +++ b/src/AbstractFramebuffer.h @@ -253,6 +253,7 @@ class MAGNUM_EXPORT AbstractFramebuffer { #ifndef DOXYGEN_GENERATING_OUTPUT protected: void MAGNUM_LOCAL bindInternal(Target target); + Target MAGNUM_LOCAL bindInternal(); void MAGNUM_LOCAL setViewportInternal(); static MAGNUM_LOCAL Target readTarget; diff --git a/src/Framebuffer.cpp b/src/Framebuffer.cpp index def6ea157..afe16cd3d 100644 --- a/src/Framebuffer.cpp +++ b/src/Framebuffer.cpp @@ -92,8 +92,7 @@ void Framebuffer::initializeContextBasedFunctionality(Context* context) { } void Framebuffer::renderbufferImplementationDefault(GLenum attachment, Renderbuffer* renderbuffer) { - bindInternal(drawTarget); - glFramebufferRenderbuffer(static_cast(drawTarget), attachment, GL_RENDERBUFFER, renderbuffer->id()); + glFramebufferRenderbuffer(GLenum(bindInternal()), attachment, GL_RENDERBUFFER, renderbuffer->id()); } #ifndef MAGNUM_TARGET_GLES @@ -102,8 +101,7 @@ void Framebuffer::renderbufferImplementationDSA(GLenum attachment, Renderbuffer* } void Framebuffer::texture1DImplementationDefault(GLenum attachment, Texture1D* texture, GLint mipLevel) { - bindInternal(drawTarget); - glFramebufferTexture1D(static_cast(drawTarget), attachment, static_cast(texture->target()), texture->id(), mipLevel); + glFramebufferTexture1D(GLenum(bindInternal()), attachment, static_cast(texture->target()), texture->id(), mipLevel); } void Framebuffer::texture1DImplementationDSA(GLenum attachment, Texture1D* texture, GLint mipLevel) { @@ -112,8 +110,7 @@ void Framebuffer::texture1DImplementationDSA(GLenum attachment, Texture1D* textu #endif void Framebuffer::texture2DImplementationDefault(GLenum attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) { - bindInternal(drawTarget); - glFramebufferTexture2D(static_cast(drawTarget), attachment, textureTarget, textureId, mipLevel); + glFramebufferTexture2D(GLenum(bindInternal()), attachment, textureTarget, textureId, mipLevel); } #ifndef MAGNUM_TARGET_GLES @@ -124,10 +121,9 @@ void Framebuffer::texture2DImplementationDSA(GLenum attachment, GLenum textureTa void Framebuffer::texture3DImplementationDefault(GLenum attachment, Texture3D* texture, GLint mipLevel, GLint layer) { /** @todo Check for texture target compatibility */ - bindInternal(drawTarget); /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ #ifndef MAGNUM_TARGET_GLES - glFramebufferTexture3D(static_cast(drawTarget), attachment, static_cast(texture->target()), texture->id(), mipLevel, layer); + glFramebufferTexture3D(GLenum(bindInternal()), attachment, static_cast(texture->target()), texture->id(), mipLevel, layer); #else static_cast(attachment); static_cast(texture);