Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to get the depth buffer for my 2D game working by offsetting the z value of the rectangles. For some reason, my depth buffer is coming back empty. The value is always 0. I'm assuiming there is something wrong with how I attach the depth buffer to the FBO? But I've looked over that code many times and don't see anything wrong with it. Let me know if you need more information.

  • I have depth testing enabled with GL_LEQUAL.
  • I have znear and zfar set to 1.f, -10.f and I have 9 quads setup at three different depths.
  • I have set glClearDepth(1.0) and I clear bot the COLOR_BUFFER_BIT and DEPTH_BUFFER_BIT before I draw to the FBO, however the value is still 0.

FBO setup:

RenderTarget::RenderTarget(int width, int height) {

    mWidth = width;
    mHeight = height;
    mVbo = 0;

    // Create the color buffer
    glGenTextures(1, &mTextureId);
    glBindTexture(GL_TEXTURE_2D, mTextureId);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);


    // Create the depth buffer
    glGenTextures(1, &mDepth);
    glBindTexture(GL_TEXTURE_2D, mDepth);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, mWidth, mHeight, 0, GL_RED, GL_BYTE, NULL);

    /*glGenRenderbuffers(1, &mDepth);
    glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, mWidth, mHeight);*/

    // Create the frame buffer
    glGenFramebuffers(1, &mFbo);
    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextureId, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepth, 0);



    GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    assert(err == GL_FRAMEBUFFER_COMPLETE);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    createVbo();
}

Fragment shader

#version 120

uniform sampler2D diffuseMap;
uniform sampler2D lightmap;
uniform sampler2D depthMap;

varying vec4 texCoord[2];

void main()
{
    vec4 color = texture2D(diffuseMap, gl_TexCoord[0].st);
    vec4 light = texture2D(lightmap, gl_TexCoord[0].st);
    vec4 depth = texture2D(depthMap, gl_TexCoord[0].st);

    vec4 final = color * vec4(0.1);
    final += color * light;
    gl_FragColor= vec4(depth.r, depth.r, depth.r, 1.0);
}

Method to draw sprites to the screen/framebuffer

void GraphicsDevice::drawSprite(ISprite *sprite, float x, float y, float z, Material::TextureType type, Color c) {

    glActiveTexture(GL_TEXTURE0);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);


    glBindBuffer(GL_ARRAY_BUFFER, sprite->getVbo());

    glBindTexture(GL_TEXTURE_2D, sprite->getMaterial()->getTexture(type)->getId());

    glPushMatrix();
    glTranslatef(x, y, z);
    glColor4f(c.r, c.g, c.b, c.a);

    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, x));
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glPopMatrix();

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

}
share|improve this question
    
Maybe your videocard doesn't suppot GL_DEPTH_COMPONENT32? Try only GL_DEPTH_COMPONENT to allow the card to choose. –  kaoD Feb 16 '12 at 15:42
    
Thanks, but still nothing :\ –  rcapote Feb 16 '12 at 15:51
add comment

2 Answers

Did you miss glEnable(GL_DEPTH_TEST)? I don't see it anywhere in your code (although I'm aware you didn't post it all, it might be somewhere else.)

Also, both zNear and zFar MUST BE positive in perspective projection (not sure about orthogonal.) Actually, it doesn't make sense (at least syntactically) to have the planes reversed. Bear in mind that even if OpenGL looks towards the negative Z axis, z-planes are positioned relative to the viewpoint (positive being forwards from it.)

I'd be glad if someone posted a use case where negative planes are useful, and even more glad if it made sense to have the planes reversed (zFar being behind the viewer as you do.)

share|improve this answer
    
I do have depth test enabled. The reason why I used negative planes is simply so my Z values don't have to be negative when I translate the rectangles. I changed the near/far range to be positive, but that didn't fix anything. I added a new point to my OP: I have glClearDepth(1.0) and I clear the depth buffer before drawing to the FBO, but the values are all still 0. –  rcapote Feb 16 '12 at 15:32
1  
To avoid negative Z values you just have to set the Z scale to -1.0 (effectively reversing the Z viewing direction and making you "look" backwards.) Added some comments to your question which may help too. –  kaoD Feb 16 '12 at 15:40
    
@rcapote: Are you using a perspective projection or an orthographic one? –  Nicol Bolas Feb 16 '12 at 20:09
    
@NicolBolas Ortho –  rcapote Feb 16 '12 at 22:49
add comment
up vote 3 down vote accepted

The problem was I was creating and binding the depth buffer texture to GL_DEPTH_ATTACHMENT. I found some random code that attached the depth buffer to GL_DEPTH_STENCIL_ATTACHMENT, so I tried that out and it works exactly as I expect it to. So the new FBO code looks like this

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, mWidth, mHeight, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, mDepth, 0);

I would really appreciate it if someone could explain why this works and my previous one doesn't.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.