1

I want to render my scene into a cubemap FBO but I can't seem to get it working properly. Only 1 side of my cube is showing the rendered cubemap as a test.

enter image description here

This is my FBO setup:

// create cubemap FBO
unsigned int cubemapFBO;
glGenFramebuffers(1, &cubemapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, cubemapFBO);

// create color cubemap texture
unsigned int colorCubemap;
glGenTextures(1, &colorCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, colorCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);

// create depth cubemap
unsigned int 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_COMPONENT24, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
    
// attach depth texture as FBO's depth buffer
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorCubemap, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubemap, 0);

//glDrawBuffer(GL_COLOR_ATTACHMENT0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "ERROR on cubemapFBO:  Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// -- End cubemap FBO -- //

This is my projection and view matrices to capture 6 cubemap faces

// set up projection and view matrices for capturing 6 cubemap faces
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] = {
    captureProjection * glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
    captureProjection * glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
    captureProjection * glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec3(0.0f,  0.0f,  1.0f)),
    captureProjection * glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec3(0.0f,  0.0f, -1.0f)),
    captureProjection * glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
    captureProjection * glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec3(0.0f, -1.0f,  0.0f))
};
// -- End projection and view matrices setup -- //

This is my scene rendering to cubemap FBO

// render scene to cubemap FBO
glViewport(0, 0, size, size);
glBindFramebuffer(GL_FRAMEBUFFER, cubemapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
    simpleDepthShader.Use();
    for (unsigned int i = 0; i < 6; ++i)
    {
        simpleDepthShader.setMat4("shadowMatrices[" + std::to_string(i) + "]", captureViews[i]);
    }
    // skybox test
    cubemap.Use();
    glm::mat4 cubemapModel = glm::translate(glm::mat4(1.0f), positions);
    //glm::mat4 cubemapRotate = glm::rotate(glm::mat4(1.0f), glm::radians(-(float)glfwGetTime() * 0.2f), glm::vec3(0.0f, 1.0f, 0.0));
    //glm::mat4 cubemapRotate = glm::rotate(glm::mat4(1.0f), glm::radians(-(float)glfwGetTime() * 0.2f), glm::vec3(0.0f, 1.0f, 0.0));
    //cubemapModel = cubemapModel * cubemapRotate;
    cubemap.setMat4("projection", projection);
    cubemap.setMat4("view", skyboxView);
    cubemap.setMat4("model", cubemapModel);
    glDepthFunc(GL_LEQUAL);
    glDepthMask(GL_TRUE);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, secondCubemapTexture);
    renderCubemap();
    glDepthFunc(GL_LESS);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// -- End render to cubemap FBO -- //

And this is my vertex + geometry + fragment shader

#shader vertex
#version 450 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;

void main()
{
    gl_Position = model * vec4(aPos, 1.0);
}

#shader fragment
#version 450 core
out vec4 FragColor;
in vec4 FragPos;

void main()
{
    FragColor = FragPos;
}

#shader geometry
#version 450 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;

uniform mat4 shadowMatrices[6];

out vec4 FragPos; // FragPos from GS (output per emitvertex)

void main()
{
    for(int face = 0; face < 6; ++face)
    {
        gl_Layer = face; // built-in variable that specifies to which face we render.
        for(int i = 0; i < 3; ++i) // for each triangle's vertices
        {
            FragPos = gl_in[i].gl_Position;
            gl_Position = shadowMatrices[face] * FragPos;
            EmitVertex();
        }    
        EndPrimitive();
    }
} 

And then testing out the cubemap onto a cube with the fbo cubemap texture

// test cube with FBO cubemap
cube.Use();
cube.setMat4("projection", projection);
cube.setMat4("view", view);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, silverTeapotTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP, colorCubemap); // <-- here
glm::mat4 cubeModel = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -0.5f, 0.0f));
cube.setMat4("model", cubeModel);
renderTexturedCube();

0 Answers0