投影变换的目的是定义一个视景体。视景体定义了场景的可视范围,以及场景如何投射到屏幕上。投影有两种:透视投影 和 正交投影。相关的函数有4个: GL库中两个, GLU库中两个。 GL库中的两个分别为glFrustum和glOrtho,GLU库中的两个分别为gluPerspective和gluOrtho2D。
3.3.1 透视投影
透视投影的特点就是,物体离照相机越远,它在最终图像中看上去就越小。即所谓的近大远小。
void glFrustum(GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble near, GLdouble far);
创建一个透视视图平截头体的矩阵,并把它与当前矩阵相乘。平截头体的视景体是由这个函数的参数定义的:(left, bottom, -near)和(right, top, -near)分别指定了近侧裁剪平面左上角和右下角(x, y, z)坐标。near 和far分别表示从观察点到近侧和远侧裁剪平面的距离,它们的值应该是正的。
由于glFrustum使用起来并不很直观。所以通常使用GLU库中的gluPerspective()函数。
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);
创建一个表示对称透视视图平截头体的矩阵,并把它与当前矩阵相乘。fovy是yz平面上视野的角度,它的取值范围是【0.0, 180.0】。aspect是这个平截头体的纵横比,也就是它的宽度除以高度。near和far分别是观察点与近侧裁剪平面以及远裁剪平面的距离(沿z轴负方向),这两个值都应该是正的。
OpenGL中的数值,并没有单位,唯一的规则是必须使用一致的测量单位。
3.3.2 正投影
正投影,与透视投影不同,物体与照相机的距离并不影响它看上去的大小。这种类型的投影,常用于建筑蓝图,或者计算机辅助设计的应用程序。
正投影使用的函数,叫glOrtho。
void glOrtho(GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble near, GLdouble far);
这个函数的参数,和glFrustum函数的参数完全一样。只是最终定义的视景体不一样。glOrtho定义的视景体如下图所示。
其中(left, bottom, -near)和(right, top, -near)是近侧裁剪平面上的点,分别映射到视口的左下角和右上角。(left, bottom, -far)和(right, top, -far)是远侧裁剪平面上的点,分别映射到视口的左下角和右上角。near和far可以是正值或负值,甚至可以设置为0。但是,near和far不应该取相同的值。
3.3.3 视景体裁剪
定义了视景体之后,场景中物体的顶点通过模型视图矩阵和投影矩阵进行变换之后,位于视景体之外的所有图元都将裁剪掉。6个裁剪平面就是定义视景体6个侧面的平面。还可以自定义裁剪平面,参照3.7节。