Zbuffer Bringing Order into Chaos

What is a z-buffer? In Chapter 4 we discussed the framebuffer. It stores the color for each pixel on the screen. When OpenGL ES renders a triangle to the framebuffer, it just changes the color of the pixels that make up that triangle.

The z-buffer is very similar to the framebuffer in that it also has a storage location for each pixel on the screen. Instead of storing colors, it stores depth values, though. The depth value of a pixel is roughly the normalized distance of the corresponding point in 3D to the near clipping plane of the view frustum.

OpenGL ES will write a depth value for each pixel of a triangle to the z-buffer by default (if a z-buffer was created alongside the framebuffer). All we have to tell OpenGL ES is to use this information to decide whether a pixel being drawn is closer to the near clipping plane than the one that's currently there. For this we just need to call glEnable() with an appropriate parameter:

GL10.glEnable(GL10.GL_DEPTH_TEST);

That's all we need to do. OpenGL ES will then compare the incoming pixel depth with the pixel depth that's already in the z-buffer. If it is smaller, it is also closer to the near clipping plane and thus in front of the pixel that's already in the frame- and z-buffer.

Figure 10-5 illustrates the process. The z-buffer starts of with all values set to infinity (or a very high number). When we render our first triangle, we compare each of its pixels' depth value to the value of the pixel in the z-buffer. If the depth value of a pixel is smaller than the value in the z-buffer, it passes the so-called depth test, or z-test. The pixel's color will be written to the framebuffer and its depth will overwrite the corresponding value in the z-buffer. If it fails the test, neither the pixel's color nor the depth value will be written to the buffers. This is shown in Figure 10-5, where the second triangle is rendered. Some of the pixels have smaller depth values and thus get rendered; other pixels don't pass the test.

Figure 10-5. Image in the framebuffer (left); z-buffer contents after rendering each of the two triangles (right)

As with the framebuffer, we also have to clear the z-buffer each frame, otherwise the depth values from the last frame would still be in there. To do this we can call glClear(), like this:

gl.glClear(GL10.GL_C0L0R_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

This will clear the framebuffer (or colorbuffer), as well as the z-buffer (or depthbuffer), all in one go.

0 0

Post a comment