diff --git a/Outputs/OpenGL/Primitives/TextureTarget.cpp b/Outputs/OpenGL/Primitives/TextureTarget.cpp index a4061b21a..0927e9c6d 100644 --- a/Outputs/OpenGL/Primitives/TextureTarget.cpp +++ b/Outputs/OpenGL/Primitives/TextureTarget.cpp @@ -13,28 +13,39 @@ using namespace Outputs::Display::OpenGL; -TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter) : +TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter, bool has_stencil_buffer) : width_(width), height_(height), texture_unit_(texture_unit) { + // Generate and bind a frame buffer. glGenFramebuffers(1, &framebuffer_); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_); + // Round the width and height up to the next power of two. expanded_width_ = 1; while(expanded_width_ < width) expanded_width_ <<= 1; expanded_height_ = 1; while(expanded_height_ < height) expanded_height_ <<= 1; + // Generate a texture and bind it to the nominated texture unit. glGenTextures(1, &texture_); bind_texture(); + // Upload a blank initial texture and set the user-supplied magnification filter. std::vector blank_buffer(static_cast(expanded_width_ * expanded_height_ * 4), 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(expanded_width_), static_cast(expanded_height_), 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer.data()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + // Set the texture as colour attachment 0 on the frame buffer. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0); + // Also add a stencil buffer if requested. + if(has_stencil_buffer) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX1, expanded_width_, expanded_height_); + } + + // Check for successful construction. if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) throw ErrorFramebufferIncomplete; } diff --git a/Outputs/OpenGL/Primitives/TextureTarget.hpp b/Outputs/OpenGL/Primitives/TextureTarget.hpp index 269477da5..16773fc85 100644 --- a/Outputs/OpenGL/Primitives/TextureTarget.hpp +++ b/Outputs/OpenGL/Primitives/TextureTarget.hpp @@ -31,8 +31,9 @@ class TextureTarget { @param width The width of target to create. @param height The height of target to create. @param texture_unit A texture unit on which to bind the texture. + @param has_stencil_buffer A 1-bit stencil buffer is attached if this is @c true; no stencil buffer is attached otherwise. */ - TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter); + TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter, bool has_stencil_buffer); ~TextureTarget(); /*! diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 52365200f..bde563359 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -73,7 +73,7 @@ template void ScanTarget::allocate_buffer(const T &array, GLuint &b } ScanTarget::ScanTarget() : - unprocessed_line_texture_(LineBufferWidth, LineBufferHeight, UnprocessedLineBufferTextureUnit, GL_LINEAR) { + unprocessed_line_texture_(LineBufferWidth, LineBufferHeight, UnprocessedLineBufferTextureUnit, GL_LINEAR, false) { // Ensure proper initialisation of the two atomic pointer sets. read_pointers_.store(write_pointers_);