通过上篇文章的学习,现在已经了解到,要想在 Android 端使用 OpenGL ES 绘制图形,必须创建 OpenGL ES 环境和视图窗口,具体来说就是构建 EGL 环境,即 OpenGL ES 和 Android 底层平台视窗系统之间的接口。另外 OpenGL ES 2.0 版本为可编程管线,我们就可以编写着色器程序来确定绘制内容,即编写 Vertex Shader 顶点着色器和 Fragment Shader 片元着色器。
而这些工作可以通过 GLSurfaceView 非常简单的实现。
在介绍 GLSurfaceView 之前先来看下 Android 系统提供的与 OpenGL ES 相关的包:
- javax.microedition.khronos.opengles: 存放 GL 绘图指令相关代码
- javax.microedition.khronos.egl: 存放 EGL 管理相关代码,包括 Display、surface 等
- android.opengl: 存放 GL 辅助类,连接 OpenGL 与 Android View,Activity 等
其中 GLSurfaceView 处于 android.opengl 包中,GLSurfaceView 具有以下特性:
- 内置 EGL 管理,自带 GL 上下文环境和 GLThread 绘制线程
- 起到连接 OpenGL ES 与 Android 的 View 层次结构之间的桥梁作用
- 使得 OpenGL ES 库适应于 Activity 生命周期
- 继承自 SurfaceView,拥有 SurfaceView 的全部特性,绘制结果会输出到 SurfaceView 所提供的 Surface 上
- 提供了方便使用的调试工具来跟踪 OpenGL ES 函数调用以帮助检查错误
通过 GLSurfaceView 的 setRenderer 方法可设置要渲染的效果,即 GLSurfaceView.Renderer 渲染器接口,该接口方法:
- onSurfaceCreated:渲染线程开启时调用,可做初始化背景色、初始化纹理资源等工作
- onSurfaceChanged:窗口尺寸改变时调用,通常会设置视窗范围或投影矩阵等
- onDrawFrame:外部请求渲染一次就调用一次,可在此载入着色器程序、激活绑定纹理以及调用绘制
下面来看具体如何绘制一个三角形:
public class Triangle implements GLSurfaceView.Renderer {
//顶点着色器
private static final String vertexShaderResource =
"attribute vec3 vPosition;" +
"void main() {" +
" gl_Position = vec4(vPosition.x, vPosition.y, vPosition.z, 1.0);" +
"}";
//片段着色器
private static final String fragmentShaderResource =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
//顶点
private final float[] vertexCoords = new float[]{
0.0f, 0.5f, 0.0f, // top
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f // bottom right
};
private final float color[] = {
1.0f, 0f, 0f, 1.0f}; //red
// 着色器程序
private int mProgram;
// 顶点坐标数据
private FloatBuffer vertexFloatBuffer;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//设置清空屏幕后的背景色
GLES30.glClearColor(0.5f,