2024-08-13 17:47:16 -04:00
|
|
|
#include <GL/glew.h>
|
|
|
|
#include <GLFW/glfw3.h>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include "fbo.h"
|
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
namespace FBO {
|
|
|
|
Framebuffer GenerateFramebuffer(int width, int height) {
|
|
|
|
Framebuffer fbo;
|
|
|
|
fbo.id = CreateFramebuffer();
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
|
2024-08-13 17:47:16 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
fbo.albedoTexture = CreateTexture(width, height, GL_RGBA);
|
|
|
|
fbo.positionTexture = CreateTexture(width, height, GL_RGBA);
|
|
|
|
fbo.normalTexture = CreateTexture(width, height, GL_RGBA);
|
|
|
|
fbo.depthTexture = CreateDepthTexture(width, height);
|
2024-08-13 17:47:16 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
AttachTextureToFramebuffer(fbo.id, fbo.albedoTexture, GL_COLOR_ATTACHMENT0);
|
|
|
|
AttachTextureToFramebuffer(fbo.id, fbo.positionTexture, GL_COLOR_ATTACHMENT1);
|
|
|
|
AttachTextureToFramebuffer(fbo.id, fbo.normalTexture, GL_COLOR_ATTACHMENT2);
|
2024-08-13 17:47:16 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
GLenum drawBuffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
|
|
|
glDrawBuffers(3, drawBuffers);
|
2024-08-13 17:47:16 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
|
|
|
std::cerr << "Error: Framebuffer is not complete!" << std::endl;
|
|
|
|
}
|
2024-08-17 19:08:11 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2024-08-17 19:40:42 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
return fbo;
|
2024-08-13 17:47:16 -04:00
|
|
|
}
|
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
GLuint CreateFramebuffer() {
|
|
|
|
GLuint fboId = 0;
|
|
|
|
glGenFramebuffers(1, &fboId);
|
|
|
|
return fboId;
|
2024-08-13 17:47:16 -04:00
|
|
|
}
|
2024-08-20 00:47:41 -04:00
|
|
|
|
|
|
|
GLuint CreateTexture(int width, int height, GLenum format) {
|
|
|
|
GLuint textureId = 0;
|
|
|
|
glGenTextures(1, &textureId);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textureId);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, format, GL_FLOAT, nullptr);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
if(textureId == 0) {
|
|
|
|
std::cerr << "Texture was not created!" << std::endl;
|
|
|
|
}
|
|
|
|
return textureId;
|
2024-08-13 17:47:16 -04:00
|
|
|
}
|
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
GLuint CreateDepthTexture(int width, int height) {
|
|
|
|
GLuint depthId;
|
|
|
|
glGenRenderbuffers(1, &depthId);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, depthId);
|
|
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height);
|
|
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthId);
|
|
|
|
if(depthId == 0) {
|
|
|
|
std::cerr << "Depth Texture was not created!" << std::endl;
|
|
|
|
}
|
|
|
|
return depthId;
|
|
|
|
}
|
2024-08-17 19:40:42 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
void AttachTextureToFramebuffer(GLuint framebufferId, GLuint textureId, GLenum attachment) {
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, textureId, 0);
|
|
|
|
}
|
2024-08-17 19:10:41 -04:00
|
|
|
|
2024-08-20 00:47:41 -04:00
|
|
|
void Cleanup(const Framebuffer& fbo) {
|
|
|
|
if (fbo.albedoTexture != 0) {
|
|
|
|
glDeleteTextures(1, &fbo.albedoTexture);
|
|
|
|
}
|
|
|
|
if (fbo.positionTexture != 0) {
|
|
|
|
glDeleteTextures(1, &fbo.positionTexture);
|
|
|
|
}
|
|
|
|
if (fbo.normalTexture != 0) {
|
|
|
|
glDeleteTextures(1, &fbo.normalTexture);
|
|
|
|
}
|
|
|
|
if (fbo.depthTexture != 0) {
|
|
|
|
glDeleteTextures(1, &fbo.depthTexture);
|
|
|
|
}
|
|
|
|
if (fbo.id != 0) {
|
|
|
|
glDeleteFramebuffers(1, &fbo.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}; // namespace
|