-1

This post has been updated

I am using the following two stackoverflow references a, b, to help me build a cubemap with depth values of a scene. However I have been having multiple problems and I have no idea how to resolve these.

Here are bits of my code:

def create_empty_cubemap(self) -> None:
    '''creates an empty cubemap ready to store depth values'''
    
    self.cube_tex = glGenTextures(1)
    glBindTexture(GL_TEXTURE_CUBE_MAP, self.cube_tex)
    
    for i in range(6):
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_DEPTH_COMPONENT32F, 1024, 1024,
                        0, GL_DEPTH_COMPONENT, GL_FLOAT, None)

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # or GL_LINEAR?
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_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)

    glBindTexture(GL_TEXTURE_CUBE_MAP, 0)

The function I use to create the depth cubemap is the following,

def create_depthcube(self) -> None:
    '''Generates a cubemap with depth values'''

    #                   pitch, yaw, name
    rotation_dict = {0: [  0,  90,   'X+'],
                     1: [  0, -90,   'X-'],
                     2: [-90, 180,   'Y+'],
                     3: [ 90, 180,   'Y-'],
                     4: [  0, 180,   'Z+'],
                     5: [  0,   0,   'Z-']}
    
    self.cube_framebuffer = glGenFramebuffers(1)
    glBindFramebuffer(GL_FRAMEBUFFER, self.cube_framebuffer)
    # glClear(GL_DEPTH_BUFFER_BIT) # PROBLEM 1
    
    # use shader
    self.cubemap_shader.use()

    # generate a cubemap camera
    cubemap_camera = Camera(self.camera.position)
    cubemap_camera.width = 1024
    cubemap_camera.height = 1024
    cubemap_camera.zoom = 90.0

    # set viewport size to cubemap size
    glViewport(0, 0, 1024, 1024)

    # create a projection matrix
    projection = glm.perspective(glm.radians(90.0), 1.0, 0.1, 100)
    self.cubemap_shader.set_uniform_mat4('projection', projection)        

    # create depthcube by capturing depth 
    for i in range(6):

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
                               GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, self.cube_tex, 0) #PROBLEM2
        
        # all fine?
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE):
            raise RuntimeError("ERROR.FRAMEBUFFER. Framebuffer is not complete!")

        # clear colors and buffers
        glClearColor(0.1,0.1,0.1,0.1)
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT)

        # rotate camera
        cubemap_camera.pitch = rotation_dict[i][0]
        cubemap_camera.yaw =  rotation_dict[i][1]
        cubemap_camera.update_camera_vectors()
        
        # update view (look at matrix)?
        view = cubemap_camera.get_matrix_view()
        self.cubemap_shader.set_uniform_mat4('view',view)
        self.cubemap_shader.set_uniform_mat4('projection', projection)

        # render scene
        self.render()

    # unbind fbo
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

    # reset viewport dimensions to display dimensions
    glViewport(self.camera.width, self.camera.height) 

My vertex shader is as follows:

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

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

And my fragment shader is minimal

#version 330 core
// depth cubemap

out float fragmentDepth;

void main()
{    
    //fragmentDepth = gl_FragCoord.z;
}

Now when I execute the program I get an error at PROBLEM1 location with the glClear function. If I comment this line I get an error at PROBLEM2 location with the 'glFramebufferTexture2D' function. Neither of them I can explain (particularly PROBLEM1). Is this the right way to generate a cubemap to store the depth of a scene? What am I doing wrong?

marcos
  • 134
  • 15

1 Answers1

-1

At the end there were several errors in my code. First, ,my create_empy_cubemap()function was incorrect. The following function works,

def create_empty_cubemap(self) -> None:
    '''creates an empty cubemap ready to store depth values'''
    
    self.depth_map_fbo = glGenFramebuffers(1)
    glBindFramebuffer(GL_FRAMEBUFFER, self.depth_map_fbo)
    
    self.depth_tex = glGenTextures(1)
    glBindTexture(GL_TEXTURE_CUBE_MAP, self.depth_tex)
    
    for i in range(6):
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_DEPTH_COMPONENT32, CM*1024, CM*1024,
                        0, GL_DEPTH_COMPONENT, GL_FLOAT, None)

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # or GL_LINEAR?
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_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)

    # attach depth texture to  fbo depth buffer
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, self.depth_tex,0)
    glDrawBuffer(GL_NONE)
    glReadBuffer(GL_NONE)
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

Second, my create_depthcube()function ended up being very similar with some slight modifications,

def create_depthcube(self) -> None:
    '''Generates a cubemap with depth values'''

    #                   pitch, yaw, rel_pitch, rel_yaw, name, location
    rotation_dict = {0: [   0,  90,         0,      90, 'X+', 'Right'],
                        1: [   0, -90,         0,    -180, 'X-', 'Left'],
                        2: [  90, 180,       -90,      90, 'Y+', 'Top'],
                        3: [ -90, 180,       180,       0, 'Y-', 'Bottom'],
                        4: [   0,   0,       -90,     180, 'Z+', 'Back'],
                        5: [   0, 180,         0,    -180, 'Z-', 'Front']}
    
    # create empty cubemap
    self.create_empty_cubemap()
    
    # generate a cubemap camera
    cubemap_camera = Camera(self.camera.position)
    cubemap_camera.width = 1024
    cubemap_camera.height = 1024
    cubemap_camera.zoom = 90.0

    # # bind depth map buffer
    glBindFramebuffer(GL_FRAMEBUFFER, self.depth_map_fbo)
    
    # set viewport size to cubemap size
    glViewport(0, 0, 1024, 1024)

    # create a projection matrix
    projection = glm.perspective(glm.radians(90.0), 1.0, 0.1, 100)
    self.cubemap_shader.set_uniform_mat4('projection', projection)        

    # RENDER TO DEPTH CUBEMAP
    for i in range(6):

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,
                                self.depth_tex, 0)
        
        # all fine?
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE):
            raise RuntimeError("ERROR.FRAMEBUFFER. Framebuffer is not complete!")

        # clear colors and buffers
        glClearColor(0.1,0.1,0.1,0.1)
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT)

        # rotate camera
        cubemap_camera.pitch = rotation_dict[i][0] #0
        cubemap_camera.yaw =  rotation_dict[i][1] #1
        cubemap_camera.update_camera_vectors()
        
        # update view (lookat matrix)?
        view = cubemap_camera.get_matrix_view()
        self.cubemap_shader.set_uniform_mat4('view',view)

        # render scene
        self.render(self.cubemap_shader, cubemap_camera, projection)

        # #output ?
        zbuffer = glReadPixelsf(0, 0, 1024, 1024, GL_DEPTH_COMPONENT, GL_FLOAT)
        zbuffer = zbuffer.reshape((1024, 1024))
        np.save(f'{rotation_dict[i][5]}_cube', np.flipud(zbuffer))

    # unbind fbo
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

    # reset viewport dimensions to display dimensions
    glViewport(0,0, self.camera.width, self.camera.height) 

More importantly, however, was the fact that when I wanted to render to generate the cubemap I had to alter my original render() function to be able to accept a different shader, camera and projection matrix as parameters.

marcos
  • 134
  • 15