(二)顶点数组
在OpenGL需要进行大量的函数调用才能完成对几何图元的渲染,比如绘制一个20条边的多边形至少需要22个函数调用。首先调用1次glBegin(),然后为每个顶点调用1次函数,最后调用1次glEnd()。这些函数开销可能会影响应用程序的性能。OpenGL提供了一些顶点数组函数,允许只用少数几个数组指定大量的与顶点相关的数据,并用少量函数调用这些数据。把数据放在顶点数组中可以提高应用程序的性能。使用顶点数组可以减少函数调用的次数,从而提高性能。另外,使用顶点数组还可以避免共享顶点的冗余处理。
使用顶点数组对几何图形进行渲染需要3个步骤:
1)激活(启用)数组
2)填充数组
3)使用数组的数据绘制几何图形
有代码有真像,代码如下:
#include <gl/glut.h>
void display(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
GLint glArray[]={200,300,
50,150,
50,150,
300,150,
300,150,
200,300
};
GLfloat colors[] = {1.0,0.2,0.2,
0.2,0.2,1.0,
0.8,1.0,0.2,
0.75,0.75,0.75,
0.35,0.35,0.35,
0.5,0.5,0.5
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2,GL_INT,0,glArray);
glColorPointer(3,GL_FLOAT,0,colors);
glBegin(GL_LINES);
glArrayElement(0);
glArrayElement(1);
glArrayElement(2);
glArrayElement(3);
glArrayElement(4);
glArrayElement(5);
glEnd();
glFlush();
}
void Reshape(int h,int w)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,w,0.0,h);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(400,400);
glutInitWindowPosition(100,100);
glutCreateWindow("顶点数组");
glutDisplayFunc(display);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}
运行结果如图:
要启用一个数组,我们可以调用glEnableClientState()函数来启用(激活),从理论上说,最多可能调用这个函数8次,激活8个可用的数组。但是在实践中,可以激活的数组最多只有6个,这是因为有些数组不能同时激活。例如:不能同时激活RGBA模式(颜色模式)和颜色索引模式。
如果现在你要禁用一种模式,相应的你可以调用glDisableClientState()函数
激活一个数组后,需要填充数组,然后我们要指定这个数组的数据,比如:上面的glArray顶点数组,我们就用OpenGL里的glVertexPointer来指定;如果是colors颜色数组,就用glColorPointer来指定。
最后Opengl引用数组里的数据进行图形渲染。glArrayElement函数就是用来引用数组里的数据的,它是解引用单个数组元素。
(三)跨距
我们在上面的程序中使用了两个数组,这里可以把两个数组合并成一个数组,然后通过使用跨距来访问。
我们修改上面的代码,如下:
void display2(void)
{
glClearColor(0.0,0.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat intertwined[]={
200,300,1.0,0.2,0.2,
50,150,0.2,0.2,1.0,
50,150,0.8,1.0,0.2,
300,150,0.75,0.75,0.75,
300,150,0.35,0.35,0.35,
200,300,0.5,0.5,0.5
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2,GL_FLOAT,5*sizeof(GL_FLOAT),intertwined);
glColorPointer(3,GL_FLOAT,5*sizeof(GL_FLOAT),&intertwined[2]);
glBegin(GL_LINES);
glArrayElement(0);
glArrayElement(1);
glArrayElement(2);
glArrayElement(3);
glArrayElement(4);
glArrayElement(5);
glEnd();
glFlush();
}
只需要用display2函数替换display函数就可以了,运行效果如下:
结果一样,只是背景换成了蓝色的背景。
除了用glArrayElement解引用单个数组元素外,OpenGL还提供了glDrawElement()函数对数组的一个列表进行引用,效果差不多
glBegin(mode)
for(int i=0; i< count; i++)
{
glArrayElement(i);
}
glEnd();
glDrawElement()使用之后,可能会使几个状态处于不稳定。而且要注意的是,使用glDrawElement()应放在glBegin和glEnd函数之外,不能放在其里面。