Browse Source

More intuitive framebuffer attachment mapping.

pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
72d48ac3e7
  1. 22
      src/DefaultFramebuffer.cpp
  2. 29
      src/DefaultFramebuffer.h
  3. 28
      src/Framebuffer.cpp
  4. 31
      src/Framebuffer.h

22
src/DefaultFramebuffer.cpp

@ -27,15 +27,27 @@ DefaultFramebuffer defaultFramebuffer;
DefaultFramebuffer::DefaultFramebuffer() { _id = 0; }
#ifndef MAGNUM_TARGET_GLES2
void DefaultFramebuffer::mapForDraw(std::initializer_list<DrawAttachment> attachments) {
GLenum* _attachments = new GLenum[attachments.size()];
for(auto it = attachments.begin(); it != attachments.end(); ++it)
_attachments[it-attachments.begin()] = static_cast<GLenum>(*it);
void DefaultFramebuffer::mapForDraw(std::initializer_list<std::pair<GLuint, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
if(attachment.first > max) max = attachment.first;
/* Create linear array from associative */
GLenum* _attachments = new GLenum[max+1];
std::fill_n(_attachments, max, GL_NONE);
for(const auto& attachment: attachments)
_attachments[attachment.first] = static_cast<GLenum>(attachment.second);
bindInternal(drawTarget);
glDrawBuffers(attachments.size(), _attachments);
glDrawBuffers(max+1, _attachments);
delete[] _attachments;
}
void DefaultFramebuffer::mapForDraw(DrawAttachment attachment) {
bindInternal(drawTarget);
glDrawBuffer(static_cast<GLenum>(attachment));
}
#endif
void DefaultFramebuffer::mapForRead(ReadAttachment attachment) {

29
src/DefaultFramebuffer.h

@ -168,21 +168,38 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Map given attachments for drawing
* @param attachments Attachments. If any value is
* @ref DrawAttachment "Attachment::None", given output is not
* used.
* @brief Map shader outputs to buffer attachment
*
* @p attachments is list of shader outputs mapped to framebuffer
* buffer attachments. Shader outputs which are not listed are not
* used, you can achieve the same by passing @ref DrawAttachment "DrawAttachment::None"
* as attachment. Example usage:
* @code
* framebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft},
* {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}});
* @endcode
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers}
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
void mapForDraw(std::initializer_list<DrawAttachment> attachments);
void mapForDraw(std::initializer_list<std::pair<GLuint, DrawAttachment>> attachments);
/**
* @brief Map shader output to buffer attachment
* @param attachment Buffer attachment
*
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer}
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
void mapForDraw(DrawAttachment attachment);
#endif
/**
* @brief Map given attachment for reading
* @param attachment Attachment
* @param attachment Buffer attachment
*
* @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}

28
src/Framebuffer.cpp

@ -42,17 +42,29 @@ Framebuffer::~Framebuffer() {
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)
attachments[it-colorAttachments.begin()] = *it + GL_COLOR_ATTACHMENT0;
bindInternal(Target::Draw);
void Framebuffer::mapForDraw(std::initializer_list<std::pair<GLuint, std::int8_t>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
if(attachment.first > max) max = attachment.first;
/* Create linear array from associative */
GLenum* _attachments = new GLenum[max+1];
std::fill_n(_attachments, max, GL_NONE);
for(const auto& attachment: attachments)
_attachments[attachment.first] = attachment.second < 0 ? GL_NONE : GL_COLOR_ATTACHMENT0 + attachment.second;
bindInternal(drawTarget);
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glDrawBuffers(colorAttachments.size(), attachments);
glDrawBuffers(max+1, _attachments);
#endif
delete[] attachments;
delete[] _attachments;
}
void Framebuffer::mapForDraw(std::int8_t attachment) {
bindInternal(drawTarget);
glDrawBuffer(static_cast<GLenum>(attachment));
}
void Framebuffer::mapForRead(std::uint8_t colorAttachment) {

31
src/Framebuffer.h

@ -49,23 +49,40 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
~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.
* @brief Map shader output to color attachment
*
* @p attachments is list of shader outputs mapped to framebuffer
* color attachment IDs. Shader outputs which are not listed are not
* used, you can achieve the same by passing `-1` as color attachment
* ID. Example usage:
* @code
* framebuffer.mapForDraw({{MyShader::ColorOutput, 0},
* {MyShader::NormalOutput, 1}});
* @endcode
* @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);
void mapForDraw(std::initializer_list<std::pair<GLuint, std::int8_t>> attachments);
/**
* @brief Map given color attachment of current framebuffer for reading
* @param colorAttachment Color attachment ID
* @brief Map shader output to color attachment
* @param attachment Color attachment ID
*
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer}
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/
void mapForDraw(std::int8_t attachment);
/**
* @brief Map given color attachment for reading
* @param attachment Color attachment ID
*
* @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/
void mapForRead(std::uint8_t colorAttachment);
void mapForRead(std::uint8_t attachment);
/**
* @brief Attachment for depth/stencil part of fragment shader output

Loading…
Cancel
Save