OpenGL中glOrtho和glViewport的区别

10

我正在努力弄清楚一件事情,假设我正在渲染一个高度为100、宽度为100的图像。

在情况A中

我使用了glOrtho(0,100,0,100,-100,100)glViewPort(0,0,50,50)。其中,glOrtho被定义为(left,right,bottom,top,zNear,zFar),glViewPort被定义为(lower left corner x,lower left corner y,width,height)。

在情况B中

我使用了glOrtho(0,50,0,50,-100,100)glViewPort(0,0,100,100)。其中,glOrtho被定义为(left,right,bottom,top,zNear,zFar),glViewPort被定义为(lower left corner x,lower left corner y,width,height)。

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

然而,在情况B中,这个图像将被剪裁,因此只有它的左上角的四分之一可见。 我正确吗? - 只是为了澄清,这是我明天CG考试的一个问题,我想确保我正确理解了OpenGL... (已经读过API了... =\)。

2个回答

30

glViewPort 是以屏幕像素为单位的:它与图形卡内部的3D世界没有任何关系,它只告诉我们窗口的哪一部分将用于渲染(或仅仅可见)。

glOrtho 则改变“内部”世界并使用OpenGL单位:如果你增加正交大小,更多的OpenGL单位将适合于屏幕可视区域内,所以“更大”的对象将轻松适应可视区域。

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

解释性图片:

Picture 1: 视口为窗口的一半

enter image description here

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

enter image description here

因此,保持纵横比的唯一方法是将正交大小加倍(在这种情况下,左和右值都加倍)

Picture 3: 最终结果(请注意,现在3D世界的更大部分可见):

enter image description here

更多细节请参见OpenGL NeHe Productions上相当熟悉的站点


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

我正确吗? - 只是为了明确,这是我明天要进行的CG测试中的一个问题,我想确保我正确理解了OpenGL...

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

值得注意的另一件事是,glOrtho()将通过正交投影矩阵乘以当前矩阵。因此,如果该矩阵的初始状态未知,则无法确定结果转换将是什么。

希望真正的测试不包含这样的不明确问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接