如何在纯OpenGL中在屏幕上可见的所有内容上获得边界框?我想要边界框的所有 8 个点的 X、Y 和 Z。
3 回答
OpenGL 没有定义您在屏幕上看到的固定“盒子”体积。从某种意义上说,应用程序使用变换和投影定义了这些边界 -通常不形成矩形棱柱。最接近这种“边界框”的是标准化的设备坐标空间或投影后的3d 视口。
在世界坐标空间中包含所有几何图形的边界框是您必须从数据中确定的,与 GL 管道无关。
要恢复世界坐标空间 (WCS) 中映射到视口角的点,您需要了解矩阵变换和齐次坐标的工作原理。
投影(除以 W)后,标准化设备坐标空间 (NDCS) 中的“前”或“近”平面为:Z/W = -1
. NDCS 是左手坐标空间。
这对应于超平面: Z = - W
,在裁剪坐标空间中,因此形式的任何(同质)点:(x, y, -z, z)
将投影到:(x/z, y/z, -1, 1)
。
映射到 3D 视口的规范视图体积由以下公式定义:
-1 <= X/W <= 1, -1 <= Y/W <= 1, -1 <= Z/W <= 1
,以 (6) 个超平面为界:
X ± W = 0,Y ± W = 0,Z ± W = 0(均匀剪裁平面)
因此,可以扩展上述内容以找到对应于 3d 视口的视体积“角”的(齐次)坐标。考虑视口的右上角,在“近”平面上。它对应于:(1, 1, -1, 1)
,尽管形式的任何点:(W, W, -W, W)
都将投影到相同的 3D (NDCS) 点。
给定一些 matrix:[M]
将一个点P
(在 WCS 中)转换为 yield Q = (1, 1, -1, 1)
,然后只需使用逆(矩阵)变换即可:P = inv[M] * Q
相同的想法可以应用于每个“角落”。它对于拾取也非常有用 - 拾取光线从“眼睛”延伸到(x, y, -1, 1)
.
注意:这比我打算介绍的更详细,并且可能超出了 OP 的要求,但我看到很多关于拾取的问题。
为什么你需要 OpenGL?是你在画东西,所以只需对你的所有数据运行一个函数。考虑投影并丢弃视图体积之外的结果;检查非常简单,尤其是在使用正交投影时。
我认为在 OpenGL 中,屏幕上的内容是一个截锥体,而不是一个盒子。