Depth testing : Context is everything

I just lost a few hours trying to play with the Z index between draw calls, in order to try Z-layering, as advised by peterharris on ARM Community, in my question For binary transparency : Clip, discard or blend ?.

However, for reasons I did not understand, the Z layer seemed to be completely ignored. Only the glDraw calls order was taken into account.

The solution

Request an EGL_DEPTH_SIZE when selecting a display configuration for your EGL context.

Thought pattern

I really tried everything :

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glClearDepthf(1.0f);
glDepthRangef(0.1f, 1.0f);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

Still… each glDrawArrays drew pixels over previously drawn pixels that had an inferior Z value. Switched the value provided to glDepthFunc, switched the Z values, … same result.

I really started to think that Z-layering only worked for one draw batch…

Until, I searched the OpenGL wiki for “Depth Buffer” informations and stumbled upon Common Mistakes : Depth Testing Doesn’t Work :

Assuming all of that has been set up correctly, your framebuffer may not have a depth buffer at all. This is easy to see for a Framebuffer Object you created. For the Default Framebuffer, this depends entirely on how you created your OpenGL Context.

Not again

After a quick search for EGL Depth buffer on the web, I found the EGL manual page : eglChooseConfig - EGL Reference Pages, which stated this :

EGL_DEPTH_SIZE

Must be followed by a nonnegative integer that indicates the desired depth buffer size, in bits. The smallest depth buffers of at least the specified size is preferred. If the desired size is zero, frame buffer configurations with no depth buffer are preferred. The default value is zero.

The depth buffer is used only by OpenGL and OpenGL ES client APIs.

I should have known…