在绘制一些图形的时候比如正方体,正方体的顶点是有很多重合的,如果为每个顶点都分配内存那么就比较浪费内存了。
OpenGL通过索引缓冲对象来解决这个问题,做到重复的顶点只需要分配一次内存,再绘图的时候后通过EBO告诉GPU顶点的索引。
EBO即索引缓冲对象,这个对象里存的都是索引,索引的意义在于减少重复数据。
如果使用了EBO,那么绘图函数是GLDrawElements()函数。
GLDrawElements()函数使用通过索引到相应的顶点缓冲区去拿数据,如果绑定了VAO就到VAO里拿数据。
在绑定了VAO之后,后面绑定的EBO对象会成为VAO的一个元素。
EBO与VBO使用方式类似,先使用glGenBuffers创建EBO,再使用glBindBuffer绑定EBO,然后使用glBindBuffer传送数据,注意类型为GL_ELEMENT_ARRAY_BUFFER,绘图的时候使用glDrawElements函数。
/**************************/
unsigned int indices[] = { // 注意索引从0开始!
0, 1, 3, // 第一个三角形
1, 2, 3 // 第二个三角形
};
/**************************/
//创建VAO
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//创建VBO
glGenBuffers(1,&VBO);//生成VBO对象,同时用一个ID来唯一标识这个缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
//创建EBO
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//告诉OpenGL如何解析GPU缓存中的数据
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3* sizeof (float),(void*)0);
glEnableVertexAttribArray(0);
//解绑VAO VBO EBO
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
/**************************/
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);