OpenGL ES for Android 笔记

矩阵运算的顺序

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

OpenGL ES for Android 笔记_第1张图片

N tran 是平移矩阵
OpenGL ES for Android 笔记_第2张图片

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

坐标系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 笔记)