照片:如何确定如果一个3D(渲染)的一点是封闭的其他3D(渲染)的原语在前?
题
在我加载的程序,我这样做以下顺序:
// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it
为显示点的信息(说一点的标识/数量),我将3D坐标点以2D窗口的使用坐标 gluProject().我写点标识符,在那2D窗的位置,使用 glRasterPos()and2D字呈现代码。
当呈现的点闭塞的另一个原始的,它自动 不 显示由于自动阻塞的测试和深度测试这种情况发生在载的管道。然而,我点的标识文字旁边的一点,即使当它被封闭,因为我得不到这种咬合的信息。
如何确定如果一个3D(渲染)的一点是封闭的其他3D(渲染)的原语在前?或者是有更好的方式来显示的点信息的文本在它旁边 只 当它不是闭塞的?
注:我知道方法,需要额外呈现通过。我觉得这些是昂贵的,对我的目的。
解决方案
如果你不愿意使用遮挡查询的第二个通过你可以尝试抽样的Z-缓冲区进行对比,你的测试点。
因为你是加文字旁边一点,抓住化的缓冲器Z值(说使用gluProject)的中点,然后进行比较价值的采样Z-缓冲区(使用glReadPixels)值在这一点上。如果你点的背后是(更大的比)的深度值进行采样,你一点应当闭塞,你可以选择不提请文本。
这当然需要你们呈现所有的您的几何形状之前的文本,但这不应该是一个问题。
样本代码:
// 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
其他提示
阅读从z缓冲区可能是非常非常缓慢,在现代化的硬件。这就是为什么塞查询的发明。看起来ARB-闭塞查询扩展。它有一对夫妇的框架的滞后才能得到的结果,但它不会打你的表现。
如果闭塞的查询不会的工作无论出于何种原因,下一个后备选项是做一个软件的射线交叉的世界中的作用BSP树(其中不使用GL在所有)。
另外,艾伦的回答,可以测试对闭塞的数学上的突出的光线从你的摄像机的位置你的观点,并确定是否相交任何你几何形状。有很多参考文献在互联网上做雷对象交叉点测试(例如,见的 目的/目交的页面).如果你有很多的几何形状的,然后你可能需要加快速度使用边界卷或一个BSP树。
作为奖励,你闭塞码应该很容易单元的测试,因为它不依赖于抽取价值从照片.
答复Ashwin Nanjappa是非常有益的。我不是一个载的专家,所以这花了我一段时间来了解如何获得MVP的矩阵。我分享这里的代码,以补充他的职:
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );