废话不多说,我们先看一个知识点,那就是glDrawElements函数。
该函数的原型是:
void glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid *indices);
函数作用:使用count个元素定义一个几何序列,这些元素的索引值保存在indices数组中。
mode:接受的值和在glBegin()中接受的值一样,可以是GL_POLYGON、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_LINE_STRIP等。
count:组合几何图形的元素的个数,一般是点的个数。
type:indeices数组的数据类型,既然是索引,一般是整型的。
indices:索引数组
例子:
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
//四个顶点
float pfVer[] = { 0.0f, 0.0f, 0.0f,
2.0f, 0.0f, 0.0f,
2.0f, 2.0f, 0.0f,
0.0f, 2.0f, 0.0f };
//两个面
short indices[] = {0,1,2,
2,3,0 };
glEnableClientState(GL_VERTEX_ARRAY);//启用顶点数组,很重要,否则不显示
//参数1:表示该pfVer数组中几个元素表示一个点,这里是三维点,当然是3个数据表示一个点
//参数2:指示pfVer数组中元素的数据类型
//参数3:表示跨度,这里为0,表示数据元素没有跨度,即依次每3个元素表示一个点
//参数4:顶点数据数组
glVertexPointer( 3,GL_FLOAT, 0, pfVer ); //指定顶点指针,必须的,指向真正的点数据
//这个函数的参数列表前面已经解释过了。我们重点看下,第二个参数,即要画的几何图形的顶点的个数,这里因为要画2个面,每个面3个顶点,所以是6个。
//最后一个参数,传递是indices ,如果传递&indices[0]、&indices[1]会怎样?看下面的分析。
glDrawElements( GL_TRIANGLE_STRIP,2*3,GL_UNSIGNED_SHORT, indices );
glutSwapBuffers();
}
首先,上面代码的执行效果如下:
[外链图片转存中…(img-LNAUZGYx-1651190779680)]
1、如果我们将glDrawElements的最后一个参数改成&indices[0],结果会怎么样?
结果和上面一样,因为indices[0]的地址&indices[0]和数组地址indices是一样的嘛。这个学过C语言的都知道。
2、如果改成&indices[1]呢?
看下运行结果:
[外链图片转存中…(img-hkoYdlxO-1651190779681)]
我的运气比较好,第一次就出来结果了,你运行的话,可能第一次会报错,再运行可能还会报错,多运行几次就出来结果了。
glDrawElements( GL_TRIANGLE_STRIP,2*3,GL_UNSIGNED_SHORT, &indices[1] );
其实上面的代码是错误的,第二个参数指示的是6个顶点,而最后一个参数表示索引是从索引数组的第二个开始,那么后面只有5个顶点,根本不够6个,所以你运行出来已经很不错了。如果你把前面的6改成5,即:
glDrawElements( GL_TRIANGLE_STRIP,5,GL_UNSIGNED_SHORT, &indices[1] );
这样的话,代码是没有错误的,所以你不管怎么运行都不会报错,因为从索引数组的第二个元素开始的确只有5个顶点,前面第二个参数指定的参数也是5个顶点,所以,代码是完全正确的。
下面我们分析下结果,你会发现,因为我们画的是三角形,5个点是不够画2个三角形的,因为不能看到glDrawElements内部的实现,我只能根据结果猜测函数内部只根据最后3个顶点画了一个三角形,而舍去了前2个顶点。这只是我的猜测,希望知道原因的各位看官不吝指教。