参考ChatGpt de 回答理解
函数说明:
void glDrawArrays(GLenum mode,GLint first,GLsizei count);
mode:表示绘制的基本图元类型,常用的有GL_POINTS(绘制单独的点)、GL_LINES(绘制单独的线段)、GL_TRIANGLES(绘制三角形)等。
first:表示要绘制的顶点数组的起始位置。
count:表示要绘制的顶点数量。
案例
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
其中,vertices是一个包含三个顶点的数组,每个顶点由三个GLfloat类型的数值表示。glVertexAttribPointer函数指定了顶点数组的属性,这里将顶点坐标属性设置为0。glEnableVertexAttribArray函数启用顶点属性数组。最后,glDrawArrays函数根据顶点数组绘制一个三角形。
void glDrawElements( GLenum mode,GLsizei count,GLenum type,const GLvoid * indices);
mode:表示绘制的基本图元类型,常用的有GL_POINTS(绘制单独的点)、GL_LINES(绘制单独的线段)、GL_TRIANGLES(绘制三角形)等。
count:表示要绘制的顶点数量。
type:表示索引数组中元素的数据类型,如GL_UNSIGNED_BYTE(无符号字节)、GL_UNSIGNED_SHORT(无符号短整型)等。
indices:表示索引数组的起始位置。
案例:
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
GLuint indices[] = {
0, 1, 2
};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
其中,vertices是一个包含三个顶点的数组,每个顶点由三个GLfloat类型的数值表示。indices是一个包含三个索引的数组,表示绘制三角形时使用的顶点的顺序。glVertexAttribPointer函数指定了顶点数组的属性,这里将顶点坐标属性设置为0。glEnableVertexAttribArray函数启用顶点属性数组。最后,glDrawElements函数根据顶点数组和索引数组绘制一个三角形。
具体区别:(chatgpt 的回答 比一般的博客回答的要好)
具体来说,glDrawArrays和glDrawElements之间的区别包括以下几个方面:
数据组织方式:glDrawArrays函数使用一个连续的顶点数组来描述几何形状,而glDrawElements函数使用一个索引数组来描述几何形状,其中索引数组中的元素表示顶点数组中的索引。
内存使用:由于glDrawArrays函数使用一个连续的顶点数组,因此它需要更多的内存来存储数据,而glDrawElements函数使用索引数组来描述几何形状,可以通过重复使用相同的顶点来减少内存使用和数据传输。
数据传输:由于glDrawArrays函数使用一个连续的顶点数组,因此它需要更多的数据传输,而glDrawElements函数使用索引数组来描述几何形状,可以通过重复使用相同的顶点来减少数据传输。
精度:由于glDrawArrays函数使用一个连续的顶点数组,因此它可以提供更高的精度,而glDrawElements函数使用索引数组来描述几何形状,可能会因为索引数组中的浮点精度损失而导致绘制精度下降。
顶点复用:由于glDrawElements函数使用索引数组来描述几何形状,因此它可以通过重复使用相同的顶点来优化几何形状的绘制。相比之下,glDrawArrays函数需要在顶点数组中提供每个顶点的所有信息,无法进行顶点复用。
综上所述,glDrawArrays和glDrawElements两个函数的具体区别在于数据组织方式、内存使用、数据传输、精度以及顶点复用等方面。开发者可以根据具体的需求来选择使用哪个函数。