Android OpenGL ES Framebuffer objects - rendering depth-buffer to texture
I am using an Android device running Froyo supporting OpenGL ES 1.1 and OpenGL ES 2.0
I want to render the depth buffer to a texture. Having seen a number of examples for OpenGL, OpenGL ES on other platforms (including iPhone) I have tried a number of FBO configurations.
I seem to be able to get an FBO set-up with a colour texture but every time I attach a depth texture it fails.
My current code is based on this example but creating a colour texture as well instead of setting draw and read buffers to none.
开发者_StackOverflowIs there a simple example of configuring an OpenGL ES FBO on Android to render depth to a texture? Alternatively is there a document describing what is and is not supported?
Thanks for the comments - I specifically needed a solution for ES 1.1, if it could be found and work on Android. I also want to look at ES 2 - I am not sure I understand the idea of packing the depth information into colour buffer - do you have a reference I can look at to understand the idea better?
Regarding code - my source is barely different from the link I posted above. The Framebuffer status is that it is not complete.
Thanks for the fragment shader suggestion - I get the idea now. Will look at that if I can't get another solution working. My ideal is to get depth and colour at the same time - don't really want to render colour and depth separately if I can help it.
OK, an answer of sorts. Got this to work on Android 2.2 with OpenGL ES 2:
// Create a frame buffer
glGenFramebuffers( 1, &(frame_buffer ) );
// Generate a texture to hold the colour buffer
glGenTextures(1, &(colour_texture) );
glBindTexture(GL_TEXTURE_2D, colour_texture);
// Width and height do not have to be a power of two
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
pixelWidth, pixelHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Probably just paranoia
glBindTexture(GL_TEXTURE_2D, 0);
// Create a texture to hold the depth buffer
glGenTextures(1, &(depth_texture) );
glBindTexture(GL_TEXTURE_2D, depth_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
pixelWidth, pixelHeight,
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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);
glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer);
// Associate the textures with the FBO.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, colour_texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, depth_texture, 0);
// Check FBO status.
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if ( status == GL_FRAMEBUFFER_COMPLETE )
{
// Success
}
Pretty trivial really, follow the OpenGL ES2 manual and do everything in the right order.
Tried this with OpenGL ES 1.1, adding OES to the required function calls and _OES to the constants since frame buffer objects is an extension. Any attempt to attach a depth texture to the frame buffer results in an incomplete frame buffer object.
So at the moment my conclusion is that this doesn't work with OpenGL ES 1.1 on Android, but it clearly does work with ES 2.2.
If anyone has a solution for ES 1.1 it would be interesting to see it.
Rendering to a depth texture isn't supported on many devices. You'll need to attach a renderbuffer for your depth buffer.
精彩评论