【问题标题】:OpenGL stretched shapes - aspect ratioOpenGL拉伸形状 - 纵横比
【发布时间】:2012-01-30 22:31:57
【问题描述】:

我的 openGL 视图大小为(比如说..)800(宽度)x600(高度)。 然后我得到了一个二维坐标对象:

0.0 , 0.0
0.1 , 0.0
0.1 , 0.1
0.0 , 0.1

正如你所理解的,这个应该是一个正方形(基于类比)。 但是在我的 openGL 视图上打印这个拉伸。现在,我明白为什么会这样了。这基本上是因为我正在处理-1,1的默认矩阵。 而且由于我的 800x600 分辨率没有 1 的纵横比,我的形状被拉伸了。

现在我对如何解决这个问题更感兴趣。我已经阅读了诸如 glFrustum、glOrtho、glViewPort 之类的函数,它们发生在投影矩阵上并且可以解决这些问题。问题是,我不确定使用它们。我基本上想要的是在制作正方形时保持上述坐标,并在我的视图上实际显示为正方形。

解决这个问题的正确方法是什么?

【问题讨论】:

标签: opengl 2d aspect-ratio


【解决方案1】:
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
float aspect = (float)width / (float)height;
glOrtho(-aspect, aspect, -1, 1, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

更新:解释发生了什么

OpenGL 是一个状态机,在 OpenGL-2.1 及以下版本中维护一组转换矩阵。顶点 ↑v 首先与 modelview 矩阵相乘以产生眼睛坐标顶点 ↑v',用于照明计算。然后↑v'乘以投影矩阵,到达所谓的剪辑空间↑v'',在哪里(顾名思义)执行裁剪操作(或者至少定义了它们的结果)。从剪辑空间中,通过计算 ↑v#{x,y,z,w} = ↑v 可以达到所谓的 标准化设备坐标 (NDC)强>{x,y,z,w}/↑v_w

↑v# 被定义在 [-1 … 1] 范围内,该范围被映射以填充选定的视口矩形。视口不影响变换矩阵!它只是从 NDC 到它定义的窗口坐标的转换。

在上面的代码中,我将模型视图矩阵设置为恒等式,即顶点按原样进入投影。投影本身是一个正射投影,它映射 x 值范围 [-aspect ... aspect] → [-1 ... 1] 和 y 值范围 [-1 ... 1] → [-1 ... 1](即 y 没有变化)。因此,顶点通过窗口方面进行转换,以适应 NDC 到视口的值范围。

为什么我告诉你 OpenGL 是一个状态机?因为这意味着您可以随时切换投影和变换。因此,如果您需要渲染小地图,请不要将其放置在 3D 场景中。只需为其切换视口和投影。一般来说,您应该在绘图函数中设置所有渲染状态(即所有矩阵)。窗口事件处理程序(重绘处理程序除外)根本不应该执行任何 OpenGL 操作。

【讨论】:

  • 这确实给我带来了我想要的结果。然而,我担心它会产生一些其他问题,我没有立即意识到这些问题。例如,我的矩阵刚刚更改为什么坐标。 1024/600 等于 1.7 ......我的矩阵也是 -1.7->1.7(也许我不应该在这里使用 matrix 关键字)。如果您添加更多关于刚刚发生的事情的信息,我将不胜感激。 +1 迄今为止提供了一个有效的解决方案。
  • 很好的解释,事实上我想出了一些我渴望尝试的巧妙想法。谢谢
  • 我很困惑。不是正射投影映射[-aspect,aspect] -> [-1,1]而不是反过来吗?
  • @JoSo:确实是这样,当我写的时候不知何故在“反向”思考(基本上你想将 NDC 坐标范围 [-1…1] 映射到 [-aspect…as​​pect] ,但当然从剪辑空间顶点位置的角度来看,情况正好相反。
  • 谢谢。这真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-02
  • 2013-04-17
  • 2019-07-26
  • 2013-04-25
  • 2020-11-25
  • 1970-01-01
相关资源
最近更新 更多