前面有讲到过变换函数时,需要确定自己的矩阵,上一节讲的是模型视图矩阵,这一节就来讲一讲投影矩阵。
注意:在调用本节描述的任意变换函数之前,都不要忘记首先调用下面的函数:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
这样做的目的是为了使后面调用的变换函数是作用与投影矩阵,而不是模型变换矩阵。
1.透视投影
透视投影,物体距离观察点越远,在最终图像中看上去就越小。这就好比照相机照相原理,物体距离照相机越远,在相机成像时,形成的影像就越小。
glFrunstum()用于计算一个用于实现透视投影的矩阵,它与当前的投影矩阵(一般为单位矩阵)相乘。如附图所示,视景体用于剪裁那些位于它之外的物体,平截头体的4个侧面底面和顶面对应于视景体的6个剪裁平面。位于这些平面之外的物体(或物体一部分)将被裁掉。
注:投影矩阵的目的就是为了定义一个视景体。视景体有两个用途:1,决定一个物体如何映射到屏幕上;2.定义哪些物体被剪裁到图像之外。
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分别表示从观察点到近侧和远侧剪裁平面的距离,它们的值应是正的。
gluPerspective()函数也是创建一个视景体,与调用上面glFrunstum()产生的视景体相同。但是这个函数并不是指定近侧剪裁平面的连个角,而是指定y方向上视野的角度和纵横比(x/y)。
注:gluPerspective()仅限于创建沿视线方向同时对称于x轴和y轴的平截头体,就是平时我们需要的这种。
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near , GLdouble far); 创建一个表示对称透视试图平截头体的矩阵,并把它与当前矩阵相乘。 fovy是yz平面上视野的角度,它的值必须在[0.0, 180.0]之间。 aspect是这个平截头体的纵横比,也就是它的宽度除以高度。 near和far值分别是观察点与近侧才见平面及远侧剪裁平面的距离(z轴负方向)均为正值。
举例:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(22, w/h, 1 , 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
2. 正投影
在正投影下,视景体是一个平行的长方体,两端大小并没有不同,也就是物体与观察点之间的距离不影响观察者看到的物体大小,它以它实际的形态存在。正投影之后,保持它们的实际大小以及它们之间的角度是至关重要的。
glOrtho()函数创建一个正交平行的视景体。如没有其它变换,投影的方向与z轴平行,观察点的方向朝向z轴的负方向(没有其它变换时,所有的投影方向均如此)。
void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); 创建一个表示正交平行视景体的矩阵,并把它与当前矩阵相乘。 (left, bottom, -near) 和(right, top, -near)是近侧裁剪平面上的点,分别映射到视口的左下角和右上角。 (left, bottom, -far) 和(right, top, -far)是远侧裁剪平面上的点,分别映射到视口窗口的左下角和有伤口。 near和far可以是正值或负值,甚至可以设置为0.但是near和far不应该取相同的值。
二维图像投影到二维屏幕上时,提供了另一个函数完成。此时场景中的物体所有z坐标都假定位于-1.0~1.0之间。所有z坐标都是0.
void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); 创建一个表示把二维坐标投影到屏幕上的矩阵,并把当前矩阵与它相乘。 剪裁局域为矩阵,它的左下角坐标为(left, bottom) ,右上角坐标为(right, top)。
当场景中物体的顶掉通过模型视图矩阵和投影矩阵变换后,位于视景体之外的所有图元都将裁减掉。6个裁剪面就是定义视景体6个侧面的平面。还可以指定其它裁剪平面,使它们位于我们所需要的地方。