好的!下面我帮你梳理一份面向零基础的《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 环境和渲染。
  • 渲染流程:创建上下文 → 编写并编译着色器 → 传递顶点数据 → 调用绘制命令 → 显示结果。