OpenGL ES应用开发实践指南(android 卷)笔记 第五章1

来源:互联网 发布:尼康d810调焦软件 编辑:程序博客网 时间:2024/06/04 19:19

第五章  调整屏幕的宽高比

1.桌子在横屏模式情况下被压扁了,之所以会发生,是因为我们之前直接把坐标传递给OpenGL时,没有考虑屏幕的宽高比。每个二维和三维应用程序都有一个共同的大问题:怎样决定在屏幕上显示什么以及如何针对屏幕尺寸做出调整?这个问题有一个通用的解决方案:在OpenGL里,我们可以使用投影把真是世界的一部分映射到屏幕上,以这种方式映射会使它在不同屏幕尺寸或方向上看起来总是正确的。考虑到有如此大量的设备,能够适应这些设备是很重要的。

首先,我们要复习一些基本的线性代数内容,并学习矩阵(matrix)与向量(vector)是如何相乘的。

然后,要学习如何通过矩阵定义和使用投影,这能让我们弥补屏幕方向变化的影响,这样桌子看起来就不会是扁的。

2.宽高比的问题

我们现在相当熟悉这样一个事实,在OpenGL里,我们要渲染的一切物体都要映射到x轴和y轴上[-1,1]范围内,对z轴也是一样的。这个范围内的坐标被成为归一化设备坐标,其独立于屏幕实际的尺寸或形状。

不幸的是,因为它们独立于实际的屏幕尺寸,如果直接使用它们,我们就会遇到问题,例如横屏模式下被压扁的桌子。

假设实际的设备分辨率以像素为单位是1280*720,这在新的Android设备上是一个常用的分辨率。为了使讨论更加容易,让我们也暂时假定OpenGL占用整个显示屏。

如果设备是竖屏模式下,那么[-1,1]的范围对应1280像素高,却只有720像素宽。图像会在x轴显得扁平,如果在横屏模式下,同样的问题也会发生在y轴上。

归一化设备坐标假定坐标空间是一个正方形。然而,因为实际的视口(viewport)可能不是一个正方形,图像就会在一个方向上被拉伸,在另外一个方向上被压扁。在一个竖屏设备上,归一化设备坐标上定义的图像看上去就是在水平方向上被压扁了;在竖屏模式下,同样的图像就在另一个方向上看起来是压扁的。

3.适应宽高比

我们需要调整坐标空间,以使它把屏幕的形状考虑在内,可行的一个方法是把较小的范围固定在[-1,1]内,而按屏幕尺寸的比例调整较大的范围。

举例来说,在竖屏情况下,其宽度是720,而高度是1280,因此我们可以把宽度范围限定在[-1,1],并把高度范围调整为[-1280/720,1280/720]或[-1.78,1.78]。同理,在横屏模式情况下,把高度范围设定为[-1.78,1.78],而把高度范围设为[-1,1]。

通过调整已有的坐标空间,最终会改变我们可用的空间。

通过这个方法,无论是竖屏模式还是横屏模式,物体看起来就都一样了。

4.调整坐标空间,以便我们把屏幕方向考虑进来,我们需要停止直接在归一化设备坐标上工作,而开始在虚拟坐标空间里工作。接下来,我们需要找到某种可以把虚拟空间坐标转换回归一化设备坐标的方法,让OpenGL可以正确地渲染它们。这种转换应该把屏幕方向计算在内,以使空气曲棍球桌子在竖屏模式和横屏模式情况下看上去都是正确的。

我们想要进行的操作叫做正交投影(orthographic projection)。使用正交投影,不管多远或多近,所有物体看上去大小总是相同的。为了更好地理解这种投影是做什么的,想象一下,在我们的场景中有一个火车轨道,直接从空中俯瞰。

还有一种特殊类型的正交投影,被称为等轴测投影(isometric projection),它是从侧角观察的一种正交投影。正如在一些城市模拟和策略游戏中看到的,这种类型的投影能用来重新创建一个经典的三维角。

从虚拟坐标回到归一化设备坐标

当我们使用正交投影把虚拟坐标变换回归一化设备坐标时,实际上定义了三维世界内部的一个区域。在这个区域内的所以东西都会显示在屏幕上,而区域外的所有东西都会被剪裁掉。






阅读全文
0 0
原创粉丝点击