OpenGL ES 索引绘图

1,509 阅读2分钟

EBO即Element Buffer Objects,用来存储绘制物体的索引。所谓索引就是对顶点属性数组中元素的一个位置标记。使用索引绘图时,先通过顶点属性数组指定数据,然后利用指向这些数据的索引来指示OpenGL完成绘图。索引绘图主要是为了决绝顶点高度重叠的问题。使用索引绘图的原理如下图所示。 -w780 在左边图中,没有使用索引绘制矩形时,要重复指定重叠的顶点数据,V1和V2都重复了,使用了6个顶点属性数据;右边的图中,使用索引绘制时,只需要指定顶点在属性数组中的索引即可,使用0,1,2,3代表V0,V1,V2,V3顶点,绘制矩形一共指定了6个索引,使用4个顶点属性数据。

上面的例子可能看不出有大区别,但是当要绘制的物体包含多个重叠的顶点时,如果每个顶点属性包括了位置、颜色、纹理坐标、法向量等属性,那么将会造成很大的额外空间开销,影响GPU性能。同时,如果需要修改一个顶点处的数据,那么重复的顶点数据都要被改过来,这个工作也很无趣。因此,使用索引绘制能够节省存储空间,而且能灵活应对顶点属性的改变。 不使用索引也可以绘制矩形,我们使用6个顶点,数据如下:

GLfloat vertices[] = {
        // 第一个三角形
        -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
        0.5f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f,
        0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
        // 第二个三角形
        -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
        0.0f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f,
        0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
};

然后在绘制时更新顶点数目即可

glDrawArrays(GL_TRIANGLES, 0, 6);

下面介绍使用索引的绘制方法。我们需要在VBO中存储顶点属性数据,另一方面,就是使用EBO存储索引数据。我们重新指定顶点数据和索引数据如下:

// 指定顶点属性数据 顶点位置 颜色
GLfloat vertices[] = {
    -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 0
    0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,  // 1
    0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,  // 2
    0.0f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f  // 3
};
// 索引数据
GLshort indices[] = {
    0, 1, 2,  // 第一个三角形
    0, 3, 1   // 第二个三角形
};

创建EBO,并将索引数据传送到EBO,如下:

glGenBuffers(1, &EBOId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

使用索引绘图:

参数一:图元连接方式
参数二:索引个数
参数三:索引的数据类型
参数四:索引数据,可以直接将索引数组传递进来,也可以使用索引缓冲区,这里使用的是索引缓冲区
glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(indices[0]), GL_UNSIGNED_INT, 0);

运行结果如下图所示: -w827