Browse Source

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.
pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
19029d97c6
  1. 58
      src/AbstractFramebuffer.cpp
  2. 57
      src/AbstractFramebuffer.h
  3. 5
      src/Context.cpp
  4. 27
      src/DefaultFramebuffer.cpp
  5. 15
      src/DefaultFramebuffer.h
  6. 97
      src/Framebuffer.cpp
  7. 88
      src/Framebuffer.h
  8. 2
      src/Implementation/FramebufferState.h

58
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<GLenum>(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<GLbitfield>(mask), static_cast<GLenum>(filter));
#else
static_cast<void>(sourceBottomLeft);
static_cast<void>(sourceTopRight);
static_cast<void>(destinationBottomLeft);
static_cast<void>(destinationTopRight);
static_cast<void>(mask);
static_cast<void>(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<GLbitfield>(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<GLenum>(format), static_cast<GLenum>(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)

57
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<GLbitfield>(mask), static_cast<GLenum>(filter));
#else
static_cast<void>(sourceBottomLeft);
static_cast<void>(sourceTopRight);
static_cast<void>(destinationBottomLeft);
static_cast<void>(destinationTopRight);
static_cast<void>(mask);
static_cast<void>(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<GLbitfield>(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:

5
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);
}

27
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<DrawAttachment> attach
for(auto it = attachments.begin(); it != attachments.end(); ++it)
_attachments[it-attachments.begin()] = static_cast<GLenum>(*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<GLenum>(attachment));
#else
static_cast<void>(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]};
}
}

15
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<GLenum>(attachment));
#else
static_cast<void>(attachment);
#endif
}
void mapForRead(ReadAttachment attachment);
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
};
/** @brief Default framebuffer instance */

97
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<std::int8_t> 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<std::int8_t> 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<void>(colorAttachment);
#endif
}
void Framebuffer::attachRenderbuffer(Target target, DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer) {
bindInternal(target);
glFramebufferRenderbuffer(static_cast<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), GL_RENDERBUFFER, renderbuffer->id());
}
void Framebuffer::attachRenderbuffer(Target target, std::uint8_t colorAttachment, Renderbuffer* renderbuffer) {
bindInternal(target);
glFramebufferRenderbuffer(static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer);
#else
static_cast<void>(depthStencilAttachment);
static_cast<void>(texture);
static_cast<void>(mipLevel);
static_cast<void>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer);
#else
static_cast<void>(colorAttachment);
static_cast<void>(texture);
static_cast<void>(mipLevel);
static_cast<void>(layer);
#endif
}
}

88
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<void>(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<GLenum>(target), static_cast<GLenum>(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<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(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<GLenum>(target), static_cast<GLenum>(depthStencilAttachment), static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer);
#else
static_cast<void>(depthStencilAttachment);
static_cast<void>(texture);
static_cast<void>(mipLevel);
static_cast<void>(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<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer);
#else
static_cast<void>(colorAttachment);
static_cast<void>(texture);
static_cast<void>(mipLevel);
static_cast<void>(layer);
#endif
}
void attachTexture3D(Target target, std::uint8_t colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer);
};
}

2
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;
};
}}

Loading…
Cancel
Save