- 投影Projection - 投影转换是根据所绘制对象所在GLSurfaceView的宽高来调整绘制对象的坐标。若不做投影计算,所绘对象就会因view窗口的不等比例而被歪曲。投影转换的计算一般只应发生在OpenGL view的宽高比已被建立或改变时,在渲染器的onSurfaceChanged()方法中。关于OpenGL ES投影和坐标映射的更多内容,请看 Mapping Coordinates for Drawn Objects.
- 摄像机视角Camera View - 这种转换会根据一个虚拟的摄像机方位对绘制对象的坐标进行调整。值得注意的是:OpenGL ES并非真正的定义一个摄像机对象,而是提供一系列工具方法通过转换绘制对象的显示来模拟一个摄像机。摄像机视角仅在建立GLSurfaceView时被计算一次,也可能根据用户动作或app的功能而动态的改变。
本节课讲解如何创建一个投影和摄像机视角并将其应用到GLSurfaceView中的绘制对象上。
定义一个投影
一个投影转换的数据是在你的GLSurfaceView.Renderer类的onSurfaceChanged()方法中计算的。下面的示例代码获取了GLSurfaceView的宽和高,然后调用Matrix.FrustumM()方法将数值填充到一个投影转换矩阵Matrix:The data for a projection transformation is calculated in the onSurfaceChanged()
method of yourGLSurfaceView.Renderer
class. The following example code takes the height and width of the GLSurfaceView
and uses it to populate a projection transformation Matrix
using the Matrix.frustumM()
method:
@Override public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); float ratio = (float) width / height; // 投影矩阵matrix应用于绘制对象坐标 // 在onDrawFrame()方法中 Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); }
这段代码填充了一个投影matrix,mProjMatrix,可以在onDrawFrame()方法中结合摄像机视角转换使用,这将在下一部分讲到。
注意: 只把一个投影转换作用于绘制对象上一般会导致显示很空。一般情况下,你必须同时也使用摄像机视角转换。
定义一个摄像机视角
通过添加摄像机视角转换作为绘制流程的一部分来完成对绘制对象进行转换的流程吧。在如下所示的示例代码中,摄像机视角转换的计算是使用Matrix.setLookAtM()方法,然后与前面计算出的投影matrix相组合。最后组合出的转换矩阵然后被传递给绘制对象。
@Override public void onDrawFrame(GL10 unused) { ... // 设置摄像机视角位置(View matrix) Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // 计算投影与视角转换 Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); // Draw shape mTriangle.draw(mMVPMatrix); }
使用投影和摄像机视角转换
为了使用投影与摄像机视角组合转换矩阵,修改绘制对象的draw()方法以接收组合转换矩阵,并将其应用到形状上。
public void draw(float[] mvpMatrix) { // 传入转换矩阵 ... // 获取shape的转换矩阵的句柄 mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); // 应用投影和视角转换 GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); // 绘制三角形 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); ... }
只要正确的计算并应用了投影和摄像机视角转换,所绘制的对象就会以正确的比例显示:
图 1. 应用了投影和摄像机视角转换的三角形
既然你的app已经正确的显示了图形,下一步就是给图形添加动作。