典型的OpenGL投影矩阵(从glFrustum或gluPerspective获得)将相机点放置在原点。投影平面位于(0, 0, -1):相机前方一单位。
因此,对于给定的顶点,你需要找到的是在(0, 0, -1)平面上投影时的X和Y位置。这在技术上被称为“光线追踪”,但由于它是一个轴对齐的平面,并且相机位于原点,所以实际上只是简单的算术运算。
vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);
请注意,在此透视投影下插值参数将在窗口空间中是线性的,而不是在眼睛/相机空间中。也就是说,将没有
透视正确的插值。
另外,请注意,上述“简单算术”并没有考虑到FOV。为了处理这个问题,您需要通过透视矩阵的左上部分来转换
oldPosition
的X和Y。或者只需从投影矩阵中提取0,0和1,1的值,并将它们与
oldPosition
的X和Y相乘。这将解决缩放问题。
还有一点需要注意,因为您没有说明整体目标。
OpenGL不要求您使用单个投影矩阵渲染整个场景。您可以使用正交矩阵渲染部分场景,同时为其余部分使用透视矩阵。这通常在游戏中完成,其中HUD和文本元素以正交方式呈现,而游戏本身则处于3D透视状态。
如果这就是您要做的事情,那么您只需要像下面这样做:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);
//Render my perspective stuff here.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...);
glMatrixMode(GL_MODELVIEW);
// Render my orthographic stuff here.
如果您有正交对象与透视对象重叠,您可能希望在正交渲染期间关闭深度测试。