openGL 坐标系

OpenGL 中场景进行变换,要经历一些过程:视图变换 à 模型变换 à 投影变换,然后到了窗口坐标。这几个变换开始的时候把我搞很混,这几天整理一下。

       一般书上把这几个变换用照相机类比,其实每个变换都是产生一个 4x4 矩阵,然后与当前矩阵(Current Matrix) 相乘,得到一个坐标变换矩阵,最后把世界坐标系(欧式空间)中的物体变换到屏幕坐标系中。这里梳理一下概念:

       1 、视图变换( VIEW Transformation ):它类似将照相机指向物体,即确定视点(观察点)的位置和观察方向。一般用的函数为 glu 封装的函数:

void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,  --------- 观察点

       GLdouble centrex, GLdouble centrey, GLdouble centrez,  -- 视线方向:从 eye 指向 centre

       GLdouble upx, GLdouble upy, GLdouble upz ------------ 视图体自下而上的方向

 )

       这个函数会产生一个视图矩阵,并右乘到当前矩阵上。模型变换通常发生在模型变换之前。其实,视图变换也是通过平移和旋转得到的,观察位置与物体位置之间是个相对的状态,我们也把视图变换和模型变换统一成一个变换,产生一个矩阵:模型视图变换矩阵。

       2 、模型变换 (MODEL Transformation) :它确定模型的位置和方向,对模型进行旋转、平移和缩放。用到三个子函数: glTranslate*(x, y, z) 、 glRotate*(x, y, z) 、 glScale*(x, y, z) 。每个函数都会产生一个矩阵,并右乘当前矩阵。

       3 、投影变换( PROJECTION Transformation ):产生一个六面的视图体,把视图体以外的场景剪裁掉,把视图体内的物体、场景作为绘制对象,让“照相机拍摄”。两种投影方式,两个投影函数:glFrustum(left, right, bottom, top, near, far) ,

glOrtho(left, right, bottom, top, near, far )

这两个函数的参数非常对称,都是构筑了一个六面体,形成可视范围。它们都产生一个矩阵,并左乘当前矩阵。(当然,还有 glu 的两个函数)。

      

       要理解整个过程,关键在理解当前变换矩阵 CTM ,(简称为 C )。它是一个状态概念,应用到 OpenGL流水线中的每一个定点: P = C*P’ 。这条等式是对同一个点在两个坐标系体统之间进行转换,从右边的坐标系下的坐标( P’ )转换到左边的坐标系下的坐标( P )。而矩阵 C 是 4x4 的齐次坐标矩阵,它都蕴含着一个局部坐标系信息:以右边坐标系为参考坐标系统,左边坐标系的位置和方向。

       用手工定义一个矩阵,如下(按 OpenGL 矩阵方式定义。与数学定义矩阵的方式转置):

       CTM[16] = { a0, a1, a2, a3,         // x 轴的方向向量

                        a4, a5, a6, a7,          // y 轴的方向向量

                        a8, a9, a10, a11,              // z 轴的方向向量

                        a12, a13, a14, a15    // 原点的位置

                            }

      

       再来考察当前变换矩阵 CTM ,它是在 OpenGL 流水线中一个模型视图矩阵和一个投影矩阵的复合。 CTM = P*C*M 。(注意到上面提到的左乘右乘了吗?)

我们来分析一个简单的例子: 见openGL 坐标系(2)

 

对 glRotatef(45.0, 0.0, 0.0, 1.0)   

glTranslatef(3.0, 0.0, 0.0);  

这两个变换,可以看成:

       glMultMatrixf(R);

       glMultMatrixf(T);

R,T 都是右乘到 CTM : CTM = CTM * R * T

对模型变换的理解有两种:

1、在全局固定坐标系下,对物体进行变换。这时候,我们要以相反的顺序来考虑代码中的变换函数了,它的实际过程是这样 P = CTM *( R*(T* p’)) 。

首先、对物体进行平移,平移到坐标( 3.0, 0.0, 0.0 )。  然后,把物体相对原点绕z轴旋转45度。

2、物体捆绑在局部坐标系下,所有的变换都是坐标系进行的。这时,我们用顺序来看这个变换。

glRotatef(45.0, 0.0, 0.0, 1.0) 产生一个齐次矩阵 R( 这可是代表一个局部坐标系哦 )   ,即局部坐标系 R 相对刚才开始的坐标系 I (单位矩阵)作了旋转变换,绕旋转了45度。

glTranslatef(3.0, 0.0, 0.0) 产生一个齐次矩阵 T (也是代表了一个局部坐标系),相对 R 坐标系沿x轴( R 系)平移了3个单位,得到了自己的局部坐标系 T 。

最后在这个局部坐标系 T 下画了 Cube 。

代码中的 Tmat = R * T ,它也是从 T 坐标系变换到 R 坐标系,再变换到最后的模型视图的世界坐标系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值