Android OpenGL ES 6.索引法绘制

前言

之前我们绘制的都是一些简单的基础图形,本章节我们绘制一个复杂些的形状,如下。

《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. 顶点数据过多,代码的可读性降低,需要隔几行就注释一下
  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,方法参数分别是

  1. 图形绘制方式
  2. 绘制的顶点数
  3. 索引的数据格式
  4. 索引的数据Buffer

这里再回顾下顶点法的绘制方法GLES20.glDrawArrays,方法参数分别是

  1. 图形绘制方式
  2. 从顶点数据读取数据的起点位置(以点作为单位,而非向量)
  3. 绘制的顶点数

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教程规划

    原文作者:Benhero
    原文地址: https://www.jianshu.com/p/92c12166a935
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞