learn-opengl/33-shadow-mapping/src/framebuffer.cpp

72 lines
3 KiB
C++

#include "framebuffer.hpp"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
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);
}