#include "framebuffer.hpp" #include #include void FrameBuffer::init() { // target_fb configuration // ------------------------- glGenFramebuffers(1, &target_fb); glBindFramebuffer(GL_FRAMEBUFFER, target_fb); // create the multisamples color attachment texture glGenTextures(1, &texture_multi); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture_multi); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture_multi, 0); // create a renderbuffer object for depth and stencil attachment (we won't be sampling these) glGenRenderbuffers(1, &target_rbo); glBindRenderbuffer(GL_RENDERBUFFER, target_rbo); glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer. glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, target_rbo); // now actually attach it // now that we actually created the target_fb and added all attachments we want to check if it is actually complete now dbc::check(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame buffer not complete."); glBindFramebuffer(GL_FRAMEBUFFER, 0); // intermediate fbo here glGenFramebuffers(1, &intermediate_fbo); glBindFramebuffer(GL_FRAMEBUFFER, intermediate_fbo); // create a color attachment texture glGenTextures(1, &texture_buffer); glBindTexture(GL_TEXTURE_2D, texture_buffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_buffer, 0); dbc::check(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame buffer not complete."); glBindFramebuffer(GL_FRAMEBUFFER, 0); } void FrameBuffer::begin() { // target_fb stuff here glBindFramebuffer(GL_FRAMEBUFFER, target_fb); glEnable(GL_DEPTH_TEST); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void FrameBuffer::commit() { // disable the frame buffer glBindFramebuffer(GL_READ_FRAMEBUFFER, target_fb); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_fbo); glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, 0); } void FrameBuffer::draw(Screen& screen) { glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); screen.shader.use(); glBindVertexArray(screen.target_VAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture_buffer); glDrawArrays(GL_TRIANGLES, 0, 6); }