泰然

 找回密码
 注册泰然

[iTyran原创]GLKit 矩阵变换:自转公转

2011-12-17 17:16| 发布者: u0u0| 查看: 14192| 评论: 22|原作者: u0u0

摘要: Xcode创建的默认iOS OpenGL ES 2.0 project代码分析,GLKit 矩阵变换:自转公转

[iTyran原创]GLKit 矩阵变换:自转公转

作者:u0u0 - iTyran
版权声明: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很好的展示了这些用法,是很值得学习的。
7

鲜花

握手

雷人

路过

鸡蛋

刚表态过的朋友 (7 人)

发表评论

最新评论

引用 xmxueping 2014-1-29 12:08
来学习学习
引用 gywinner 2013-3-3 15:36
学习一下
引用 scottboy 2012-5-26 16:55
额,貌似运行起来有点问题
引用 kehaoran74 2012-3-7 20:22
有都奥利
引用 ale423 2012-2-22 23:36
学习
引用 halley 2012-2-19 14:25
哎,没心思学下去
引用 liaobuqide2 2012-2-19 12:23
hao dong xi!
引用 Android 2012-2-2 19:18
很不错哈~
引用 mark006002 2012-1-31 11:52
GOOD!!
引用 cl890305 2012-1-19 10:23
正在学习中
引用 go369 2012-1-18 01:04
又涨知识了,挺好的。
引用 Quinn 2012-1-11 11:22
向楼方主学习
引用 Jack_zer 2012-1-9 15:39
很好 学习了
引用 panzhiccp 2011-12-28 10:33
迟早用得上
引用 panzhiccp 2011-12-28 10:33
顶一个
引用 chichi1314 2011-12-28 04:08
simon tutorial is good as well
引用 chichi1314 2011-12-28 04:08
看着你这个 好像挺好的
引用 chichi1314 2011-12-28 04:08
我正向看看
引用 chichi1314 2011-12-28 04:07
学习了
引用 lucky 2011-12-26 13:25
看着你这个 好像挺好的

查看全部评论(22)

手机版|小黑屋|Archiver| 泰然论坛 ( 蜀ICP备13018980号-2 )

GMT+8, 2017-6-24 13:07 , Processed in 0.016078 second(s), 13 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

返回顶部