I am not certain what I am doing incorrectly.
Let me first explain what I am trying to accomplish. I just trying to view a scene as normal and whenever I click on a key capture the distance from the camera to each pixel in the scene. In addition, I want the distance to each pixel to be stored in a texture attached to my framebuffer (but not as a color_attachment0 but rather as a second color_attachment1).
I get an error whenever I run the instruction glReadPixelsf(0,0, SCR_WIDTH, SCR_HEIGHT, GL_RED, GL_FLOAT) (SCR_WIDTH = 800 and SCR_HEIGHT= 600)
Am I specifying correctly the output of my fragment shader?
Here are the main parts involved.
Vertex shader of ShaderDepth
#version 440 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec4 pos;
void main()
{
pos = view * model * vec4(aPos, 1.0f);
gl_Position = projection * view * model * vec4(aPos, 1.0f);
}
fragment shader of ShaderDepth
#version 440 core
layout(location = 1) out float depth; // second texture COLOR_ATTACHMENT1
in vec4 pos;
//out float depth;
void main()
{
depth = length(pos.xyz);
}
Usually, I would have just have just specified depth as simple float as shown commented on the fragment shader. My understanding is that because I am using COLOR_ATTACHMENT1 rather than 0 I need to use layout() instead??? Is this correct?
My main render loop:
while (not glfwWindowShouldClose(window)):
# captures keys
processInput(window)
# render
glClearColor(0.1, 0.1, 0.1, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_DEPTH_TEST)
# define basic viewing parameters
view = camera.GetViewMatrix()
projection = glm.perspective(glm.radians(camera.Zoom), SCR_WIDTH / SCR_HEIGHT, 0.1, 100.0)
# default shader
shader = shaderDisplay
if camera.capture:
# bind the framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, fbo)
glClearColor(0.1, 0.1, 0.1, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
# set shader to shader depth
shader = shaderDepth
# set uniforms on shader
shader.use()
shader.setMat4("view", view)
shader.setMat4("projection", projection)
# draw floor
glBindVertexArray(planeVAO)
glBindTexture(GL_TEXTURE_2D, floorTexture)
shader.setMat4("model", glm.mat4(1.0))
glDrawArrays(GL_TRIANGLES, 0, 6)
glBindVertexArray(0)
# cube 1
glBindVertexArray(cubeVAO)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, cubeTexture)
model = glm.mat4(1.0)
model = glm.translate(model, glm.vec3(0.0, 0.0, -0.75))
shader.setMat4("model", model)
glDrawArrays(GL_TRIANGLES, 0, 36)
# cube 2
scale = 0.35
model = glm.mat4(1.0)
model = glm.scale(model, glm.vec3(scale, scale, scale))
model = glm.translate(model, glm.vec3(0.0, 0, 2.0))
shader.setMat4("model", model)
glDrawArrays(GL_TRIANGLES, 0, 36)
glBindVertexArray(0)
glfwSwapBuffers(window)
glfwPollEvents()
# end of capture
if camera.capture:
# save outputs ERROR HERE
depth = glReadPixelsf(0,0, SCR_WIDTH, SCR_HEIGHT, GL_RED, GL_FLOAT)
np.save('depth', np.flipud(depth))
# switch shader back to display shader
shader = shaderDisplay
# reset capture flag
camera.capture = False
# unbind framebuffer back to default
glBindFramebuffer(GL_FRAMEBUFFER,0)
Finally my framebuffer is as such,
# create depth buffer
fbo= glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, fbo)
# COLOR DEPTH
color_depth_tex = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, color_depth_tex)
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F,
SCR_WIDTH, SCR_HEIGHT, 0, GL_RED, GL_FLOAT, None)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glBindTexture(GL_TEXTURE_2D, 0)
# Attach depth to framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, color_depth_tex, 0)
draw_buffers = [GL_COLOR_ATTACHMENT1]
glDrawBuffers(1, draw_buffers)
# DEPTH
depth_tex = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, depth_tex)
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F,
SCR_WIDTH, SCR_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, None)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glBindTexture(GL_TEXTURE_2D, 0)
# Attach depth to framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0)
# check for errors (after attaching a texture)
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE):
print(glCheckFramebufferStatus(GL_FRAMEBUFFER))
raise RuntimeError("ERROR.FRAMEBUFFER. Framebuffer is not complete!")
# unbind framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0)
Incidentally, if I comment out the fragment shader layout(location = 1) out float depth; and uncomment out float depth and attach my #COLOR_DEPTH as a GL_COLOR_ATTACHMENT0 I do not get the error when I execute glReadPixelsf though I get some strange result.
What I see is the following,
but what I get is
I am not able to explain a) why my image is not 800 x 600 (which is what was specified) b) and why I get my cube repeated c) why the depth is not calculated continuously???
Apologies for the looooong message

