In my OpenGL program, I am doing the following in sequence:
// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it
For displaying the point information (say a point identifier/number), I convert the 3D coordinates of the point to 2D window coordinates using gluProject(). I write the point identifier at that 2D window location using glRasterPos() and 2D character rendering code.
When a rendered point is occluded by another primitive, it is automatically not displayed due to automatic occlusion test and depth test that happens in the OpenGL pipeline. However, my point identifier text is displayed beside the point, even when it is occluded since I do not get this occlusion information.
How to determine if a 3D (rendered) point is occluded by other 3D (rendered) primitives in front of it? Or is there a better way to display the point information text beside it only when it is not occluded?
Note: I am aware of the methods that require an extra rendering pass. I feel that those are expensive for my purpose.
If you're not willing to use an occlusion query second pass you can try sampling the Z-buffer to compare against your test point.
Since you are adding text next to a point, grab the normalized Z buffer value (say using gluProject) of the point, then compare that value to the sampled Z-buffer (using glReadPixels) value at that point. If your point is behind (greater than) the depth value you sampled, your point should be occluded and you can choose not to draw the text.
This of course requires that you render all your geometry before the text, but that shouldn't be an issue.
Sample code:
// Assumed to already hold 3D coordinates of point
GLdouble point3DX, point3DY, point3DZ;
// Project 3D point coordinates to 2D
GLdouble point2DX, point2DY, point2DZ; // 2D coordinates of point
gluProject( point3DX, point3DY, point3DZ,
mMatrix, pMatrix, vMatrix, // MVP matrices
&point2DX, &point2DY, &point2DZ);
// Read depth buffer at 2D coordinates obtained from above
GLfloat bufDepth = 0.0;
glReadPixels( static_cast<GLint>( point2DX ), static_cast<GLint>( point2DY ), // Cast 2D coordinates to GLint
1, 1, // Reading one pixel
GL_DEPTH_COMPONENT, GL_FLOAT,
&bufDepth);
// Compare depth from buffer to 2D coordinate "depth"
GLdouble EPSILON = 0.0001; // Define your own epsilon
if (fabs(bufDepth - point2DZ) < EPSILON)
// 3D point is not occluded
else
// 3D point is occluded by something