三维变换到二维投影_OpenGL版本

摘自:http://fred.easymorse.com/?p=296   (注明:已经打不开了,我是通过网页快照看到的)

从三维物体到二维图象,就如同用相机拍照一样,通常都要经历以下几个步骤:
  1、将相机置于三角架上,让它对准三维景物,它相当于OpenGL中调整视点的位置,即视点变换(Viewing Transformation)。
  2、将三维物体放在场景中的适当位置,它相当于OpenGL中的模型变换(Modeling Transformation),即对模型进行旋转、平移和缩放。
  3、选择相机镜头并调焦,使三维物体投影在二维胶片上,它相当于OpenGL中把三维模型投影到二维屏幕上的过程,即OpenGL的投影变换(Projection Transformation),OpenGL中投影的方法有两种,即平行投影和透视投影。为了使显示的物体能以合适的位置、大小和方向显示出来,必须要通过投影。
  4、冲洗底片,决定二维相片的大小,它相当与OpenGL中的视口变换(Viewport Transformation)(在屏幕窗口内可以定义一个矩形,称为视口(Viewport),视景体投影后的图形就在视口内显示)规定屏幕上显示场景的范围和尺寸。

视图变换和模型变换这两种变换可以互相替换,比如你不必移动相机(视图变换)来观察场景,而是通过移动场景(模型变换)。

在代码中,视图变换必须放在模型变换之前,但可以在绘图之前的任何时候执行投影变换和视口变换。视图变换函数gluLookAt()和模型变换函数glTranslate()等通常放在函数display()中,而视口变换函数glViewport()和投影函数glFrustum()等放在reshape()中。

模型变换:将顶点坐标从世界坐标系变换到视觉坐标系的过程。世界坐标系,也称为全局坐标系。可以认为该坐标系是固定不变的。在初始态下,其x轴为沿屏幕水平向右,y轴为沿屏幕垂直向上,z轴则为垂直屏幕面向外指向用户。长度单位定义为,窗口范围按此单位恰好是(-1,-1)到(1,1)。世界坐标是OpenGL中用来描述场景的坐标,相当于场景固定不变。用世界坐标系来描述物体及光源的位置。视觉坐标系,也称为局部坐标系。该坐标系是可以活动的。在初始态下,其原点及x,y 轴分别与世界坐标系的原点及x,y 轴重合,而z 轴则正好相反,即为垂直屏幕面向内。当前绘图坐标系是绘制物体时的坐标系,就是模型坐标系。程序刚初始化时,世界坐标系和当前绘图坐标系是重合的。当用glTranslatef(),glScalef(), glRotatef()对当前绘图坐标系进行平移、伸缩、旋转变换之后,世界坐标系和当前绘图坐标系不再重合。改变以后,再用绘图函数绘图时,都是在当前绘图坐标系进行绘图,所有的函数参数也都是相对当前绘图坐标系来讲的。OpenGL 中有一个坐标变换矩阵栈(ModelView),栈顶就是当前坐标变换矩阵,进入OpenGL管道的每个坐标(齐次坐标)都会先乘上这个矩阵,结果才是对应点在场景中的世界坐标。OpenGL中的坐标变换都是通过矩阵运算完成的,要注意的是变换中的矩阵乘法是左乘。

考察下面利用三个变换绘制顶点的代码:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(N);
glMultMatrixf(M);
glMultMatrixf(L);
glBegin(GL_POINTS);
glVertex3f(v);
glEnd();
glMultMatrix()函数,它表示把当前矩阵与参数表示的矩阵相乘并赋给当前矩阵。C是当前矩阵,glMultMatrix(M)后的当前矩阵为C*M。在这个过程中,GL_MODELVIEW状态相继引入了I(单位阵)、N、M、L矩阵。变换后的顶点为NMLv。因此,顶点的变换为N(M(Lv)),即是先作变换L,然后是变换M,最后才是N。这里,顶点v的实际变换顺序正好与指定的顺序相反。

矩阵栈操纵命令:
glPushMatrix();当前矩阵入栈,这时矩阵栈将栈顶值压入栈。
glPopMatrix();栈顶出栈,通常与上一条命令配合使用。
glLoadIdentity();将栈顶设为不变矩阵(就是对角线全为1其它为0的那个)。
glMultMatrix(M);将栈顶T设为M·T。

gluOtho2d()
剪裁面,类似照相机取景,在无限的空间中取出想要的一部分景色。

glViewPort()
指定一个剪裁面后,需要在窗口中显示出来。我们先取景(就是用gluOrtho2D()剪出来的剪裁面),然后在我们定义的窗口中选一个区域来显示这个取好的景。

你可能感兴趣的:(三维变换到二维投影_OpenGL版本)