OpenGL ES 2.0 & the Depth Buffer/Texture
-
I'm currently in the process of implementing shadow mapping for my OpenGL app and ran across this depth buffer issue - according to the OpenGL ES 2.0 specs (both PowerVR and http://developer.meego.com/api/1.2/opengles-2.0/glTexImage2D.html), a texture format GL_DEPTH_COMPONENT is not supported. However I tried and it does compile for Harmattan. Didn't yet run it to see whether there is an error. Any experiences on this? I really dislike the idea of having to pack the depth values into a RGBA texture.
- Matti
-
Does PowerVR support this extension? http://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt
-
It would appear that the SGX 530, at least, does not.
http://www.rojtberg.net/348/powervr-sgx-530-does-not-support-depth-textures/
Which would be sad since the performance I'm getting out of a RGBA packed depth texture is not very good. I'll check with glGetString() later. The most modern phones seem to support the extension (ref google) so I guess it's worth implementing even if mine doesnt .)
-
Well, welcome to OpenGL world. :)
I hope you will survive extension hell. :)
-
Well, the device seems to have extensions GL_OES_depth_texture, GL_OES_depth24, GL_OES_texture_float etc. which would hint that this should work. However if I try to pass GL_DEPTH_COMPONENT as the format, glTexImage2D() fails - well, this is what the OpenGL ES 2.0 spec does say, after all, GL_DEPTH_COMPONENT is not among the supported choices.
I tried creating a RGBA texture and was able to attach it to a FBO as GL_DEPTH_ATTACHMENT using glFramebufferTexture2D() and everything goes fine on paper. Rendering / reading that texture doesnt really work like with a depth texture (which I have working on the desktop build very nicely).
Such a shame.
-
See kids, this is what happens when you don't read the documentation :) Changing the <type> parameter to GL_UNSIGNED_INT did the trick. I'll share the code so maybe the next guy is spared the hassle:
Creating the FBO:
@bool GLController::CreateDepthTextureAndFBO(GLuint* fboId,
GLuint* depthTextureId,
GLuint* renderBuffer,
int width, int height)
{
// Create a framebuffer object
glGenFramebuffers(1, fboId);
glBindFramebuffer(GL_FRAMEBUFFER, *fboId);// Create a render buffer glGenRenderbuffers(1, renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, *renderBuffer); // Create a texture for storing the depth glGenTextures(1, depthTextureId); glBindTexture(GL_TEXTURE_2D, *depthTextureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Remove artifact on the edges of the shadowmap glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); Debug("glGetError() 0 = 0x%x", glGetError()); if ( m_hasDepthTextureExtension ) { // We'll use a depth texture to store the depths in the shadow map glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); // Attach the depth texture to FBO depth attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depthTextureId, 0); } else { // We'll use a RGBA texture into which we pack the depth info glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Attach the RGBA texture to FBO color attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *depthTextureId, 0); // Allocate 16-bit depth buffer glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); // Attach the render buffer as depth buffer - will be ignored glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *renderBuffer); } // check FBO status GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); if ( fboStatus != GL_FRAMEBUFFER_COMPLETE ) { Debug("FBO not complete: 0x%x", fboStatus); return false; } // Go back to using the default frame buffer glBindFramebuffer(GL_FRAMEBUFFER, DefaultFramebufferId); return true;
}
@Shaders for rendering the depth:
@const char* DepthShadowMapVertexShader =
GLSL_VERSION_STRING
"precision highp float;\n"
"\n"
"attribute vec3 in_coord;\n"
"uniform mat4 mvp_matrix;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = mvp_matrix * vec4(in_coord, 1.0);\n"
"}\n";const char* DepthShadowMapFragmentShader =
GLSL_VERSION_STRING
"precision highp float;\n"
"\n"
"void main()\n"
"{\n"
"}\n";@Shaders using the shadow map: see http://fabiensanglard.net/shadowmapping/index.php#c5t_form
Cheers to Fabian Sanglard +others for help and ideas on this issue.
- Matti
-
Happy to see it works! :)