Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have 2 different shaders, and when I change the shader (glUseProgram), it seems that the depth information is lost, because everything drawn with the 2nd shader appears completely on top of anything drawn by the first shader.

If I switch the order of shader use/drawing, then it's the same (the last drawn object always appears on top of the first drawn object if there is a shader change between the 2 objects, even if the last drawn object is further away)

share|improve this question

I'll confirm that the depth buffer is not cleared by OpenGL ES2 when changing shaders.

If it appears to be doing so in your code, that indicates a bug on your side. Check for calls to glClear(GL_DEPTH_BUFFER_BIT) which might be getting triggered indirectly from your shader-changing code (I recommend putting a breakpoint on every call to glClear in a debugger, to see exactly when they're being called)

You should probably also check that you're not calling glDisable(GL_DEPTH_TEST) or modifying glDepthFunc() in a way that would result in the depth buffer appearing to have been cleared, when actually the depth test has been completely disabled (these two different issues can often look identical, in many types of scenes).

share|improve this answer
Thanks for this answer. It turned out I didn't have a depth buffer attached. – bobobobo Oct 1 '12 at 2:48
up vote 1 down vote accepted

Ok, I had the depth test enabled but I didn't have a depth buffer. That was surprising!

To add a depth buffer in ES2:

The entire init and resizeFromLayer functions become:

// Create an ES 2.0 context
- (id <ESRenderer>) init
  if (self = [super init])
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    // Create the vertex formats + shaders
    if (!context || ![EAGLContext setCurrentContext:context] || ![self loadShaders])
      return nil;

    // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
    glGenFramebuffers(1, &defaultFramebuffer);
    glGenRenderbuffers(1, &colorRenderbuffer);

    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);

    glGenRenderbuffers(1, &depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
  return self;

- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
  // Allocate color buffer backing based on the current layer size
  glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];

  int backingWidth,backingHeight;

  glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
  glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
  glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
  glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); // linked post says need this

  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    return NO;

  return YES;
share|improve this answer
You should probably mark this answer as accepted, there's nothing wrong in accepting an answer to your own question. – Laurent Couvidou Oct 1 '12 at 8:52

Your Answer


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.