In the previous segment, we saw how the order of drawing mattered. That's because there is no consideration of which objects in the 3D world are before other objects. This gets to the heart of a fundamental problem in computer graphics about visibility testing or removing hidden objects or hidden points. This has been a really big problem in graphics throughout the 60's, the 70's.A number of different solutions were proposed. And the final solution implemented in OpenGL is surprisingly simple. We'll talk about depth testing or Z-buffering. First though, we'll discuss a concept known as double buffering. If you draw a new primitive over an old one, and you just have old objects in the screen, and then you replace them with new objects, this can lead to a jerky sensation, except, especially if the rate of drawing is slow. Which leads to a solution that we refer to as double buffering. The idea is, you render the whole scene or the whole geometry into a back buffer, which is off screen. And when you're finished, you just swap the buffers. Therefore, the entire screen is refreshed simultaneously. You're not waiting while you see one object drawn then the other object drawn and you don't lead to flicker because of that. This leads to a very simple change in the main in the display routine. When you init the display mode, instead of asking for GLUT_SINGLE, you ask for GLUT_DOUBLE. And at the end of display, you swap the buffers before you end the display routine and flush. Once we've set up double buffering, the next thing we do is turn on the depth test or the Z-buffer. And this is a very simple idea, which is that you just maintain an additional frame buffer for the depth, or the Z-buffer. Here I have my screen. And normally, here is a couple of pixels. So I have a triangle here that maps onto the screen. It will of course have a certain color, but it will also have a certain depth. So, you store the depth at that point. Now I have another triangle right here which also maps into the region, you just need to check if the depth of the new triangle is less than the depth of the old triangle. If so, you replace the old depth and the old color. If not, you retain the old depth and the old color. And in this very simple way you can do depth testing. There were many more complicated algorithms proposed, and initially the Z-buffer was thought to be too expensive because of the additional memory. But memory is cheap nowadays, and this simple method is the method of choice in OpenGL. Of course, the depth buffer test is normally less than, but in fact, any test can be used. And you can, in fact, code this up even in the shader. There are a couple of changes in the main function. So instead of just asking for the RGB, you need to ask also for the depth buffer. And when you clear, you just clear the depth buffer bit in addition to the color buffer. Beyond that, initializing the depth buffer is really very trivial in OpenGL. You enable the depth test and you set the depth function to GL_LESS. Even if you don't set the depth function that is the default. You don't need to override this in the shader. The depth test will be performed by default. But in fact, with today's programmable shaders if for whatever reason you wanted to do your own funky depth test, you can actually override it. So let's go back and show the demo. Let me first show you some of the aspects of the depth test. So you notice that when you initialize the display mode, I earlier had single and RGB. But now I have double and RGB and depth. And finally, when you actually draw in display, you'll notice that the last part swaps the buffers if DEMO is greater than or equal to 2. So let me now set DEMO is equal to 2. And as before, I'm going to actually make my program. And now you can see, voila, the plane is in the right place. The order of drawing doesn't matter. Just for fun, I'll move it back to where it was originally. And you'll see again that doesn't make any difference. So earlier, we had the plane here. So, let me uncomment this and I can comment this again. You'll notice that, again, there's no difference about where I place the plane. So depth buffering ensures that you get the correct perception of depth, you get objects that are nearer to you that are drawn, objects that are further away that are not drawn. The Z-buffer is really one of the most fundamental concepts in computer graphics, and it ensures that objects are drawn properly, that hidden objects are not drawn, and hidden surfaces and hidden lines are eliminated.