如何将2D世界转换为屏幕坐标OpenGL

时间:2013-04-21 02:55:04

标签: opengl screen coordinates transformation

我目前正致力于将OpenGL驱动的渲染器实现为2D游戏引擎。

因为OpenGL屏幕坐标空间是[-1,1],所以我对它应该如何与通用的笛卡尔2D世界坐标系接口感到困惑。

让我们说世界上的视口是[-500,-500]到[1200,1200],其中[0,0]是世界的起源。我只需要翻译并缩小到-1和1之间的坐标吗?或者是否需要进行其他形式的转型?

如何计算在屏幕上绘制已在您自己的坐标系中定义位置的对象的位置?

我很感激有和没有glOrtho的解释(因此我们也可以使用Z轴进行透视效果)。

3 个答案:

答案 0 :(得分:17)

首先,OpenGL使用多个坐标系,因此没有“ OpenGL坐标系”。您所指的是归一化设备坐标(NDCs),其中所有三个坐标都在[-1,1]范围内。不同的坐标系及其名称在“{9.011如何转换坐标?什么是不同的坐标空间?”一节中解释here。 1)

其次,为了避免混淆,在OpenGL中,术语“视口”指的是您正在渲染的窗口部分,它位于窗口坐标中。在你的问题中,你用它来描述你想要渲染的世界的部分(l,r,t,b)=( - 500,-500,1200,1200),它是世界坐标。

您问如何“计算在屏幕上绘制对象的位置”。您需要做的是定义一个从一个坐标系映射到另一个坐标系的变换(4x4矩阵)。您的2D世界以世界坐标给出,因此您需要定义一个矩阵,将世界坐标转换为NDC,即投影矩阵。在您的着色器中,您只需将顶点与此投影矩阵相乘,即可获得NDC。 glm::ortho / glOrtho计算此类投影矩阵。至于透视投影,目前尚不清楚你想做什么,但你应该在glm中试验perspectivelookat函数。

要清楚,您可以在任何所需的坐标系中定义顶点(称为世界坐标系),并简单地绘制这些顶点。您的顶点着色器的工作是应用您定义的变换。

另请注意,您指定了一个正方形,通常这不是您想要的。监视器和大多数窗口都不是正方形,因此如果将该正方形映射到典型的视口,您将看到一个扭曲的世界视图。您需要考虑视口的宽高比(宽度:高度)。我试图解释here


1)作为旁注,FAQ很老,指的是OpenGL的古老版本。如今,程序员被期望并被鼓励管理模型视图和投影矩阵本身,因为您需要在着色器中使用它们。我强烈推荐glm,它只是标题,因此非常容易集成,并且具有很好的语法,可以反映GLSL。

答案 1 :(得分:2)

在投影矩阵上使用glOrtho,然后正常绘制。对于你的例子,我猜你想要glOrtho(0,1000,0,3000,-1,1)这将给你一个视口1000个单位的宽度和3000个单位的高度

答案 2 :(得分:0)

将场景放置在您想要的任何坐标系中。我建议使用glm(http://glm.g-truc.net/)初始化矩阵并执行数学运算等。因此,您可能拥有一个场景图引擎,您可以在其中管理2D / 3D世界中的所有对象。只需在glm中设置视图和投影正确即可。实际上,您不需要任何图形管道实现细节 - 因此您的游戏引擎可能会有一个糟糕的设计决策。