美文网首页
OpenGL ES for Android 笔记

OpenGL ES for Android 笔记

作者: hjm1fb | 来源:发表于2017-09-16 16:48 被阅读68次

    矩阵运算的顺序

    调用Matrix.translateM时,执行的是
    Mvm * Ntran
    其中 Mvm 是ModelView矩阵,维度4X4,形式如下:


    Ntran 是平移矩阵

    对照着图,就不难理解Matrix.translateM方法执行的源代码列了。我们再执行Matrix.rotateM,结果是
    Mvm * Ntran* Nrotate
    这样得到的结果 Mresult 再与初始顶点坐标矩阵Mv相乘(左乘)就是
    Mv' = Mresult * Mv
    = Mvm * Ntran* Nrotate * Mv
    = Mvm * Ntran* (Nrotate * Mv
    所以实际结果是先旋转再平移,与代码写的顺序相反。

    坐标系Tip

    因为OpenGL中的视图坐标(观察者或者照相机的视角对应的坐标系)和笛卡尔坐标系都是右手坐标系统,而归一化设备坐标系对应的是左手坐标系统,为了对应起来,投影矩阵的Z值会有个负号。
    这样比如 Matrix.perspectiveM方法中的near far分别为1f, 10f。那么最后可见的Z值范围是 -1f~-10f。而默认的情况下Z值为0,所以为了让图形可见,需要执行类似

    Matrix.translateM(mModelMatrix, 0, 0.1f, 0f, -2.5f);
    

    的代码来移动Z值到范围内。

    纹理坐标以左下角为原点

    三维图形学,为什么使用四维矩阵?

    1. 为了能通过矩阵乘法实现平移变换
    2. 为了区别点和向量.第四维如果是1,表示一个点,如果是0,表示一个向量

    坐标系旋转

    使用的是视图坐标系(Z坐标箭头向外),并且遵循右手定则:
    右手手掌张开,除大拇指的四指向掌心握住,大拇指向所旋转的轴的正方向,四指旋转的方向就是正方向。
    比如

    Matrix.rotateM(mModelMatrix, 0, 30f, 0f, 0f, 1f);
    

    就相当于图形逆时针转了30度。

    纹理单元与纹理目标

    显卡中有N个纹理单元(具体数目依赖你的显卡能力),
    每个纹理单元(GL_TEXTURE0、GL_TEXTURE1等)都有GL_TEXTURE_1D、GL_TEXTURE_2D等纬度。
    openGL ES中只有GL_TEXTURE_2D。
    当执行以下代码

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);  
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId1);
    

    作用是将当前纹理单元0(GL_TEXTURE0)的GL_TEXTURE_2D绑定为纹理textureId,即赋值操作,当前纹理单元的GL_TEXTURE_2D成为了textureId1的别名。
    比如之后的

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
    

    就相当于是对textureId1的操作。如果要解绑的话,调用

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    

    但要掌握好时机,比如画完纹理再解绑。

    假设我的操作都在纹理单元0执行,那么以下代码没有任何副作用,因为是在纹理单元1执行,并且最后重新切换到了纹理单元0:

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
     GLES20.glActiveTexture(GLES20.GL_TEXTURE0);  
    

    相关文章

      网友评论

          本文标题:OpenGL ES for Android 笔记

          本文链接:https://www.haomeiwen.com/subject/ezfusxtx.html