Model View Matrix,Projection Matrix

来源:互联网 发布:房地产行业体验 知乎 编辑:程序博客网 时间:2024/05/25 19:58

转自:http://blog.sina.com.cn/s/blog_43699c540101o1wu.html


上个星期最happy的事情之一是帮某一直说做游戏的朋友解决了几个问题。他正在做游戏设计课的Project,用到了一些关于OpenGL的东西。而我这种三脚猫水平的能帮到点忙,实在是幸运无比。


*关于向量与点
点表示3维空间中的一个位置。向量表示一个方向,也就是两个点的差值,p1-p2。无论是说位置还是方向都需要事先说明它是在哪个坐标系中的。在进行坐标系转换时,某点的位置关乎此坐标系原点的位置,而方向则无关了。

*关于旋转矩阵
旋转矩阵是一个3x3的矩阵,也就是Model ViewMatrix的左上角那个3x3的矩阵,其是一个正交矩阵。正交矩阵的逆就是它的转置。其是由三列组成的。
ux, vx, wx
uy, vy, wy
uz, vz, wz
第一列表示“这个坐标系的X轴正方向是世界坐标系中的(ux, uy, uz)“。
第二列表示“这个坐标系的Y轴正方向是世界坐标系中的(vx, vy, vz)“。
第三列表示“这个坐标系的Z轴正方向是世界坐标系中的(wx, wy, wz)"。
简单的记法是这样的:此坐标系中沿X方向走1格,在世界坐标中就沿着(ux, uy,uz)走了一格。也就是说世界坐标系中的(ux, uy, uz)就是此坐标系中的(1, 0, 0)

假设坐标系1的旋转矩阵是M1,坐标系1的原点在世界坐标中的p1,那么就可以将同一个点/方向在2个坐标系之间转换,
如果某点在坐标系1中的位置是p,那么它在世界坐标系中的位置就是M1*p +p1,在坐标系1中的方向v在世界坐标系中就是M1 * v。
如果某点在世界坐标系中的位置是p,那么它在坐标系1中的位置就是T(M1)*(p-p1);在世界坐标系中的方向v在坐标系1中是T(M1)*v;

*glTranslatef, glScalef, glRotatef是怎么回事(假设全用默认设置)
gl{Translate | Scale | Rotate}是“局部进行”的(performedlocally)。想象一下我们坐在某架飞机中,当接到“平移”和指令时,其平移的方向是在飞机的局部坐标系中指定的。同样,当接到“绕轴x旋转a角度”时,其x轴的方向也是局部坐标系中的方向。
简单的记忆方法是,因为上面三个转换都没有提供额外的信息,所以是局部的,因为局部的话不需要知道别的信息就行了。
所以,如果想让某个已经旋转了某个角度的东西绕着世界坐标系中的Y+轴旋转,glRotatef里面的轴就应该是T(M1) *(0, 1, 0)
又,如果现在有两个OpenGL指令
glTranslatef(0, 0, -10)
glRotatef(0, 1, 0, alpha)
作用在同一架飞机上
当先执行Translate,后执行Rotatef的时候,飞机会先向前飞10距离,然后绕自身的Y轴旋转alpha。当alpha增加时,我们能看到一架在(0,0, -10)原地打转的飞机。
当先执行Rotatef,后执行Translate的时候,飞机会先绕自身的Y轴旋转alpha,然后再向前飞10距离。当alpha增加时,我们能看到一架绕着一个半经为10的圆不停地转的飞机。飞机的机尾始终指向圆心。

*Ray picking
当用户在屏幕上点了一下,想选中某物体的时候,只需从视锥的顶点向屏幕上的某点发射一根射线,然后与所有物体求交点,就知道用户点了哪个物体了。
这根射线在裁剪空间中是由(0.5, 0.5, 0)射向(win_x, win_y,win_z)的。裁剪空间的所有
win_x与win_y是标准化后的坐标,其范围由ProjectionMatrix决定。win_z需要从深度缓冲中去取,要用到glReadPixels。
用gluUnProject可以将上述2点由裁剪空间反变换到世界坐标系中。gluUnProject需要知道Viewport、ModelView、Projection这三个矩阵,也就是基本上所有的变换所需的信息。变换完以后因为两点能确定一条射线,所以就能进行接下来的操作了。
0 0
原创粉丝点击