Android OpenGL ES 完整教程
本教程将分为以下几个部分:

-
第一部分:基础知识与环境搭建
- 什么是 OpenGL ES?
- 为什么在 Android 上使用 OpenGL ES?
- 开发环境准备
- 创建第一个 OpenGL ES 项目 (Hello Triangle)
-
第二部分:深入理解渲染管线
- OpenGL ES 渲染管线简介
- 顶点着色器 与 片段着色器
- 着色器语言 基础
-
第三部分:绘制第一个 3D 物体
- 3D 坐标系统 与 变换
- 矩阵与变换 (模型、视图、投影矩阵)
- 在 Android 中实现矩阵变换
-
第四部分:进阶主题
(图片来源网络,侵删)- 纹理映射
- 深度测试
- 交互与动画
-
第五部分:学习资源与最佳实践
第一部分:基础知识与环境搭建
什么是 OpenGL ES?
- OpenGL (Open Graphics Library): 是一个跨语言、跨平台的图形 API,用于渲染 2D 和 3D 矢量图形。
- ES (Embedded Systems): 是 OpenGL 的一个子集,专门为嵌入式系统(如手机、平板)设计,它去除了许多桌面 OpenGL 中不必要的复杂功能,更适合移动设备的硬件和性能。
- 版本: Android 主要支持 OpenGL ES 2.0, 3.0, 3.1 和 3.2。本教程将以 OpenGL ES 2.0 为基础,因为它兼容性最好,且足以理解核心概念,新版本主要增加了更多可编程管线功能和性能优化。
为什么在 Android 上使用 OpenGL ES?
- 高性能: 对于复杂的 2D/3D 图形,使用 OpenGL ES 可以直接利用 GPU 进行并行计算,性能远超传统的
Canvas绘图。 - 游戏开发: 几乎所有 Android 3D 游戏都基于 OpenGL ES 或其高级封装(如 Unity, LibGDX)。
- 视觉效果: 可以实现复杂的视觉效果,如滤镜、实时渲染、AR/VR 等。
开发环境准备
- 安装 Android Studio: 这是官方推荐的 IDE。
- 安装 SDK: 确保在 SDK Manager 中安装了最新的 Android SDK 和 NDK(Native Development Kit,虽然我们先用 Java/Kotlin,但了解有好处)。
- 创建新项目: 选择 "Empty Activity" 模板。
创建第一个 OpenGL ES 项目 (Hello Triangle)
我们将创建一个最简单的 OpenGL ES 应用,在屏幕上绘制一个彩色三角形。
步骤 1: 添加 OpenGL ES 依赖
在 build.gradle (Module: app) 文件中,确保你有 OpenGL ES 的依赖。glide 或其他库会间接引入它,但最好明确一下。

dependencies {
// ... 其他依赖
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// 确保有 OpenGL ES 的库支持
// 通常不需要手动添加,但知道它存在很重要
}
步骤 2: 创建 GLSurfaceView
GLSurfaceView 是 Android 中用于显示 OpenGL ES 图形的专用视图。
- 在
activity_main.xml中添加GLSurfaceView:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.opengl.GLSurfaceView
android:id="@+id/gl_surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
步骤 3: 配置 GLSurfaceView
在 MainActivity.java 中设置 GLSurfaceView。
public class MainActivity extends AppCompatActivity {
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
glSurfaceView = findViewById(R.id.gl_surface_view);
// 设置 OpenGL ES 版本
glSurfaceView.setEGLContextClientVersion(2); // 使用 OpenGL ES 2.0
// 设置渲染器
glSurfaceView.setRenderer(new MyGLRenderer());
// 设置渲染模式:只在需要时渲染(当数据变化时)
// GLSurfaceView.RENDERMODE_WHEN_DIRTY 是性能优化的关键
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
}
步骤 4: 创建渲染器
渲染器是 OpenGL ES 应用的核心,它负责所有的绘图操作,我们需要实现 GLSurfaceView.Renderer 接口。
创建一个新类 MyGLRenderer.java:
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MyGLRenderer implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 当 surface 被创建时调用
// 设置清屏色为黑色
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 当 surface 的大小改变时调用(屏幕旋转)
gl.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
// 每一帧绘制时调用
// 清除颜色缓冲区
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
}
}
现在运行程序,你应该会看到一个黑色的屏幕,这很好,因为我们已经成功设置了 OpenGL ES 环境。
步骤 5: 绘制三角形
要绘制图形,我们需要使用 着色器,着色器是运行在 GPU 上的小程序。
- 顶点着色器: 定义顶点的位置、颜色等属性。
- 片段着色器: 定义每个像素(片段)的颜色。
创建着色器代码 (字符串形式)
在 MyGLRenderer 中添加:
// 顶点着色器的代码
private final String vertexShaderCode =
"attribute vec4 vPosition;" // 顶点位置属性
+ "void main() {"
+ " gl_Position = vPosition;" // 设置最终位置
+ "}";
// 片段着色器的代码
private final String fragmentShaderCode =
"precision mediump float;" // 设置精度
+ "uniform vec4 vColor;" // 颜色属性
+ "void main() {"
+ " gl_FragColor = vColor;" // 设置片段颜色
+ "}";
加载并编译着色器
我们需要将着色器代码加载到 GPU 并编译成可执行程序。
private int loadShader(int type, String shaderCode) {
// 创建着色器对象
int shader = GLES20.glCreateShader(type);
// 将源码加载到着色器对象中并编译
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
创建并链接着色器程序
一个完整的渲染过程需要将顶点着色器和片段着色器链接成一个 程序。
在 MyGLRenderer 中添加成员变量和 onSurfaceCreated 中的初始化代码:
private int mProgram; // 着色器程序
// 三角形的顶点坐标 (逆时针顺序)
static float[] triangleCoords = {
0.0f, 0.5f, 0.0f, // 顶点1
-0.5f, -0.5f, 0.0f, // 顶点2
0.5f, -0.5f, 0.0f // 顶点3
};
// 设置颜色为红色
float[] color = { 1.0f, 0.0f, 0.0f, 1.0f 