Browse Source

Reworked framebuffer attachment enums.

Instead of having pair of functions for depth/stencil and color
attachments this is now solved using specialized class. It is now more
descriptive, as specifying color attachment is now done explicitly using
Framebuffer::ColorAttachment(2) instead of just `2`. Specifying "no
attachment" is now also done explicitly using
Framebuffer::DrawAttachment::None instead of `-1`.

Also updated related documentation.
pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
80cb4eb8e5
  1. 58
      src/DefaultFramebuffer.h
  2. 52
      src/Framebuffer.cpp
  3. 306
      src/Framebuffer.h

58
src/DefaultFramebuffer.h

@ -85,32 +85,32 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
* Write output to back left framebuffer. * Write output to front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
BackLeft = GL_BACK_LEFT, FrontLeft = GL_FRONT_LEFT,
/** /**
* Write output to back right framebuffer. * Write output to front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
BackRight = GL_BACK_RIGHT, FrontRight = GL_FRONT_RIGHT,
/** /**
* Write output to front left framebuffer. * Write output to back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
FrontLeft = GL_FRONT_LEFT, BackLeft = GL_BACK_LEFT,
/** /**
* Write output to front right framebuffer. * Write output to back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
FrontRight = GL_FRONT_RIGHT, BackRight = GL_BACK_RIGHT,
#endif #endif
/** /**
* Write output to back framebuffer. * Write output to back buffer.
* *
* On desktop OpenGL, this is equal to @ref DrawAttachment "DrawAttachment::BackLeft". * On desktop OpenGL, this is equal to @ref DrawAttachment "DrawAttachment::BackLeft".
*/ */
@ -121,7 +121,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#endif #endif
/** /**
* Write output to front framebuffer. * Write output to front buffer.
* *
* On desktop OpenGL, this is equal to @ref DrawAttachment "DrawAttachment::FrontLeft". * On desktop OpenGL, this is equal to @ref DrawAttachment "DrawAttachment::FrontLeft".
*/ */
@ -140,52 +140,52 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/ */
enum class ReadAttachment: GLenum { enum class ReadAttachment: GLenum {
/** Don't read from any framebuffer */ /** Don't read from any buffer */
None = GL_NONE, None = GL_NONE,
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
* Read from back left framebuffer. * Read from front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
BackLeft = GL_BACK_LEFT, FrontLeft = GL_FRONT_LEFT,
/** /**
* Read from back right framebuffer. * Read from front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
BackRight = GL_BACK_RIGHT, FrontRight = GL_FRONT_RIGHT,
/** /**
* Read from front left framebuffer. * Read from back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
FrontLeft = GL_FRONT_LEFT, BackLeft = GL_BACK_LEFT,
/** /**
* Read from front right framebuffer. * Read from back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
FrontRight = GL_FRONT_RIGHT, BackRight = GL_BACK_RIGHT,
/** /**
* Read from left framebuffer. * Read from left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
Left = GL_LEFT, Left = GL_LEFT,
/** /**
* Read from right framebuffer. * Read from right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES. * @requires_gl Stereo rendering is not available in OpenGL ES.
*/ */
Right = GL_RIGHT, Right = GL_RIGHT,
#endif #endif
/** Read from back framebuffer. */ /** Read from back buffer. */
Back = GL_BACK, Back = GL_BACK,
/** /**
* Read from front framebuffer. * Read from front buffer.
* @requires_es_extension %Extension @es_extension2{NV,read_buffer_front,GL_NV_read_buffer} * @requires_es_extension %Extension @es_extension2{NV,read_buffer_front,GL_NV_read_buffer}
*/ */
Front = GL_FRONT Front = GL_FRONT
@ -194,7 +194,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
, ,
/** /**
* Read from front and back framebuffer. * Read from front and back buffer.
* @requires_gl In OpenGL ES you must specify either * @requires_gl In OpenGL ES you must specify either
* @ref Magnum::DefaultFramebuffer::ReadAttachment "ReadAttachment::Front" * @ref Magnum::DefaultFramebuffer::ReadAttachment "ReadAttachment::Front"
* or @ref Magnum::DefaultFramebuffer::ReadAttachment "ReadAttachment::Back". * or @ref Magnum::DefaultFramebuffer::ReadAttachment "ReadAttachment::Back".
@ -209,9 +209,9 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/** /**
* @brief Map shader outputs to buffer attachment * @brief Map shader outputs to buffer attachment
* *
* @p attachments is list of shader outputs mapped to framebuffer * @p attachments is list of shader outputs mapped to buffer
* buffer attachments. Shader outputs which are not listed are not * attachments. %Shader outputs which are not listed are not used, you
* used, you can achieve the same by passing @ref DrawAttachment "DrawAttachment::None" * can achieve the same by passing @ref DrawAttachment "DrawAttachment::None"
* as attachment. Example usage: * as attachment. Example usage:
* @code * @code
* framebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft}, * framebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft},
@ -230,7 +230,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/** /**
* @brief Map shader output to buffer attachment * @brief Map shader output to buffer attachment
* @param attachment Buffer attachment * @param attachment %Buffer attachment
* *
* Similar to above function, can be used in cases when shader has * Similar to above function, can be used in cases when shader has
* only one (unnamed) output. * only one (unnamed) output.
@ -250,7 +250,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/** /**
* @brief Map given attachment for reading * @brief Map given attachment for reading
* @param attachment Buffer attachment * @param attachment %Buffer attachment
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the * framebufferbuffer is not currently bound, it is bound before the

52
src/Framebuffer.cpp

@ -34,6 +34,13 @@ Framebuffer::Texture1DImplementation Framebuffer::texture1DImplementation = &Fra
Framebuffer::Texture2DImplementation Framebuffer::texture2DImplementation = &Framebuffer::texture2DImplementationDefault; Framebuffer::Texture2DImplementation Framebuffer::texture2DImplementation = &Framebuffer::texture2DImplementationDefault;
Framebuffer::Texture3DImplementation Framebuffer::texture3DImplementation = &Framebuffer::texture3DImplementationDefault; Framebuffer::Texture3DImplementation Framebuffer::texture3DImplementation = &Framebuffer::texture3DImplementationDefault;
const Framebuffer::DrawAttachment Framebuffer::DrawAttachment::None = Framebuffer::DrawAttachment(GL_NONE);
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::Depth = Framebuffer::BufferAttachment(GL_DEPTH_ATTACHMENT);
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::Stencil = Framebuffer::BufferAttachment(GL_STENCIL_ATTACHMENT);
#ifndef MAGNUM_TARGET_GLES2
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::DepthStencil = Framebuffer::BufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT);
#endif
Framebuffer::Framebuffer(const Rectanglei& viewport) { Framebuffer::Framebuffer(const Rectanglei& viewport) {
_viewport = viewport; _viewport = viewport;
@ -49,7 +56,7 @@ Framebuffer::~Framebuffer() {
glDeleteFramebuffers(1, &_id); glDeleteFramebuffers(1, &_id);
} }
void Framebuffer::mapForDraw(std::initializer_list<std::pair<GLuint, std::int8_t>> attachments) { void Framebuffer::mapForDraw(std::initializer_list<std::pair<GLuint, DrawAttachment>> attachments) {
/* Max attachment location */ /* Max attachment location */
std::size_t max = 0; std::size_t max = 0;
for(const auto& attachment: attachments) for(const auto& attachment: attachments)
@ -59,20 +66,15 @@ void Framebuffer::mapForDraw(std::initializer_list<std::pair<GLuint, std::int8_t
GLenum* _attachments = new GLenum[max+1]; GLenum* _attachments = new GLenum[max+1];
std::fill_n(_attachments, max, GL_NONE); std::fill_n(_attachments, max, GL_NONE);
for(const auto& attachment: attachments) for(const auto& attachment: attachments)
_attachments[attachment.first] = attachment.second < 0 ? GL_NONE : GL_COLOR_ATTACHMENT0 + attachment.second; _attachments[attachment.first] = GLenum(attachment.second);
(this->*drawBuffersImplementation)(max+1, _attachments); (this->*drawBuffersImplementation)(max+1, _attachments);
delete[] _attachments; delete[] _attachments;
} }
void Framebuffer::attachTexture2D(DepthStencilAttachment depthStencilAttachment, Texture2D* texture, GLint mipLevel) { void Framebuffer::attachTexture2D(BufferAttachment attachment, Texture2D* texture, GLint mipLevel) {
/** @todo Check for texture target compatibility */
(this->*texture2DImplementation)(GLenum(depthStencilAttachment), GLenum(texture->target()), texture->id(), mipLevel);
}
void Framebuffer::attachTexture2D(std::uint8_t colorAttachment, Texture2D* texture, GLint mipLevel) {
/** @todo Check for texture target compatibility */ /** @todo Check for texture target compatibility */
(this->*texture2DImplementation)(GL_COLOR_ATTACHMENT0 + colorAttachment, GLenum(texture->target()), texture->id(), mipLevel); (this->*texture2DImplementation)(attachment, GLenum(texture->target()), texture->id(), mipLevel);
} }
void Framebuffer::initializeContextBasedFunctionality(Context* context) { void Framebuffer::initializeContextBasedFunctionality(Context* context) {
@ -90,39 +92,39 @@ void Framebuffer::initializeContextBasedFunctionality(Context* context) {
#endif #endif
} }
void Framebuffer::renderbufferImplementationDefault(GLenum attachment, Renderbuffer* renderbuffer) { void Framebuffer::renderbufferImplementationDefault(BufferAttachment attachment, Renderbuffer* renderbuffer) {
glFramebufferRenderbuffer(GLenum(bindInternal()), attachment, GL_RENDERBUFFER, renderbuffer->id()); glFramebufferRenderbuffer(GLenum(bindInternal()), GLenum(attachment), GL_RENDERBUFFER, renderbuffer->id());
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Framebuffer::renderbufferImplementationDSA(GLenum attachment, Renderbuffer* renderbuffer) { void Framebuffer::renderbufferImplementationDSA(BufferAttachment attachment, Renderbuffer* renderbuffer) {
glNamedFramebufferRenderbufferEXT(_id, attachment, GL_RENDERBUFFER, renderbuffer->id()); glNamedFramebufferRenderbufferEXT(_id, GLenum(attachment), GL_RENDERBUFFER, renderbuffer->id());
} }
void Framebuffer::texture1DImplementationDefault(GLenum attachment, Texture1D* texture, GLint mipLevel) { void Framebuffer::texture1DImplementationDefault(BufferAttachment attachment, Texture1D* texture, GLint mipLevel) {
glFramebufferTexture1D(GLenum(bindInternal()), attachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel); glFramebufferTexture1D(GLenum(bindInternal()), GLenum(attachment), static_cast<GLenum>(texture->target()), texture->id(), mipLevel);
} }
void Framebuffer::texture1DImplementationDSA(GLenum attachment, Texture1D* texture, GLint mipLevel) { void Framebuffer::texture1DImplementationDSA(BufferAttachment attachment, Texture1D* texture, GLint mipLevel) {
glNamedFramebufferTexture1DEXT(_id, attachment, GLenum(texture->target()), texture->id(), mipLevel); glNamedFramebufferTexture1DEXT(_id, GLenum(attachment), GLenum(texture->target()), texture->id(), mipLevel);
} }
#endif #endif
void Framebuffer::texture2DImplementationDefault(GLenum attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) { void Framebuffer::texture2DImplementationDefault(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) {
glFramebufferTexture2D(GLenum(bindInternal()), attachment, textureTarget, textureId, mipLevel); glFramebufferTexture2D(GLenum(bindInternal()), GLenum(attachment), textureTarget, textureId, mipLevel);
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Framebuffer::texture2DImplementationDSA(GLenum attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) { void Framebuffer::texture2DImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) {
glNamedFramebufferTexture2DEXT(_id, attachment, textureTarget, textureId, mipLevel); glNamedFramebufferTexture2DEXT(_id, GLenum(attachment), textureTarget, textureId, mipLevel);
} }
#endif #endif
void Framebuffer::texture3DImplementationDefault(GLenum attachment, Texture3D* texture, GLint mipLevel, GLint layer) { void Framebuffer::texture3DImplementationDefault(BufferAttachment attachment, Texture3D* texture, GLint mipLevel, GLint layer) {
/** @todo Check for texture target compatibility */ /** @todo Check for texture target compatibility */
/** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
glFramebufferTexture3D(GLenum(bindInternal()), attachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer); glFramebufferTexture3D(GLenum(bindInternal()), GLenum(attachment), static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer);
#else #else
static_cast<void>(attachment); static_cast<void>(attachment);
static_cast<void>(texture); static_cast<void>(texture);
@ -132,8 +134,8 @@ void Framebuffer::texture3DImplementationDefault(GLenum attachment, Texture3D* t
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Framebuffer::texture3DImplementationDSA(GLenum attachment, Texture3D* texture, GLint mipLevel, GLint layer) { void Framebuffer::texture3DImplementationDSA(BufferAttachment attachment, Texture3D* texture, GLint mipLevel, GLint layer) {
glNamedFramebufferTexture3DEXT(_id, attachment, GLenum(texture->target()), texture->id(), mipLevel, layer); glNamedFramebufferTexture3DEXT(_id, GLenum(attachment), GLenum(texture->target()), texture->id(), mipLevel, layer);
} }
#endif #endif

306
src/Framebuffer.h

@ -46,16 +46,16 @@ Renderbuffer depthStencil;
// configure the textures and allocate texture memory... // configure the textures and allocate texture memory...
framebuffer.attachTexture2D(0, &color); framebuffer.attachTexture2D(Framebuffer::ColorAttachment(0), &color);
framebuffer.attachTexture2D(1, &normal); framebuffer.attachTexture2D(Framebuffer::ColorAttachment(1), &normal);
framebuffer.attachRenderbuffer(Framebuffer::DepthStencilAttachment::DepthStencil, &depthStencil); framebuffer.attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, &depthStencil);
@endcode @endcode
Then you need to map outputs of your shader to color attachments in the Then you need to map outputs of your shader to color attachments in the
framebuffer: framebuffer:
@code @code
framebuffer.mapForDraw({{MyShader::ColorOutput, 0}, framebuffer.mapForDraw({{MyShader::ColorOutput, Framebuffer::ColorAttachment(0)},
{MyShader::NormalOutput, 1}}); {MyShader::NormalOutput, Framebuffer::ColorAttachment(1)}});
@endcode @endcode
The actual @ref Platform::GlutApplication::drawEvent() "drawEvent()" might The actual @ref Platform::GlutApplication::drawEvent() "drawEvent()" might
@ -64,13 +64,13 @@ off-screen framebuffer, then bind the default and render the textures on
screen: screen:
@code @code
void drawEvent() { void drawEvent() {
defaultFramebuffer.clear(AbstractFramebuffer::Clear::Color) defaultFramebuffer.clear(DefaultFramebuffer::Clear::Color)
framebuffer.clear(AbstractFramebuffer::Clear::Color|AbstractFramebuffer::Clear::Depth|AbstractFramebuffer::Clear::Stencil); framebuffer.clear(Framebuffer::Clear::Color|Framebuffer::Clear::Depth|Framebuffer::Clear::Stencil);
framebuffer.bind(AbstractFramebuffer::Target::Draw); framebuffer.bind(Framebuffer::Target::Draw);
// ... // ...
defaultFramebuffer.bind(AbstractFramebuffer::Target::Draw); defaultFramebuffer.bind(DefaultFramebuffer::Target::Draw);
// ... // ...
} }
@endcode @endcode
@ -91,6 +91,90 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
friend class Context; friend class Context;
public: public:
/**
* @brief Color attachment
*
* @see Attachment, attachRenderbuffer(), attachTexture1D(),
* attachTexture2D(), attachCubeMapTexture(), attachTexture3D()
*/
class ColorAttachment {
friend class Framebuffer;
public:
/**
* @brief Constructor
* @param id Color attachment id
*/
inline constexpr explicit ColorAttachment(std::uint8_t id): attachment(GL_COLOR_ATTACHMENT0 + id) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; }
#endif
private:
GLenum attachment;
};
/**
* @brief Draw attachment
*
* @see mapForDraw()
*/
class DrawAttachment {
public:
/** @brief No attachment */
static const DrawAttachment None;
/** @brief Color attachment */
inline constexpr /*implicit*/ DrawAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; }
#endif
private:
inline constexpr explicit DrawAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment;
};
/**
* @brief %Buffer attachment
*
* @see attachRenderbuffer(), attachTexture1D(), attachTexture2D(),
* attachCubeMapTexture(), attachTexture3D()
*/
class BufferAttachment {
public:
/** @brief Depth buffer */
static const BufferAttachment Depth;
/** @brief Stencil buffer */
static const BufferAttachment Stencil;
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Both depth and stencil buffer
*
* @requires_gles30 Combined depth and stencil attachment is
* not available in OpenGL ES 2.0.
*/
static const BufferAttachment DepthStencil;
#endif
/** @brief Color buffer */
inline constexpr /*implicit*/ BufferAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; }
#endif
private:
inline constexpr explicit BufferAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment;
};
/** /**
* @brief Constructor * @brief Constructor
* *
@ -108,15 +192,15 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
~Framebuffer(); ~Framebuffer();
/** /**
* @brief Map shader output to color attachment * @brief Map shader output to attachments
* *
* @p attachments is list of shader outputs mapped to framebuffer * @p attachments is list of shader outputs mapped to framebuffer
* color attachment IDs. Shader outputs which are not listed are not * color attachment IDs. %Shader outputs which are not listed are not
* used, you can achieve the same by passing `-1` as color attachment * used, you can achieve the same by passing Framebuffer::DrawAttachment::None
* ID. Example usage: * as color attachment ID. Example usage:
* @code * @code
* framebuffer.mapForDraw({{MyShader::ColorOutput, 0}, * framebuffer.mapForDraw({{MyShader::ColorOutput, Framebuffer::ColorAttachment(0)},
* {MyShader::NormalOutput, 1}}); * {MyShader::NormalOutput, Framebuffer::DrawAttachment::None}});
* @endcode * @endcode
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
@ -126,11 +210,11 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access} * @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/ */
void mapForDraw(std::initializer_list<std::pair<GLuint, std::int8_t>> attachments); void mapForDraw(std::initializer_list<std::pair<GLuint, DrawAttachment>> attachments);
/** /**
* @brief Map shader output to color attachment * @brief Map shader output to attachment
* @param attachment Color attachment ID * @param attachment Draw attachment
* *
* Similar to above function, can be used in cases when shader has * Similar to above function, can be used in cases when shader has
* only one (unnamed) output. * only one (unnamed) output.
@ -142,13 +226,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access} * @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/ */
inline void mapForDraw(std::int8_t attachment) { inline void mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + attachment)); (this->*drawBufferImplementation)(GLenum(attachment));
} }
/** /**
* @brief Map given color attachment for reading * @brief Map given color attachment for reading
* @param attachment Color attachment ID * @param attachment Color attachment
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the * framebufferbuffer is not currently bound, it is bound before the
@ -157,35 +241,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} * @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/ */
inline void mapForRead(std::uint8_t attachment) { inline void mapForRead(ColorAttachment attachment) {
(this->*readBufferImplementation)(GL_COLOR_ATTACHMENT0 + attachment); (this->*readBufferImplementation)(GLenum(attachment));
} }
/** /**
* @brief Attachment for depth/stencil part of fragment shader output * @brief Attach renderbuffer to given buffer
* * @param attachment %Buffer attachment
* @see attachRenderbuffer(), attachTexture1D(), attachTexture2D(),
* attachCubeMapTexture(), attachTexture3D()
*/
enum class DepthStencilAttachment: GLenum {
Depth = GL_DEPTH_ATTACHMENT, /**< Depth output only. */
Stencil = GL_STENCIL_ATTACHMENT /**< Stencil output only. */
#ifndef MAGNUM_TARGET_GLES2
,
/**
* Both depth and stencil output.
* @requires_gles30 Combined depth and stencil attachment is not
* available in OpenGL ES 2.0.
*/
DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT
#endif
};
/**
* @brief Attach renderbuffer to given framebuffer depth/stencil attachment
* @param depthStencilAttachment Depth/stencil attachment
* @param renderbuffer %Renderbuffer * @param renderbuffer %Renderbuffer
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
@ -194,48 +256,16 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access} * @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}
*/ */
inline void attachRenderbuffer(DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer) { inline void attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) {
(this->*renderbufferImplementation)(GLenum(depthStencilAttachment), renderbuffer); (this->*renderbufferImplementation)(attachment, renderbuffer);
}
/**
* @brief Attach renderbuffer to given framebuffer color attachment
* @param colorAttachment Color attachment ID (number between 0 and 15)
* @param renderbuffer %Renderbuffer
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}
*/
inline void attachRenderbuffer(std::uint8_t colorAttachment, Renderbuffer* renderbuffer) {
(this->*renderbufferImplementation)(GL_COLOR_ATTACHMENT0 + colorAttachment, renderbuffer);
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Attach 1D texture to given framebuffer depth/stencil attachment * @brief Attach 1D texture to given buffer
* @param depthStencilAttachment Depth/stencil attachment * @param attachment %Buffer attachment
* @param texture 1D texture
* @param mipLevel Mip level
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} or
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES.
*/
inline void attachTexture1D(DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) {
(this->*texture1DImplementation)(GLenum(depthStencilAttachment), texture, mipLevel);
}
/**
* @brief Attach 1D texture to given framebuffer color attachment
* @param colorAttachment Color attachment ID (number between 0 and 15)
* @param texture 1D texture * @param texture 1D texture
* @param mipLevel Mip level * @param level Mip level
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the * framebufferbuffer is not currently bound, it is bound before the
@ -244,32 +274,16 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access} * @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES. * @requires_gl Only 2D and 3D textures are available in OpenGL ES.
*/ */
inline void attachTexture1D(std::uint8_t colorAttachment, Texture1D* texture, GLint mipLevel) { inline void attachTexture1D(BufferAttachment attachment, Texture1D* texture, GLint level) {
(this->*texture1DImplementation)(GL_COLOR_ATTACHMENT0 + colorAttachment, texture, mipLevel); (this->*texture1DImplementation)(attachment, texture, level);
} }
#endif #endif
/** /**
* @brief Attach 2D texture to given framebuffer depth/stencil attachment * @brief Attach 2D texture to given buffer
* @param depthStencilAttachment Depth/stencil attachment * @param attachment %Buffer attachment
* @param texture 2D texture
* @param mipLevel Mip level. For rectangle textures it
* should be always 0.
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see attachCubeMapTexture(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/
void attachTexture2D(DepthStencilAttachment depthStencilAttachment, Texture2D* texture, GLint mipLevel);
/**
* @brief Attach 2D texture to given framebuffer color attachment
* @param colorAttachment Color attachment ID (number between 0 and 15)
* @param texture 2D texture * @param texture 2D texture
* @param mipLevel Mip level. For rectangle textures it * @param level Mip level
* should be always 0.
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the * framebufferbuffer is not currently bound, it is bound before the
@ -277,14 +291,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see attachCubeMapTexture(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @see attachCubeMapTexture(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access} * or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/ */
void attachTexture2D(std::uint8_t colorAttachment, Texture2D* texture, GLint mipLevel); void attachTexture2D(BufferAttachment attachment, Texture2D* texture, GLint level);
/** /**
* @brief Attach cube map texture to given framebuffer depth/stencil attachment * @brief Attach cube map texture to given buffer
* @param depthStencilAttachment Depth/stencil attachment * @param attachment %Buffer attachment
* @param texture Cube map texture * @param texture Cube map texture
* @param coordinate Cube map coordinate * @param coordinate Cube map coordinate
* @param mipLevel Mip level * @param level Mip level
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the * framebufferbuffer is not currently bound, it is bound before the
@ -292,32 +306,15 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access} * or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/ */
inline void attachCubeMapTexture(DepthStencilAttachment depthStencilAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { inline void attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint level) {
(this->*texture2DImplementation)(GLenum(depthStencilAttachment), GLenum(coordinate), texture->id(), mipLevel); (this->*texture2DImplementation)(attachment, GLenum(coordinate), texture->id(), level);
} }
/** /**
* @brief Attach cube map texture to given framebuffer color attachment * @brief Attach 3D texture to given buffer
* @param colorAttachment Color attachment ID (number between 0 and 15) * @param attachment %Buffer attachment
* @param texture Cube map texture
* @param coordinate Cube map coordinate
* @param mipLevel Mip level
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/
inline void attachCubeMapTexture(std::uint8_t colorAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) {
(this->*texture2DImplementation)(GL_COLOR_ATTACHMENT0 + colorAttachment, GLenum(coordinate), texture->id(), mipLevel);
}
/**
* @brief Attach 3D texture to given framebuffer depth/stencil attachment
* @param depthStencilAttachment Depth/stencil attachment
* @param texture 3D texture * @param texture 3D texture
* @param mipLevel Mip level * @param level Mip level
* @param layer Layer of 2D image within a 3D texture * @param layer Layer of 2D image within a 3D texture
* *
* If @extension{EXT,direct_state_access} is not available and the * If @extension{EXT,direct_state_access} is not available and the
@ -327,58 +324,39 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access} * @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,texture_3D} * @requires_es_extension %Extension @es_extension{OES,texture_3D}
*/ */
inline void attachTexture3D(DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { inline void attachTexture3D(BufferAttachment attachment, Texture3D* texture, GLint level, GLint layer) {
/** @todo Check for texture target compatibility */
(this->*texture3DImplementation)(GLenum(depthStencilAttachment), texture, mipLevel, layer);
}
/**
* @brief Attach 3D texture to given framebuffer color attachment
* @param colorAttachment Color attachment ID (number between 0 and 15)
* @param texture 3D texture
* @param mipLevel Mip level
* @param layer Layer of 2D image within a 3D texture.
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} or
* @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,texture_3D}
*/
inline void attachTexture3D(std::uint8_t colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) {
/** @todo Check for texture target compatibility */ /** @todo Check for texture target compatibility */
(this->*texture3DImplementation)(GL_COLOR_ATTACHMENT0 + colorAttachment, texture, mipLevel, layer); (this->*texture3DImplementation)(attachment, texture, level, layer);
} }
private: private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
typedef void(Framebuffer::*RenderbufferImplementation)(GLenum, Renderbuffer*); typedef void(Framebuffer::*RenderbufferImplementation)(BufferAttachment, Renderbuffer*);
void MAGNUM_LOCAL renderbufferImplementationDefault(GLenum attachment, Renderbuffer* renderbuffer); void MAGNUM_LOCAL renderbufferImplementationDefault(BufferAttachment attachment, Renderbuffer* renderbuffer);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL renderbufferImplementationDSA(GLenum attachment, Renderbuffer* renderbuffer); void MAGNUM_LOCAL renderbufferImplementationDSA(BufferAttachment attachment, Renderbuffer* renderbuffer);
#endif #endif
static RenderbufferImplementation renderbufferImplementation; static RenderbufferImplementation renderbufferImplementation;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
typedef void(Framebuffer::*Texture1DImplementation)(GLenum, Texture1D*, GLint); typedef void(Framebuffer::*Texture1DImplementation)(BufferAttachment, Texture1D*, GLint);
void MAGNUM_LOCAL texture1DImplementationDefault(GLenum attachment, Texture1D* texture, GLint mipLevel); void MAGNUM_LOCAL texture1DImplementationDefault(BufferAttachment attachment, Texture1D* texture, GLint level);
void MAGNUM_LOCAL texture1DImplementationDSA(GLenum attachment, Texture1D* texture, GLint mipLevel); void MAGNUM_LOCAL texture1DImplementationDSA(BufferAttachment attachment, Texture1D* texture, GLint level);
static Texture1DImplementation texture1DImplementation; static Texture1DImplementation texture1DImplementation;
#endif #endif
typedef void(Framebuffer::*Texture2DImplementation)(GLenum, GLenum, GLuint, GLint); typedef void(Framebuffer::*Texture2DImplementation)(BufferAttachment, GLenum, GLuint, GLint);
void MAGNUM_LOCAL texture2DImplementationDefault(GLenum attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel); void MAGNUM_LOCAL texture2DImplementationDefault(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL texture2DImplementationDSA(GLenum attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel); void MAGNUM_LOCAL texture2DImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#endif #endif
static MAGNUM_LOCAL Texture2DImplementation texture2DImplementation; static MAGNUM_LOCAL Texture2DImplementation texture2DImplementation;
typedef void(Framebuffer::*Texture3DImplementation)(GLenum, Texture3D*, GLint, GLint); typedef void(Framebuffer::*Texture3DImplementation)(BufferAttachment, Texture3D*, GLint, GLint);
void MAGNUM_LOCAL texture3DImplementationDefault(GLenum attachment, Texture3D* texture, GLint mipLevel, GLint layer); void MAGNUM_LOCAL texture3DImplementationDefault(BufferAttachment attachment, Texture3D* texture, GLint level, GLint layer);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL texture3DImplementationDSA(GLenum attachment, Texture3D* texture, GLint mipLevel, GLint layer); void MAGNUM_LOCAL texture3DImplementationDSA(BufferAttachment attachment, Texture3D* texture, GLint level, GLint layer);
#endif #endif
static Texture3DImplementation texture3DImplementation; static Texture3DImplementation texture3DImplementation;
}; };

Loading…
Cancel
Save