OpenGL实践4之索引绘制
DionysosLai(906391500@qq.com)
引言:
之前我们绘图时,都是使用glDrawArrays函数,采用的是“序列绘图”(ordered draws)方式。今天,我们介绍另外一种绘图方式:“索引绘图”(index draws)。
“序列绘图”,顾名思义就是将顶点一个个按顺序排列存放在顶点缓存中。绘图时,我们按照组成图元顶点数量(点:一个顶点;线:两个顶点;三角形:三个顶点)一个个读取下来,并绘制形成图形。可以用下图表示出来:
如果我们是绘制三角形,且开始偏移为0,那么可以绘制123、456两个三角形。
“索引绘图”,顶点同样也是存放在顶点缓存中。但是在绘图过程中,顶点读取顺序并不是按照序列顺序读取,而是根据我们提供的顶点索引读取,比方我们要绘制一个三角形,我们可以用第3个、第5个、第2个这三个顶点组成。用下图表示如下:
如果我们是绘制三角形,那么是绘制352、647两个三角形。
从上面中,我们可以看出索引绘图方式比序列绘图方式优势地方,在于:不需要定义重复顶点信息,可以复用之前定义过的信息,这样可以大大减轻编码工作;对于内存访问非常有效率,因为大多数物体是由相似的三角形组成的,而且这些三角形有大量重复的顶点,这些重复顶点占用了同一块内存。
准备工作:
在OpenGL中,使用索引绘图,我们首先需要生产和绑定索引缓存,同时该缓存必须绑定顶点缓存上。另外,使用另一个绘图函数:
void glDrawElements (GLenum mode, GLsizeicount, GLenum type, const void *indices);
mode:绘图类型;
count:绘图顶点数量,该值为 绘制图元的数量 * 一个图元的顶点数
type :索引值的类型,只能是下列值之一:GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, orGL_UNSIGNED_INT。
indices:指向索引存贮位置的指针。
代码大纲:
/// 顶点坐标数据
GLfloatvertices[12] = {
-1.0f, 1.0f, 0.0f ,
-1.0f, -1.0f, 1.0f ,
1.0f, -1.0f, 0.0f ,
1.0f, 1.0f, 0.0f,
};
///缓存数据
GLuintvertexbuffer1;
glGenBuffers(1,&vertexbuffer1);
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer1);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW);
生成和绑定顶点缓存。这里我们生成了4个顶点,分别在上下左右四个位置。
///顶点索引数据
unsignedint Indices[] = { 0, 1, 2, 1, 2, 3 };
创建一块索引数组,这个数组值指向之前绑定的顶点缓存。
///缓存数据
glGenBuffers(1,&vertexbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vertexbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(Indices), Indices, GL_STATIC_DRAW);
生成和绑定索引缓存,注意跟之前不同的是,索引缓存使用的是GL_ELEMENT_ARRAY_BUFFER参数
voiddisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vertexbuffer);
glDrawElements(GL_TRIANGLES, 6,GL_UNSIGNED_INT, 0);
glutSwapBuffers();
glFlush();
}
在绘图之前,为了确保绑定的是顶点缓存,我们再次绑定索引缓存。同时使用函数glDrawElements,绘制两个三角形。绘制结果如下所示:
到目前为止,我们索引绘图教程就到此为止。下一章我们学习着色器中Uniform Variables内容。
最后祝大家工作愉快。代码下载:https://github.com/DionysosLai/OpenGL-Practice