I have amended the post to reflect some suggested changes and added additional information
I have been struggling to be able to generate a cubemap where I can store depth information from a scene- 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)
# 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) #PROBLEM1
# 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;
}
I get an error at PROBLEM1 location with the glFramebufferTexture2D
function. Is this the right way to generate a cubemap to store the depth of a scene? What am I doing wrong?
I am including the render()
function below. All of the code is an adaptation of Vries code. This displays two cubes and a floor which are rendered into another framebuffer with a color attachment. This is then copy to the default display buffer. I wanted to be able to press a key and capture the depth information of a scene in a cubemap.
def render(self) -> None:
'''Render objects'''
# use normal display shader
self.shader.use()
# render cubes
model = glm.mat4(1.0)
glBindVertexArray(self.cube_vao)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.cube_texture)
# cube 1
model = glm.translate(model, glm.vec3(-1.0, 0.0, -1.0))
self.shader.set_uniform_mat4('model', model)
glDrawArrays(GL_TRIANGLES, 0, 36)
# cube 2
model = glm.mat4(1.0)
model = glm.translate(model, glm.vec3(2.0, 0.0, 0.0))
self.shader.set_uniform_mat4('model', model)
glDrawArrays(GL_TRIANGLES, 0, 36)
glBindVertexArray(0) # remove binding
# render floor
glBindVertexArray(self.floor_vao)
glBindTexture(GL_TEXTURE_2D, self.floor_texture)
self.shader.set_uniform_mat4('model', glm.mat4(1.0))
glDrawArrays(GL_TRIANGLES, 0, 6)
glBindVertexArray(0) # remove binding
# Render to default (display) buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glDisable(GL_DEPTH_TEST)
glClearColor(1.0, 1.0, 1.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
self.screen_shader.use()
glBindVertexArray(self.quad_vao)
glBindTexture(GL_TEXTURE_2D, self.texture_color_buffer)
glDrawArrays(GL_TRIANGLES, 0, 6)