目前我们一直是在竖屏情况下进行学习调试的,那如果我们在横屏下进行调试,会发生什么,很明显宽高比发生了变化,导致我们的矩形,从竖形变成了横形,看起来好像被压扁了,效果如下图:
之所以会这样,是因为我们之前直接把坐标传递给OpenGL时,没有考虑屏幕的宽高比。每个二维和三维应用程序都有一个共同的问题。
在开发图形应用程序时,我们经常面临一个挑战,如何在不同尺寸和方向的屏幕上正确地显示内容。这个问题在二维和三维图形编程中尤为常见。OpenGL作为一个强大的图形库,提供了一种解决方案,那就是使用投影技术来将三维世界映射到二维屏幕上。
投影技术的核心是使用矩阵变换来适应不同的屏幕尺寸和方向。这样,无论用户使用的是手机、平板电脑还是桌面显示器,图形都能以正确的比例和形状显示出来。例如,如果我们没有正确地应用投影,一个矩形可能在某些设备上看起来会被压扁或拉伸。
为了解决这个问题,我们需要首先回顾一些基本的线性代数知识,了解矩阵和向量是如何进行乘法运算的。这将帮助我们理解如何通过矩阵来定义和实现投影变换。
接下来,我们将学习如何利用投影矩阵来调整图形的显示,以适应屏幕的方向变化。通过这种方式,我们可以确保无论屏幕如何旋转或改变大小,图形都能保持其正确的形状和比例,例如,一个桌子在任何情况下看起来都应该是矩形的,而不是被压扁的。
通过学习和应用投影技术,我们可以确保我们的图形应用程序能够更好地适应各种不同的显示设备,提供更加一致和准确的视觉体验。
我们将继续在上一篇的基础上进行本篇内容的开发。
宽高比问题
在OpenGL中,我们通常将所有要渲染的物体映射到一个标准化的坐标空间内,这个空间的x轴和y轴范围是(−1,1),z轴也是如此。这种坐标系统称为归一化设备坐标,它与屏幕的实际尺寸和形状无关。
然而,这种坐标系统虽然方便,但在实际应用中可能会遇到问题。比如,如果我们直接使用归一化设备坐标而不进行任何调整,那么在不同的屏幕方向下,物体的形状可能会被扭曲。举例来说,如果一个设备的实际分辨率是1920像素宽和1080像素高,那么在竖屏模式下,
(−1,1)的坐标范围会对应到1920像素的高度,但只有1080像素的宽度。这会导致图像在水平方向上显得有些扁。同样,在横屏模式下,问题会以垂直方向上的扁形式出现。
归一化设备坐标假设坐标空间是一个正方形,但实际的屏幕视口可能不是正方形。这就可能导致图像在屏幕的一个方向上被拉伸,在另一个方向上被压缩。例如,在一个竖屏设备上,原本应该呈现为矩形的物体,可能会在水平方向上被压扁,而在横屏模式下,物体可能会在垂直方向上出现类似的变形。
要解决这个问题,我们需要考虑屏幕的实际尺寸和形状,通过适当的投影变换来调整物体的显示,确保它们在不同方向的屏幕上都能正确地显示,保持其应有的形状和比例。
适应宽高比
在处理屏幕显示内容时,我们经常需要考虑屏幕的宽高比。为了适应不同的屏幕尺寸和方向,我们可以采用一种简单的方法来调整坐标空间。这种方法的核心思想是保持一个维度的坐标范围不变,而根据屏幕的宽高比来调整另一个维度的坐标范围。
例如,如果我们有一个竖屏设备,其宽度为720像素,高度为1280像素,我们可以选择将宽度的坐标范围固定在
(−1,1)而将高度的坐标范围调整为(−1.78,1.78)。这个新的范围是根据屏幕的高度与宽度的比例计算出来的,确保了在竖屏模式下,图像的显示比例与屏幕的实际宽高比相匹配。
相反,在横屏模式下,我们可以将高度的坐标范围固定在(−1,1),并将宽度的坐标范围调整为(−1.78,1.78),以适应屏幕的宽度和高度的相对比例。
通过这种方法,无论屏幕是竖屏还是横屏,我们都能保证物体在屏幕上的显示效果是一致的,避免了因屏幕宽高比不同而导致的图像变形。
正交投影
为了适应屏幕方向的变化,我们需要调整坐标空间,这要求我们不再直接使用归一化设备坐标,而是转向一个虚拟坐标空间。在这个虚拟空间中,我们需要一种机制,将虚拟空间的坐标转换回归一化设备坐标,以便OpenGL能够正