C ++ / OpenGL将世界坐标转换为屏幕(2D)坐标

时间:2011-12-13 14:56:39

标签: c++ opengl matrix

我在OpenGL中制作游戏,我在世界空间中有一些对象。我想创建一个函数,我可以在其中获取对象的位置(3D)并将其转换为屏幕的位置(2D)并将其返回。

我知道以下各种变量中物体,投影矩阵和视图矩阵的3D位置:

Matrix projectionMatrix;
Matrix viewMatrix;
Vector3 point3D;

1 个答案:

答案 0 :(得分:33)

要进行此变换,必须首先获取模型空间位置并将其转换为剪辑空间。这是通过矩阵乘法完成的。我将使用GLSL风格的代码来明确我正在做的事情:

vec4 clipSpacePos = projectionMatrix * (viewMatrix * vec4(point3D, 1.0));

注意我如何在乘法之前将3D矢量转换为4D矢量。这是必要的,因为矩阵是4x4,并且您不能将4x4矩阵与3D矢量相乘。你需要第四个组件。

下一步是将此位置从剪辑空间转换为规范化设备坐标空间(NDC空间)。 NDC空间在所有三个轴的范围[-1,1]上。这是通过将前三个坐标除以第四个来完成的:

vec3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;

显然,如果clipSpacePos.w为零,则表示您遇到问题,所以您应该事先检查一下。如果它为零,则表示该对象位于投影平面内;它的视空间深度为零。这样的顶点会被OpenGL自动修剪。

下一步是从这个[-1,1]空间转换为窗口相对坐标。这需要使用您传递给glViewport的值。前两个参数是窗口左下角的偏移量(vec2 viewOffset),后两个参数是视口区域的宽度/高度(vec2 viewSize)。鉴于这些,窗口空间位置是:

vec2 windowSpacePos = ((ndcSpacePos.xy + 1.0) / 2.0) * viewSize + viewOffset;

这就是你走的路。请记住:OpenGL的窗口空间是相对于窗口的左下角,而不是左上角。