01 坐标裁剪
窗口是以像素为单位进行度量的。开始在窗口中绘制点、线和形状之前,必须告诉OpenGL如何把指定的坐标对翻译为屏幕坐标。我们可以通过指定占据窗口的笛卡尔空间区域完成这个任务,这个区域成为裁剪区域。在二维空间中,裁剪区域就是窗口内部最小和最大的x和y值。下图为两种常见的裁剪区域:
02 视口:把绘图坐标映射到窗口坐标
裁剪区域的高度和宽度很少正好与窗口的高度和宽度(以像素为单位)相匹配。因此,坐标系统必须从逻辑笛卡尔坐标映射到物理屏幕像素坐标。这种映射是通过叫做“视口”的设置来指定的。视口就是窗口内部用于绘制裁剪区域的客户区域。视口简单地把裁剪区域映射到窗口中的一个区域。
下图是一个很大的窗口,其大小为300*200像素,它的视口被定义为整个用户区域。如果这个窗口的裁剪区域被设置为沿x轴0至150,沿y轴0至100,我们看到这个窗口逻辑坐标将被映射到一个更大的屏幕坐标系统中。
而下图显示的是一个裁剪区域相匹配的视口,我们看到的这个窗口仍然是300*200像素,此时可视区域占据窗口的左下部分。
我们可以使用视口来缩小或放大窗口中的图像,也可以通过把视口设置为大于窗口的用户区域,从而只显示裁剪区域的一部分。
03 投影:从3D到2D
不管我们觉得自己的眼睛看到的三维图像有多么真实,屏幕上的像素实际上只是二维的。那么OpenGL是如何把这些笛卡尔坐标翻译为可以在屏幕上绘图的二维坐标呢?答案是“投影”。如下图所示:
背景中的一座房子被描绘到一块扁平的玻璃上。通过指定在窗口中显示的视景体Viewing Volum
,并指定如何对它进行变换,可以得到不同的投影。
正投影Orthographic Projection
使用这种投影时,需要指定一个正方体或者长方体的视景体,视景体之外的任何物体都不会被绘制。实际大小相同的物体,不管远近,在屏幕上都具有相同的大小。
透视投影 Perspective Projection
这种投影中,远处的物体看上去比近处的物体更小一些。它的视景体看上去有点像一个顶部被削平的金字塔,剩下来的形状称为平截头体 Frustum
。靠近视景体前面的物体看上去比较接近它们的原始大小,靠近过视景体后补的物体,看上去就显得比较小。