PDA

View Full Version : Z Buffer



Rong Yao
03-06-2002, 07:44 AM
Is there any way to know the values in Z Buffer? Or is there any way to know which is the front most plane if there are several planes? OpenGL will check the values in Z Buffer and hide all the overlap parts if these parts are behide the front most(closest to the viewer) object. Is there any way for the user to know that? Thank you!

Furrage
03-06-2002, 08:33 AM
glEnable(GL_DEPTH_TEST)

and before you start drawing you clear the depth buffer with
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

Rong Yao
03-06-2002, 09:29 AM
Thank you, Furrage! My question actually is: is there any way for the programmer to know which plane is in front of another one if there are two planes in the view? OpenGL knows that with Z Buffer, however, how can I know this?

Our project: we need to retrieve some information from planes in the view. We only try to get information from the front most plane. So we need to know which plane is the front most one. Is there any way to do that?

Furrage
03-06-2002, 09:45 AM
You might try selection (Chapter 13 of the redbook). Otherwise you're going to have to use gluProject() and gluUnproject()

Rob The Bloke
03-06-2002, 06:38 PM
nope you dont!

The selection buffer will deal with multiple selections through the line projected down the line of sight.

In this case that's not needed because you only want to find the front polygon, handily sorted for you by the depth buffer.

The easiet way for you to do it is this :

1. USE DOUBLE BUFFERING AND RGB OR RGBA COLOR MODES!!! (very important and you'll see why shortly)

2. After drawing your scene and swapping your buffers, clear the back framebuffer.

3. Turn off lighting and texturing!!!!

4. Draw each of your planes using a specific colour for each one specified with glColor3ub() (or the 4ub version), using the color value as a reference number, eg :

poly1 = 0,0,1
poly2 = 0,0,2
...
poly255 = 0,0,255
poly256 = 0,1,0
...
poly16777216 = 255,255,255

keep black as a default - no poly here type thing.

5. Having drawn your polygons, there will be an image in your back buffer that contains a unique ID for each of your polygons that are visible. (the depth buffer would have sorted out which are visible)

6. Read the pixel you want to check (as RGB or RGBA unsigned bytes from the back buffer) and use the color value to work out which polygon has been drawn infront of all the others using the above indexing.

Thats it, the things to bear in mind though are that your graphics card must be able to support 24 or 32bit display modes. (wont work that well on a voodoo3!). Make sure you dont accidentally swap the buffers after doing the drawing for the second time, the idea of using the backbuffer is so that this remains invisible. There are better (faster) ways of doing this (namely BSP trees etc), but they ultimately involve more work.

marcus256
03-07-2002, 12:38 AM
You could also use the stencil buffer. Clear the stencil buffer to zero. When you draw your planes, assign a different stencil-value to each plane. Then you can read back the stencil values from the stencil buffer, and know (per pixel) which plane was drawn for each pixel. If I'm not misstaking, this is a way to do it:



glEnable( GL_STENCIL_TEST );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );

glStencilFunc( GL_ALWAYS, 1, 0 );
DrawPlane1();
glStencilFunc( GL_ALWAYS, 2, 0 );
DrawPlane2();
glStencilFunc( GL_ALWAYS, 3, 0 );
DrawPlane3();
...

glDisable( GL_STENCIL_TEST );

Then you can glReadPixels( GL_STENCIL_INDEX, .... ). Each pixel will have a value indicating which plane is "on top" (1,2,...,N).

What the code does is basically to tell OpenGL to update ("REPLACE") the stencil buffers where the depth-test passes (i.e. the pixel is closer to the observer than the previously stored pixel). The value that is written to the stencil buffer is the second parameter of glStencilFunc (1, 2, 3 etc). "GL_ALWAYS" says that we do not care what was written previously in the stencil buffer - we overwrite everything (hence we only rely on the depth buffer).

Do not forget to clear the stencil buffer each frame.