Android OpenGL ES 6.索引法绘制
前言
之前我们绘制的都是一些简单的基础图形,本章节我们绘制一个复杂些的形状,如下。
索引绘制图中的数字是后期标注,并非GL绘制。
根据之前学的知识,我们知道,这个图形可以分解为4个三角形,用数字代表顶点序号,分别是
- 0, 1, 2
- 0, 2, 3
- 0, 4, 1
- 3, 2, 5
在程序中,每个顶点对应x、y坐标,那么我们的顶点数组数据就需要如下声明:
private static final float[] POINT_DATA = {
// 0, 1, 2
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
// 0, 2, 3
-0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f,
// 0, 4, 1
-0.5f, -0.5f,
0f, -1.0f,
0.5f, -0.5f,
// 3, 2, 5
-0.5f, 0.5f,
0.5f, 0.5f,
0f, 1.0f,
};
所以,实际声明的顶点数是4 * 3 = 12个顶点。而其中有很多顶点是可以重复的,这导致2个问题:
- 顶点数据过多,代码的可读性降低,需要隔几行就注释一下
- 有重复的顶点数据,造成了内存的浪费
这种绘制方式,叫顶点法绘制。
而本章节会引入一个新的技巧:索引法绘制。
代码实现
1. 定义坐标、索引
/**
* 顶点数据
*/
private static final float[] POINT_DATA = {
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f,
0f, -1.0f,
0f, 1.0f,
};
/**
* 数组绘制的索引:当前是绘制三角形,所以是3个元素构成一个绘制顺序
*/
private static final short[] VERTEX_INDEX = {
0, 1, 2,
0, 2, 3,
0, 4, 1,
3, 2, 5};
这里第一个float类型的数组,定义了每个顶点的坐标位置。
第二个数组是short类型的,定义了上一个数组的绘制顺序。也就是0代表着POINT_DATA数组的第0组的数据(-0.5f, -0.5f)。再解释下,之后我们会声明为2个点为一个顶点,所以索引0并非表示第0位的POINT_DATA[0],而是第0组。
2. 绘制图形
@Override
public void onDrawFrame(GL10 glUnused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// 1. 绘制模式; 2. 从数组中读取的数据长度; 3. 加载的数据格式; 4. 读取的数据缓冲区
GLES20.glDrawElements(GLES20.GL_TRIANGLES, VERTEX_INDEX.length,
GLES20.GL_UNSIGNED_SHORT, mVertexIndexBuffer);
}
这里使用到了一个新的方法GLES20.glDrawElements,方法参数分别是
- 图形绘制方式
- 绘制的顶点数
- 索引的数据格式
- 索引的数据Buffer
这里再回顾下顶点法的绘制方法GLES20.glDrawArrays,方法参数分别是
- 图形绘制方式
- 从顶点数据读取数据的起点位置(以点作为单位,而非向量)
- 绘制的顶点数
3. 顶点法、索引法的比较
按照索引的数据声明方式,代码的可读性大大地提高,那么性能上有多大提升呢?
首先,我们知道GL中,一个Float类型的数据占4个Byte,一个Short类型的占2个Byte。
那么在前言中声明的12个顶点的方式,也就是顶点法绘制方式,占的内存空间是:
12(顶点数) * 2(x、y两个向量为一组) * 4(Float格式占的Byte字节) = 96字节
而索引法的占的内存空间是:
6(顶点数) * 2(x、y两个向量为一组) * 4(Float格式占的Byte字节) + 12(索引数) * 2(Short格式占的Byte字节) = 48 + 24 = 72字节
本章节绘制的图形顶点属性比较单一,只有顶点位置,假若包含了颜色等其他顶点信息,那么顶点法占的内存将更大。
归纳下两种绘制方式的对比情况。
绘制方式 | 适用场景 | 可读性 | 内存计算方式 |
---|---|---|---|
顶点法 | 顶点复用情况少 | 低 | 顶点数 * 顶点属性数 * 顶点数据格式类型 |
索引法 | 顶点复用情况多 | 高 | 顶点数 * 顶点属性数 * 顶点数据格式类型 + 索引数 * 索引数据格式类型 |
参考
见Android OpenGL ES学习资料所列举的博客、资料。
GitHub代码工程
本系列课程所有相关代码请参考我的GitHub项目GLStudio。
课程目录
本系列课程目录详见 简书 - Android OpenGL ES教程规划