You should perform the depth test in the fragment shader "manually". OpenGL doesn't support multiple depth tests, and that its just what you need to render the second nearest pixels, because:
- You need the second front pixels (GL_LESS over the actual depth buffer)
- You need the second front pixels (GL_GREATER over the depth buffer of the first framebuffer).
This can't be done without the help of a shader, as you can only choose one of those two depth tests to be performed at once.
- You will need to read from the depth buffer of the first framebuffer. This can be done "making" the first framebuffer use a texture as a depth buffer and reading values from it later using texture(). You can assign a texture as depth buffer to a framebuffer using:
//I'm using Java and LWJGL in the example, C++ implementation should be pretty similar.
//Set active texture, bind it, etc.
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT24, X_RES, Y_RES, 0,GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (FloatBuffer)null);
//Hey you active framebuffer, use this texture as your depth buffer from now on
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
- Set the depth test to GL_LEQUAL or GL_LESS (the default depth test)
- Draw the scene again into the second framebuffer, but performing a second depth test over the first framebuffer depth texture in the fragment shader, like so:
uniform sampler2D depthTexture;
//current projected position, being z the depth.
//Assuming x and y coordinates normalized, in [0..1] range.
//To transform from standard [-1..1] coordinates to [0..1]
//coordinates, you can do (pos.x+1)/2, for example.
in vec3 pos;
if(pos.z<=texture(depthTexture,vec2(pos.x,pos.y))) discard; //Manually performing the GL_GREATER depth test for each pixel
//Rest of your shader code, if needed