170 lines
4.5 KiB
C++
170 lines
4.5 KiB
C++
#include "Framebuffer.h"
|
|
|
|
#include <cstddef>
|
|
#include <iostream>
|
|
|
|
Framebuffer::Framebuffer(uint32_t width, uint32_t height, ShaderProgram *shaderProgram) : shaderProgram(shaderProgram)
|
|
{
|
|
glGenFramebuffers(1, &FBO);
|
|
|
|
generateTextures(width, height);
|
|
setExposureCorrection(true);
|
|
}
|
|
|
|
Framebuffer::~Framebuffer()
|
|
{
|
|
glDeleteFramebuffers(1, &FBO);
|
|
glDeleteTextures(1, &colorBuffer);
|
|
glDeleteRenderbuffers(1, &depthStencilBuffer);
|
|
}
|
|
|
|
void Framebuffer::bind()
|
|
{
|
|
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
|
}
|
|
|
|
void Framebuffer::unbind()
|
|
{
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
}
|
|
|
|
void Framebuffer::render()
|
|
{
|
|
// Disable wireframe mode
|
|
GLint wireframe;
|
|
glGetIntegerv(GL_POLYGON_MODE, &wireframe);
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
shaderProgram->bind();
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, getTextureId());
|
|
|
|
GLint location = glGetUniformLocation(shaderProgram->getShaderProgramId(), "u_texture");
|
|
glUniform1i(location, 0);
|
|
|
|
// A VAO is necessary although no data is stored in it
|
|
GLuint temp_vao;
|
|
glGenVertexArrays(1, &temp_vao);
|
|
glBindVertexArray(temp_vao);
|
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
glBindVertexArray(0);
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, wireframe);
|
|
shaderProgram->unbind();
|
|
}
|
|
|
|
void Framebuffer::changeDimensions(uint32_t width, uint32_t height)
|
|
{
|
|
// Delete old textures
|
|
glDeleteTextures(1, &colorBuffer);
|
|
glDeleteRenderbuffers(1, &depthStencilBuffer);
|
|
|
|
generateTextures(width, height);
|
|
}
|
|
|
|
void Framebuffer::generateTextures(uint32_t width, uint32_t height)
|
|
{
|
|
bind();
|
|
|
|
// Create new textures
|
|
glGenTextures(1, &colorBuffer);
|
|
glGenRenderbuffers(1, &depthStencilBuffer);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, colorBuffer);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 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, colorBuffer, 0);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilBuffer);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
std::cout << "[Error] Framebuffer is not complete!" << std::endl;
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
unbind();
|
|
}
|
|
|
|
void Framebuffer::setExposureCorrection(bool exposureCorrection)
|
|
{
|
|
shaderProgram->bind();
|
|
shaderProgram->setUniform("u_exposureCorrection", exposureCorrection);
|
|
shaderProgram->unbind();
|
|
}
|
|
|
|
GLuint Framebuffer::getTextureId()
|
|
{
|
|
return colorBuffer;
|
|
}
|
|
|
|
DepthMap::DepthMap(int TYPE, int RESOLUTION)
|
|
{
|
|
glGenFramebuffers(1, &depthMapFBO);
|
|
bind();
|
|
|
|
if (TYPE == DEPTHMAP_NORMAL) {
|
|
|
|
glGenTextures(1, &depthMap);
|
|
glBindTexture(GL_TEXTURE_2D, depthMap);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, RESOLUTION, RESOLUTION, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
|
|
NULL);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
|
|
glDrawBuffer(GL_NONE);
|
|
glReadBuffer(GL_NONE);
|
|
|
|
} else if (TYPE == DEPTHMAP_CUBEMAP) {
|
|
cubeMap = new CubeMap(RESOLUTION);
|
|
|
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, cubeMap->getTextureId(), 0);
|
|
glDrawBuffer(GL_NONE);
|
|
glReadBuffer(GL_NONE);
|
|
}
|
|
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
std::cout << "[Error] Framebuffer is not complete!" << std::endl;
|
|
|
|
unbind();
|
|
}
|
|
|
|
DepthMap::~DepthMap()
|
|
{
|
|
if (cubeMap)
|
|
delete cubeMap;
|
|
}
|
|
|
|
void DepthMap::bind()
|
|
{
|
|
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
|
|
}
|
|
|
|
void DepthMap::unbind()
|
|
{
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
}
|
|
|
|
GLuint DepthMap::getFBO()
|
|
{
|
|
return depthMapFBO;
|
|
}
|
|
|
|
GLuint DepthMap::getDepthMap()
|
|
{
|
|
return depthMap;
|
|
}
|
|
|
|
GLuint DepthMap::getCubeMapId()
|
|
{
|
|
return cubeMap->getTextureId();
|
|
}
|