Browse Source

Tracking framebuffer binding.

pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
5267547373
  1. 21
      src/AbstractFramebuffer.cpp
  2. 19
      src/AbstractFramebuffer.h
  3. 4
      src/DefaultFramebuffer.h
  4. 13
      src/Framebuffer.cpp
  5. 30
      src/Framebuffer.h
  6. 30
      src/Implementation/FramebufferState.h
  7. 9
      src/Implementation/State.cpp
  8. 2
      src/Implementation/State.h

21
src/AbstractFramebuffer.cpp

@ -20,6 +20,9 @@
#include "Extensions.h"
#include "Image.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/State.h"
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -27,6 +30,24 @@ AbstractFramebuffer::Target AbstractFramebuffer::readTarget = AbstractFramebuffe
AbstractFramebuffer::Target AbstractFramebuffer::drawTarget = AbstractFramebuffer::Target::ReadDraw;
#endif
void AbstractFramebuffer::bind(Target target) {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
/* If already bound, done, otherwise update tracked state */
if(target == Target::Read) {
if(state->readBinding == _id) return;
state->readBinding = _id;
} else if(target == Target::Draw) {
if(state->drawBinding == _id) return;
state->drawBinding = _id;
} else if(target == Target::ReadDraw) {
if(state->readBinding == _id && state->drawBinding == _id) return;
state->readBinding = state->drawBinding = _id;
} else CORRADE_INTERNAL_ASSERT(false);
glBindFramebuffer(static_cast<GLenum>(target), _id);
}
void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, Image2D* image) {
bind(readTarget);
char* data = new char[AbstractImage::pixelSize(format, type)*size.product()];

19
src/AbstractFramebuffer.h

@ -31,6 +31,12 @@ namespace Magnum {
@brief Base for default and named framebuffers
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}.
@todo @extension{ARB,viewport_array}
*/
class MAGNUM_EXPORT AbstractFramebuffer {
@ -199,15 +205,13 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* DefaultFramebuffer::mapForDraw(), Framebuffer::mapForDraw(),
* @fn_gl{BindFramebuffer}
*/
inline void bind(Target target) {
glBindFramebuffer(static_cast<GLenum>(target), _id);
}
void bind(Target target);
/**
* @brief Set viewport size
*
* Call when window size changes.
* @see @fn_gl{Viewport}
* @see @fn_gl{BindFramebuffer}, @fn_gl{Viewport}
*/
inline void setViewport(const Vector2i& position, const Vector2i& size) {
bind(drawTarget);
@ -219,7 +223,8 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @param mask Which buffers to clear
*
* @see Renderer::setClearColor(), Renderer::setClearDepth(),
* Renderer::setClearStencil(), @fn_gl{Clear}
* Renderer::setClearStencil(), @fn_gl{BindFramebuffer},
* @fn_gl{Clear}
*/
inline void clear(ClearMask mask) {
bind(drawTarget);
@ -234,7 +239,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @param type Data type of pixel data
* @param image %Image where to put the data
*
* @see @fn_gl{ReadPixels}
* @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels}
*/
void read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, Image2D* image);
@ -248,7 +253,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @param image %Buffer image where to put the data
* @param usage %Buffer usage
*
* @see Buffer::bind(Target), @fn_gl{ReadPixels}
* @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels}
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0.
*/
void read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, BufferImage2D* image, Buffer::Usage usage);

4
src/DefaultFramebuffer.h

@ -171,7 +171,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @ref DrawAttachment "Attachment::None", given output is not
* used.
*
* @see mapForRead(), bind(), @fn_gl{DrawBuffers}
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers}
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
@ -182,7 +182,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @brief Map given attachment for reading
* @param attachment Attachment
*
* @see mapForDraw(), bind(), @fn_gl{ReadBuffer}
* @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) {

13
src/Framebuffer.cpp

@ -16,10 +16,23 @@
#include "Framebuffer.h"
#include "BufferImage.h"
#include "Context.h"
#include "Image.h"
#include "Implementation/State.h"
#include "Implementation/FramebufferState.h"
namespace Magnum {
Framebuffer::~Framebuffer() {
/* If bound, remove itself from state */
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
if(state->readBinding == _id) state->readBinding = 0;
if(state->drawBinding == _id) state->drawBinding = 0;
glDeleteFramebuffers(1, &_id);
}
void Framebuffer::mapForDraw(std::initializer_list<std::int8_t> colorAttachments) {
GLenum* attachments = new GLenum[colorAttachments.size()];
for(auto it = colorAttachments.begin(); it != colorAttachments.end(); ++it)

30
src/Framebuffer.h

@ -48,14 +48,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* Deletes associated OpenGL framebuffer.
* @see @fn_gl{DeleteFramebuffers}
*/
inline ~Framebuffer() { glDeleteFramebuffers(1, &_id); }
~Framebuffer();
/**
* @brief Map given color attachments of current framebuffer for drawing
* @param colorAttachments Color attachment IDs. If any value is -1,
* given output is not used.
*
* @see mapForRead(), bind(), @fn_gl{DrawBuffers}
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers}
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/
void mapForDraw(std::initializer_list<std::int8_t> colorAttachments);
@ -64,7 +64,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @brief Map given color attachment of current framebuffer for reading
* @param colorAttachment Color attachment ID
*
* @see mapForDraw(), bind(), @fn_gl{ReadBuffer}
* @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) {
@ -105,7 +105,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param depthStencilAttachment Depth/stencil attachment
* @param renderbuffer %Renderbuffer
*
* @see bind(), @fn_gl{FramebufferRenderbuffer}
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer}
*/
inline void attachRenderbuffer(Target target, DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer) {
bind(target);
@ -118,7 +118,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param colorAttachment Color attachment ID (number between 0 and 15)
* @param renderbuffer %Renderbuffer
*
* @see bind(), @fn_gl{FramebufferRenderbuffer}
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer}
*/
inline void attachRenderbuffer(Target target, std::uint8_t colorAttachment, Renderbuffer* renderbuffer) {
bind(target);
@ -133,7 +133,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param texture 1D texture
* @param mipLevel Mip level
*
* @see bind(), @fn_gl{FramebufferTexture}
* @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) {
@ -149,7 +149,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param texture 1D texture
* @param mipLevel Mip level
*
* @see bind(), @fn_gl{FramebufferTexture}
* @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) {
@ -167,7 +167,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param mipLevel Mip level. For rectangle textures it
* should be always 0.
*
* @see attachCubeMapTexture(), bind(), @fn_gl{FramebufferTexture}
* @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 */
@ -183,7 +184,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param mipLevel Mip level. For rectangle textures it
* should be always 0.
*
* @see attachCubeMapTexture(), bind(), @fn_gl{FramebufferTexture}
* @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 */
@ -199,7 +201,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param coordinate Cube map coordinate
* @param mipLevel Mip level
*
* @see attachTexture2D(), bind(), @fn_gl{FramebufferTexture}
* @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 */
@ -215,7 +218,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param coordinate Cube map coordinate
* @param mipLevel Mip level
*
* @see attachTexture2D(), bind(), @fn_gl{FramebufferTexture}
* @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 */
@ -231,7 +235,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param mipLevel Mip level
* @param layer Layer of 2D image within a 3D texture
*
* @see bind(), @fn_gl{FramebufferTexture}
* @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) {
@ -256,7 +260,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param mipLevel Mip level
* @param layer Layer of 2D image within a 3D texture.
*
* @see bind(), @fn_gl{FramebufferTexture}
* @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) {

30
src/Implementation/FramebufferState.h

@ -0,0 +1,30 @@
#ifndef Magnum_Implementation_FramebufferState_h
#define Magnum_Implementation_FramebufferState_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "Magnum.h"
namespace Magnum { namespace Implementation {
struct FramebufferState {
inline FramebufferState(): readBinding(0), drawBinding(0) {}
GLuint readBinding, drawBinding;
};
}}
#endif

9
src/Implementation/State.cpp

@ -16,18 +16,25 @@
#include "State.h"
#include "BufferState.h"
#include "FramebufferState.h"
#include "MeshState.h"
#include "ShaderProgramState.h"
#include "TextureState.h"
namespace Magnum { namespace Implementation {
State::State(): buffer(new BufferState), mesh(new MeshState), shaderProgram(new ShaderProgramState), texture(new TextureState) {}
State::State():
buffer(new BufferState),
framebuffer(new FramebufferState),
mesh(new MeshState),
shaderProgram(new ShaderProgramState),
texture(new TextureState) {}
State::~State() {
delete texture;
delete shaderProgram;
delete mesh;
delete framebuffer;
delete buffer;
}

2
src/Implementation/State.h

@ -20,6 +20,7 @@
namespace Magnum { namespace Implementation {
struct BufferState;
struct FramebufferState;
struct MeshState;
struct ShaderProgramState;
struct TextureState;
@ -29,6 +30,7 @@ struct State {
~State();
BufferState* const buffer;
FramebufferState* const framebuffer;
MeshState* const mesh;
ShaderProgramState* const shaderProgram;
TextureState* const texture;

Loading…
Cancel
Save