0
votes

EDIT: I took FBOs out of the equation to make sure the problem wasn't coming from there, so now I am just doing the following:

setup texture:

GLuint FB0Texture;
glGenTextures(1, &FB0Texture);
glBindTexture(GL_TEXTURE_2D, FB0Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, size.width, size.height, 
                 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);

and then to render:

[self drawScene];

[(EAGLView *)self.view bindFB0];

glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 320, 480);

[self drawFullScreenQuad]; (it's actually not full screen so I can see both the 3d scene and the resulting texture)

and I get the same results! Black texture if I setup FB0Texture as a "DEPTH_COMPONENT" texture, but normal scene if I setup FB0Texture as a regular GL_RGBA texture...

So I guess I am either setting up the depth texture wrong, or is it possible I am doing something wrong in the rendering which would result in the RGBA texture looking normal but the depth texture being screwed? GL_DEPTH_TEST is enabled and working fine (models look correct) so I think there is nothing wrong with the actual rendering, but at this point I am desperate for clues ...

Please help!

// END OF EDIT

I am trying to implement some basic shadow mapping on iphone, but I am stuck at rendering the depth values to a texture ... This is driving me crazy, I am obviously doing something wrong but cannot figure out what it is ...

So what I am doing :

  • setup default framebuffer, attach color render buffer and depth render buffer
  • setup a new framebuffer (call it FB0), attach a texture to the depth component

Then when I render:

  • draw scene to FB0
  • switch to default framebuffer
  • draw full screen quad using FB0 as a texture

And I get ... nothing! (well I get a full white texture)

If I attach the texture to the color component of FB0 instead of the depth component, everything works fine, as in I draw the scene to FB0, then use FB0 as a texture to draw a full screen quad, and I see exactly what I would see if I was drawing directly to the default framebuffer.

However when I attach the texture to the depth component, all I get is this white screen / texture.

Some code:

setup buffers:

// Create default framebuffer object.
glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);

// Create color render buffer and allocate backing store.
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);

// Create depth render buffer
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 320, 480); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);


// Create Depth Map Frame Buffer

glGenFramebuffers(1, &FB0);
glBindFramebuffer(GL_FRAMEBUFFER, FB0);

// Attach texture to depth component        

glGenTextures(1, &FB0Texture);
glBindTexture(GL_TEXTURE_2D, FB0Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.width, size.height, 
                 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0);

glFramebufferTexture2D(GL_FRAMEBUFFER, 
                       GL_DEPTH_ATTACHMENT, 
                       GL_TEXTURE_2D, 
                       FB0Texture, 
                       0);

If I check the status of the framebuffers after this I get no error messages, so I am assuming the buffers are created correctly.

Then in the rendering:

[(EAGLView *)self.view setFB0]; (just binds the framebuffer)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[self drawScene];

[(EAGLView *)self.view setFramebuffer]; (binds back the default frame buffer)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[(EAGLView *)self.view bindFB0Texture];

[self drawFullScreenQuad];

[(EAGLView *)self.view presentFramebuffer];

At this point I would expect to see a black and white texture with levels of gray indicating the depth, but instead I just get a solid white quad / texture.

Again, if I attach FB0Texture to GL_COLOR_ATTACHMENT0 instead of GL_DEPTH_ATTACHMENT everything works as expected, my scene gets rendered to the texture correctly. So I guess the problem is coming from how I am attaching the texture, or maybe the order in which I am doing stuff ?

1

1 Answers

1
votes

Your problem might lie in the fact that you're ONLY attaching the depth texture to the render to texture FBO, and not attaching a colour buffer too.

If this doesn't work, Apple suggest in their technical documentation that you should use the GL_OES_depth_texture extension but I haven't been able to make this work myself in terms of rendering depth to texture, although using it seems to significantly improve the fidelity of the depth-testing for the colour render-to-texture image I'm getting.

Edit: Whoops, that's what you're doing already. I should read the question more thoroughly, sorry!

I am currently experiencing this problem too, so if it's been solved I'd love to know how!

EDIT #2: I've solved the problem in my own situation. The depth buffer stores depths in non-linear space, so it's necessary to convert the depths back to linear space to visualise them properly (this can be achieved with your projection near and far plane information). The problem I was having was that most of my depth information was being stored in the range 0.995 to 1.0, meaning that to my eyes it appeared as a totally white texture. This may be the problem you're having when you're getting an all white texture.

As a side note, Xcode 4.2's awesome OpenGL ES snapshot feature helped me solve the problem. It lets you visualise all the texture and render buffer objects in your context, and even rescales the colour for you if the data is non-linear. This, as you might be able to guess, is how I figured it out.