zoukankan      html  css  js  c++  java
  • [转载]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很好的展示了这些用法,是很值得学习的。

  • 相关阅读:
    对数线性模型与线性链条件随机场
    25匹马,5个跑道,每个跑道最多能有1匹马进行比赛,最少比多少次能比出前3名?前5名?
    SVM 与 LR的异同
    EM算法简易推导
    K-means算法的优缺点
    自助采样包含训练集里63.2%的样本?
    指数加权移动平均
    oracle 对于用户的相关操作
    docker 安装 maven 私有库 nexus3
    idea 自动注入@Autowired 警告 Field injection is not recommended 关闭
  • 原文地址:https://www.cnblogs.com/PursuitOnly/p/2908883.html
Copyright © 2011-2022 走看看