This image is supposed to be a tv on a stand.
What I am doing is both bloom and shadows, so I need 3 framebuffers to do this. I haven’t got the shadow maps to work yet but I want to get my objects to show up properly first. I have a point light in a room, so I guess cube maps are used for this.
this is the setup for the framebuffers:
GLuint hdrFBO;
glGenFramebuffers(1, &hdrFBO);
glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO);
// Color buffers (HDR + Bright)
GLuint colorBuffers[2];
glGenTextures(2, colorBuffers);
for (int i = 0; i < 2; ++i)
{
glBindTexture(GL_TEXTURE_2D, colorBuffers[i]);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F,
gWindowWidth,
gWindowHeight,
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0 + i,
GL_TEXTURE_2D,
colorBuffers[i],
0
);
}
// Depth buffer
GLuint rboDepth;
glGenRenderbuffers(1, &rboDepth);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepth);
glRenderbufferStorage(
GL_RENDERBUFFER,
GL_DEPTH_COMPONENT24,
gWindowWidth,
gWindowHeight
);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
rboDepth
);
// Tell OpenGL we have two color outputs
GLuint attachments[2] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1
};
glDrawBuffers(2, attachments);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "HDR FBO broken\n";
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Sanity check
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// ------------------------------------------------------------
// PING-PONG FRAMEBUFFERS (bloom blur)
// ------------------------------------------------------------
GLuint pingpongFBO[2];
GLuint pingpongColorBuffers[2];
glGenFramebuffers(2, pingpongFBO);
glGenTextures(2, pingpongColorBuffers);
for (int i = 0; i < 2; ++i)
{
glBindFramebuffer(GL_FRAMEBUFFER, pingpongFBO[i]);
glBindTexture(GL_TEXTURE_2D, pingpongColorBuffers[i]);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F,
gWindowWidth,
gWindowHeight,
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
pingpongColorBuffers[i],
0
);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "Pingpong FBO broken\n";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// ------------------------------------------------------------
// DEPTH CUBEMAP (point light shadows)
// ------------------------------------------------------------
const unsigned int SHADOW_WIDTH = 1024;
const unsigned int SHADOW_HEIGHT = 1024;
// Depth cubemap texture
GLuint depthCubemap;
glGenTextures(1, &depthCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glTexImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
0,
GL_DEPTH_COMPONENT,
SHADOW_WIDTH,
SHADOW_HEIGHT,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
nullptr
);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// Shadow FBO
GLuint depthCubemapFBO;
glGenFramebuffers(1, &depthCubemapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, depthCubemapFBO);
glFramebufferTexture(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
depthCubemap,
0
);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "Depth cubemap FBO broken\n";
glBindFramebuffer(GL_FRAMEBUFFER, 0);
This is the rendering code up to when I redraw my objects:
glBindFramebuffer(GL_FRAMEBUFFER, depthCubemapFBO);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
sceneShader.use();
for (int i = 0; i < 6; i++)
{
sceneShader.setUniform(
"shadowMatrices[" + std::to_string(i) + "]",
shadowTransforms[i]
);
}
sceneShader.setUniform("lightPos", lightPos);
sceneShader.setUniform("farPlane", wid);
sceneShader.setUniformI("isFan", 0);
model = glm::translate(glm::mat4(1), glm::vec3(-5.894, 1.123, 5.775)) * glm::rotate(glm::mat4(1), glm::radians(135.0f), glm::vec3(0, 1, 0)) * glm::rotate(glm::mat4(1), glm::radians(270.0f), glm::vec3(1, 0, 0));
sceneShader.setUniform("model", model);
// then I render my objects with this shader
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO);
glViewport(0, 0, gWindowWidth, gWindowHeight);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap);
model = glm::rotate(glm::mat4(1), glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::rotate(glm::mat4(1), glm::radians(270.0f), glm::vec3(1, 0, 0)) * glm::scale(glm::mat4(1), glm::vec3(1.5, 1.5, 1.5));
glm::mat4 vp1 = MyCam.getVP();
glm::vec3 viewPos = MyCam.campos;
roomShader.use();
roomShader.setUniform("vp", vp1);
roomShader.setUniform("model", model);
roomShader.setUniform("lightPos", lightPos);
roomShader.setUniform("viewPos", viewPos);
roomShader.setUniform("farPlane", wid);
roomShader.setUniformSampler("Texture1", 0);
roomShader.setUniformSampler("Texture2", 1);
roomShader.setUniformSampler("depthCubemap", 2);
carpetTex.bind(1);
sceneTex.bind(0);
room.Draw();
carpetTex.unbind(1);
sceneTex.unbind(0);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
