好的!下面我帮你梳理一份面向零基础的《OpenGLES Android篇(1)》教程,重点讲解 OpenGL ES 2.x 在 Android 平台上可渲染管线的基本流程,并配合关键代码示例,帮助你快速理解和入门。
OpenGLES Android篇零基础系列(一):OpenGLES 2.x 可渲染管线基本流程
一、什么是 OpenGL ES 2.x?
- OpenGL ES 是专为嵌入式系统(手机、平板等)设计的 3D 图形 API。
- 2.x 版本是第一个完全基于可编程管线(Shader)的版本,不支持固定管线。
- 你需要自己编写顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)来控制图形渲染流程。
二、OpenGL ES 2.x 渲染管线基本流程
在 Android 中,OpenGL ES 2.x 渲染流程主要包括以下步骤:
步骤 | 说明 |
---|---|
1. 初始化环境 | 创建 GLContext 和 Surface(通过 GLSurfaceView 或自定义) |
2. 编写着色器 | 编写顶点着色器和片段着色器程序,描述顶点变换和颜色计算 |
3. 编译着色器 | 编译顶点和片段着色器,创建着色器程序 |
4. 传入顶点数据 | 通过 VBO、顶点属性指针传入顶点坐标、颜色、纹理坐标等数据 |
5. 使用着色器 | 使用编译好的程序,启用顶点属性 |
6. 绘制调用 | 调用 glDrawArrays 或 glDrawElements 进行绘制 |
7. 显示渲染结果 | 交换缓冲区,显示渲染画面 |
三、Android 开发中的常用类
- GLSurfaceView:封装了 Surface 和渲染线程,方便管理 OpenGL 渲染。
- GLSurfaceView.Renderer:实现此接口,重写渲染相关方法。
四、关键代码示例(最简三角形渲染)
1. GLSurfaceView 初始化
public class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context) {
super(context);
// 创建 OpenGL ES 2.0 上下文
setEGLContextClientVersion(2);
// 设置渲染器
setRenderer(new MyRenderer());
// 设置渲染模式,按需渲染
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
2. 实现 Renderer 接口
public class MyRenderer implements GLSurfaceView.Renderer {
private int program;
private int positionHandle;
// 顶点数据:三角形三个顶点(x,y,z)
private final float[] vertices = {
0.0f, 0.5f, 0.0f, // 顶点1
-0.5f, -0.5f, 0.0f, // 顶点2
0.5f, -0.5f, 0.0f // 顶点3
};
private FloatBuffer vertexBuffer;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 初始化顶点缓冲区
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// 编译顶点着色器和片段着色器
String vertexShaderCode =
"attribute vec4 aPosition;" +
"void main() {" +
" gl_Position = aPosition;" +
"}";
String fragmentShaderCode =
"precision mediump float;" +
"void main() {" +
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" + // 红色
"}";
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
// 创建程序并链接
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
GLES20.glClearColor(0f, 0f, 0f, 1f); // 设置清屏颜色为黑色
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 设置视口大小
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // 清屏
GLES20.glUseProgram(program); // 使用着色器程序
// 获取顶点属性位置
positionHandle = GLES20.glGetAttribLocation(program, "aPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
// 传入顶点数据
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
// 绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
GLES20.glDisableVertexAttribArray(positionHandle);
}
// 辅助方法:编译着色器
private int loadShader(int type, String shaderCode){
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
五、总结
- OpenGL ES 2.x 渲染管线基于顶点着色器和片段着色器的可编程管线。
- Android 中推荐使用 GLSurfaceView + Renderer 模式来管理 OpenGL 环境和渲染。
- 渲染流程:创建上下文 → 编写并编译着色器 → 传递顶点数据 → 调用绘制命令 → 显示结果。
发表回复