[转载]GLKit 矩阵变换:自转公转

版权声明:iTyran原创作品,谢绝转载!否则将追究法律责任。
在上一篇文章[iTyran原创]Xcode创建的默认iOSOpenGL ES 2.0 project代码分析中,
我跳过了- (void)update函数里面的矩阵变换分析,在这里我们来研究下这里干了些什么事情。

1.预备知识。
OpenGL ES 中有两套矩阵,都是4×4的GLfloat矩阵。一个叫modelview matrix ,你大部分时间都会与之打交道。它是你用来对虚拟世界进行变换的矩阵。要对虚拟世界中的物体进行旋转,转移或尺寸变化,你都需要对此矩阵进行修改。

另一个矩阵用来创建根据设定的视口(参考从零开始学习OpenGLES之三 – 透视)对世界坐标进行描述的二维表示。此矩阵称为 projection matrix 。在绝大部分时间内,你都不需要接触该矩阵。

一个3×3的矩阵可以描述绕任意轴旋转任何角度的情况。然而,为表示可能遇到的任何变换,我们仍然需要第四行/列。第四列用来保存变换信息,第四行用来表示透视变换。
至于第四行/列如何在矩阵变换中起到神奇的作用,那些令人你头痛的问题数学家门帮我们解决了。我们理解如何使用就好。

2.创建 projectionMatrix
视口矩阵使用GLKit是很简单的事情。

float aspect = fabsf(self.view.bounds.size.width /self.view.bounds.size.height);
GLKMatrix4 projectionMatrix =GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), 
aspect, 0.1f,100.0f);

首先是计算屏幕的宽高比aspect。我们的OpenGL ES程序是全屏的,所以这里直接使用self.view.bounds.size里面的值就能表示屏幕宽高。

GLKMatrix4MakePerspective有4个参数。
参数1:视角,要求输入幅度,GLKMathDegreesToRadians帮助我们把角度值转换为幅度。
参数2:算屏幕的宽高比,如果不正确设置,可能显示不出画面。
参数3:near,
参数4:far
near和far共同决定了可视深度,都必须为正值,near一般设为一个比较小的数,far必须大于near。

我们做个测试,把far值改为4,你会看到如下的效果。

你会发现正方体不能显示完全,有一部分看不到了。

3.baseModelViewMatrix公转
还记得笛卡尔坐标系吧,回顾下这里:http://ityran.com/article-3-1.html

GLKMatrix4 baseModelViewMatrix =GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);

观察gCubeVertexData数据,正方体是围绕原点展开的。这里把物体往-z方向移动4个单位。

baseModelViewMatrix =GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);

GLKMatrix4Rotate做矩阵旋转
它有5个参数:
参数1:传入矩阵,被变化的矩阵
参数2:旋转的角度。正值逆时针旋转。
参数3~5:共同组成一个向量,围绕这个向量做旋转。

这里我们还是做一个测试,把向量参数变成1.0f, 0.0f, 0.0f
这时候正方体将围绕x轴旋转。如下图:


4.modelViewMatrix 自转 + 公转
// -1.5f和shader2的1.5f间隔开一个距离

modelViewMatrix = GLKMatrix4MakeTranslation(0.0f,0.0f, -1.5f);

//自转

modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix,_rotation, 1.0f, 1.0f, 1.0f);

//公转自转作用在一起。

modelViewMatrix =GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);

SHADER_1通过下面的方式设置projectionMatrix和modelviewMatrix。

self.effect.transform.projectionMatrix =projectionMatrix;
self.effect.transform.modelviewMatrix = modelViewMatrix;

modelViewMatrix最终会和gCubeVertexData里面的每个点的position信息相乘,得出一个新的正方体坐标。

SHADER_2稍有不同,可编程着色器自己实现光线代码的计算,又多了些矩阵变换。

//GLKMatrix4GetMatrix3 upper-left 3x3 section of a4x4,左上角
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix),NULL);
_modelViewProjectionMatrix =GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);

具体这段代码如何结合Shader.vsh里面的代码实现的变化有待进一步研究。


由于OpenGL ES 2.0 对GLKit 的引入,使得矩阵变换更加简单。而Xcode创建的默认iOS OpenGL ES 2.0 project很好的展示了这些用法,是很值得学习的。

posted @ 2013-02-07 17:45  度娘818  阅读(1943)  评论(0编辑  收藏  举报