索引缓冲对象
这是对上一篇博客的补充
上一篇讲了OpenGL中的顶点数组对象(Vertex Array Object,VAO)和顶点缓冲对象(Vertex Buffer Object,VBO)。并绘制了三角形。现在将用索引缓冲对象(Element Buffer Object,EBO)进行图形的绘制。
通过上一篇的知识,当我们要绘制一个矩形时,其实是要绘制两个三角形(其中有两个点是重复的)所以,我们的顶点数据是这样的。
float vertices[] = {
// 第一个三角形
0.5f, 0.5f, 0.0f, // 右上角
0.5f, -0.5f, 0.0f, // 右下角
-0.5f, 0.5f, 0.0f, // 左上角
// 第二个三角形
0.5f, -0.5f, 0.0f, // 右下角
-0.5f, -0.5f, 0.0f, // 左下角
-0.5f, 0.5f, 0.0f // 左上角
};
绘制的时候改一下参数就行
glDrawArrays(GL_TRIANGLES, 0, 6);
这么写显然很麻烦, 而且相同的数据会被重复储存, 这会产生一大堆浪费。更好的解决方案是只储存不同的顶点,并设定绘制这些顶点的顺序。这样子我们只要储存4个顶点就能绘制矩形了,之后只要指定绘制的顺序就行了。
所以我们就要使用索引缓冲对象。
//四个点的数据
float vertices[] = {
-0.5f, -0.5f, 0.0f, //0
0.5f, -0.5f, 0.0f, //1
0.0f, 0.5f, 0.0f, //2
0.8f, 0.8f, 0.8f //3
};
//索引数据
unsigned int indices[] = {
0, 1, 2, //第一个三角形
2, 1, 3 //第二个三角形
};
现在我们需要创建索引缓冲对象:
unsigned int EBO;
glGenBuffers(1, &EBO);
然后又是熟悉的绑定和把索引复制到缓冲区内
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
只不过这次我们把缓冲的类型定义为GL_ELEMENT_ARRAY_BUFFER。
我们传递了GL_ELEMENT_ARRAY_BUFFER当作缓冲目标。最后一件要做的事是用glDrawElements来替换glDrawArrays函数,来指明我们从索引缓冲渲染。使用glDrawElements时,我们会使用当前绑定的索引缓冲对象中的索引进行绘制:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
- 第一个参数指定了我们绘制的模式,这个和glDrawArrays的一样。
- 第二个参数是我们打算绘制顶点的个数,这里填6,也就是说我们一共需要绘制6个顶点。
- 第三个参数是索引的类型,这里是GL_UNSIGNED_INT。
- 最后一个参数里我们可以指定EBO中的偏移量,但是我们会在这里填写0。