9

我正在努力找出一些东西,比如说我正在渲染一些高度为 100,宽度为 100 的图像。

在场景 A

glOrtho(0,100,0,100,-100,100)当glOrthois定义为(left,right,bottom,top,zNear,zFar)并且glViewPort(0,0,50,50)glViewPort定义为(左下角x,左下角y,宽度,高度)时,我正在使用a 。

在场景 B

当定义为 (left,right,bottom,top,zNear, zFar )glOrtho(0,50,0,50,-100,100)和glViewPort 定义为 (左下角 x, 左下角 y, 宽度, 高度)glViewPort(0,0,100,100)glOrthois

这基本上意味着在场景 A 中,图像将被渲染到比它需要的更低的宽度和高度(即每两个像素渲染一次)。在原始图像中将映射到目标“表面”中的一个,但仍会看到整个图像。

但是,在场景 B 中,图像将被剪裁,因此只有左上角的四分之一可见。我对么?- 为了清楚起见,这是一个来自明天的 CG 测试的问题,我想确保我正确获得了 openGL......(已经阅读了 API...... =\

4

2 回答 2

28

glViewPort 以屏幕像素为单位:就是这样,它与显卡“内部”的 3D 世界无关。它只是告诉窗口的哪一部分将用于渲染(或只是可见)。

glOrtho 改变了“内部”世界并且是 OpenGL 单元:更多的 OpenGL 单元将适合屏幕的可见部分,因此如果您增加正交大小,“更大”的对象将很容易适合可视区域。

修改视口不会改变截锥体,事实上,相同的图像只会被拉伸以适应新的视口。

解释性图像:

图1:视口为半窗

在此处输入图像描述

图 2:如果我只是将视口加倍,图像就会被拉伸(填充不同表面的相同截锥体)

在此处输入图像描述

因此,保持纵横比的唯一解决方案也是将正交大小加倍(在这种情况下,我将左右值加倍)

图 3:最终结果(请注意,现在 3d 世界的大部分是可见的):

在此处输入图像描述

更多详细信息可在非常熟悉的 OpenGL NeHe 制作网站上找到。

于 2014-07-02T18:51:14.577 回答
1

这两件事会影响 GL 坐标转换管道的不同阶段。OpenGL 使用一个视锥体,它在标准化的设备空间中是一个在所有 3 个维度上都在 [-1,1] 范围内的立方体。该glOrtho()调用通常用于设置投影矩阵,它将眼睛空间坐标转换为剪辑空间。GL 将在内部从剪辑空间转换为 NDC。在正交情况下,您甚至可以假设剪辑空间和 NDC 是同一件事。视口描述了从 NDC 到窗口空间的转换,这是光栅化发生的地方。

我对么?- 为了清楚起见,这是我明天进行的 CG 测试中的一个问题,我想确保我正确获得了 openGL ......

对于案例 A,您可能是正确的。在案例 B 中,可能会看到左下角。但实际上,如果没有提供进一步的信息,这个问题是无法回答的。您说图像的“宽度”和“高度”为 100。通常,这些尺寸被解释为每个方向上的像素数。但在这种情况下,这个问题似乎暗示着四边形与图像一起纹理化的渲染方式使其最终出现在从 (0,0) 到 (100,100) 的眼睛空间中(通过直接将其用作对象坐标,或通过使用另一个模型和/或视图变换)。也没有指定图像是如何映射的,即它可以被旋转(这使得不可能以任何合理的信心确定在场景 B 中看到图像的哪个部分)。

另一件值得注意的事情是glOrtho()将当前矩阵乘以正交投影矩阵。因此,如果该矩阵的初始状态未知,则无法说出最终的变换将是什么。

我希望真正的测试不会包含这种指定错误的问题。

于 2014-07-02T18:49:33.883 回答