OpenGL的:如何确定一个3D(渲染)点是在它前面的其他3D(渲染)原语阻塞?(OpenGL: H

2019-08-02 02:18发布

在我的OpenGL程序,我做的顺序如下:

// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it

用于显示点信息(说点标识符/数),I转换点到二维窗口的3D坐标使用坐标gluProject ()。 我写在该二维窗口位置使用点标识符glRasterPos ()和二维字符绘制代码。

当呈现点通过另一个原语阻塞,则自动不是由于自动阻塞测试和发生在OpenGL的流水线深度测试显示。 然而,我的观点标识文本显示跑题了,即使被遮挡,因为我没有得到这个封闭信息。

如何确定一个三维(渲染)点是在它前面的其他3D(渲染)原语阻塞? 还是有更好的方式来显示, 只有当没有遮挡它旁边的点信息的文本?

注:我知道需要一个额外的渲染通道的方法。 我觉得这些都是我的目的昂贵。

Answer 1:

如果你不愿意使用遮挡查询第二传给你可以尝试采样Z缓冲区进行比较的测试点。

既然你旁边添加文本到一个点,抢标准化Z缓冲器值(用说gluProject)的点,然后在该点(使用glReadPixels)值进行比较,该值将采样Z缓冲区。 如果你的观点是落后(大于)你采样的深度值,您的点应被遮挡,你可以选择不绘制文本。

当然,这需要你呈现文本之前,所有的几何图形,但不应该是一个问题。

示例代码:

// 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


Answer 2:

从z缓冲器读取可以很现代的硬件非常缓慢。 这就是为什么遮挡查询被发明。 中查找ARB遮挡查询扩展。 它有一对夫妇滞后的帧,然后才能得到结果,但不会达到效果。

如果遮挡查询是不会因任何原因失效,下一个退而求其次的选择是使用BSP树(不使用GL的话)做软件射线相交世界的操作。



Answer 3:

继艾伦的回答,您可以从您的摄像头位置的光线投射到你的观点,并确定它是否相交的任何几何图形的测试闭塞数学。 有大量的参考文献的因特网做射线对象相交测试(参见,例如, 对象/对象交叉路口页 )。 如果你有大量的几何形状,那么你可能需要使用的约束体积或BSP树来加快速度。

作为奖励,你的闭塞代码应该是一个更容易单元测试,因为它不依赖于从OpenGL的提取值。



Answer 4:

从阿什温Nanjappa回复是非常有益的。 我不是一个OpenGL专家,所以我花了一段时间来了解如何获得MVP矩阵。 我在这里分享代码,以补充他的职位:

    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );


文章来源: OpenGL: How to determine if a 3D (rendered) point is occluded by other 3D (rendered) primitives in front of it?