glReadPixel :: Occlusion Query

Ok I know that glReadPixel is slow and evil BUT I have to use it to make a quick and dirty occlusion query done by CPU… As strange as it sounds to my ears when the object ( the occluder ) distance is below 100 the code below work fine and I can determine if the point is occluded or not… BUT if the distance of the object is greater than 100 the depth < sz ALWAYS return false can someone explain me how I can fix that or point me another direction…

	gluProject( _x, _y, _z, 
		     _sx, _sy, &sz );

	glReadPixels( (GLint)*_sx,
				  &depth );

	if( depth < sz  )
	{ return GL_TRUE; }
	{ return GL_FALSE; }


depth normally is not the real depth, but must be calculated using front/backplane values

search the forums here about depth value calculation, I remember some topics about it here

Nope, above gluProject calculation results in window coordinates and the depth buffer contains window z-coordinates as well.

Since gluProject calculates in doubles, the OpenGL calculates in floats and the number of depth bits are normally 24 or even only 16, you need to expect a precision difference.
Make sure you do not use only 16 bits depth buffer.

If you experience this from a specific distance on, check what the resulting depth values are. I bet they are very near to 1.0 (farthest) and the depth precision there is worst.

There is not much you can do about that. Wrap your zNear and zFar values as closely as posible around your geometry. If you need precise results you might want to try HW occlusion culling instead. In your case you’d just need to render a single GL_POINT without writing into any buffer.
If you don’t have occlusion queries in HW you could use the stencil depth pass or fail parameter and the occlusion result would be a value in the stencil buffer you can fetch with glReadPixels using GL_STENCIL_INDEX and GL_UNSIGNED_BYTE.

BTW, depth and stencil often share a 32 bit word and the internal representation is not a float.
It’s fastest to read back the depth buffer as GL_UNSIGNED_INT then.