Reading Depth Buffer With PyOpenGL
Basically, I'm trying to extract a depth map (by this I mean a matrix with z corresponding to z-coordinates for vertices in GL.glVertex3dv(vertex) call - obviously, interpolated fo
Solution 1:
Running your code gave me some "Invalid Operation Error: 1282"
messages for the glReadPixels
call. Instead, here is a simple demo I just wrote that shows how to obtain the color and the depth buffer from OpenGL for a rendered triangle. What I do here is bind an FBO (framebuffer object) to the screen with the desired texture attachments (for receiving the color and depth data). I then read out the data from the GPU using glGetTexImage
. Using textures might not be the fastest approach, but this is pretty simple and should work nicely. Let me know if anything in this is unclear and I will elaborate on it.
from OpenGL.GL import *
from OpenGL.GLUT import *
import numpy as np
import sys
def draw_scene():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glBegin(GL_TRIANGLES)
glColor3f(1, 0, 0)
glVertex3f(-1, -1, 0)
glColor3f(0, 1, 0)
glVertex3f(0, 1, 0)
glColor3f(0, 0, 1)
glVertex3f(1, -1, 0)
glEnd()
def draw_texture():
global color_texture
glColor3f(1, 1, 1)
glBindTexture(GL_TEXTURE_2D, color_texture)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glBegin(GL_QUADS)
glTexCoord2f(0, 0)
glVertex3f(-1, -1, 0)
glTexCoord2f(0, 1)
glVertex3f(-1, 1, 0)
glTexCoord2f(1, 1)
glVertex3f(1, 1, 0)
glTexCoord2f(1, 0)
glVertex3f(1, -1, 0)
glEnd()
glBindTexture(GL_TEXTURE_2D, 0)
def update_display():
global fbo, color_texture, depth_texture
#Render the scene to an offscreen FBO
glBindFramebuffer(GL_FRAMEBUFFER, fbo)
draw_scene()
glBindFramebuffer(GL_FRAMEBUFFER, 0)
#Then render the results of the color texture attached to the FBO to the screen
draw_texture()
#Obtain the color data in a numpy array
glBindTexture(GL_TEXTURE_2D, color_texture)
color_str = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE)
glBindTexture(GL_TEXTURE_2D, 0)
color_data = np.fromstring(color_str, dtype=np.uint8)
#Obtain the depth data in a numpy array
glBindTexture(GL_TEXTURE_2D, depth_texture)
depth_str = glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT)
glBindTexture(GL_TEXTURE_2D, 0)
depth_data = np.fromstring(depth_str, dtype=np.float32)
print(np.min(depth_data), np.max(depth_data))#This is just to show the normalized range of depth values obtained
glutSwapBuffers()
width, height = 800, 600
fbo = None
color_texture = None
depth_texture = None
if __name__ == '__main__':
glutInit([])
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE)
glutInitWindowSize(width, height)
glutInitWindowPosition(0, 0)
glutCreateWindow("Triangle Test")
glEnable(GL_TEXTURE_2D)#not needed if using shaders...
glEnable(GL_DEPTH_TEST)
color_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, color_texture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
glBindTexture(GL_TEXTURE_2D, 0)
depth_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, depth_texture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, None)
glBindTexture(GL_TEXTURE_2D, 0)
fbo = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, fbo)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glutDisplayFunc(update_display)
glutIdleFunc(glutPostRedisplay)
glutMainLoop()
Post a Comment for "Reading Depth Buffer With PyOpenGL"