显示列表是一组存储在一起的OpenGL函数,可以在以后执行。(目的的存储值,那么就不用每次再计算,达到了优化的目的)
分配显示列表索引值
使用glGenLists来生成一个或多个未使用的索引值
创建显示列表
以glNewList开始并以glEndList结束
如下示例
GLuint listName; static void init (void) { listName = glGenLists (1); glNewList (listName, GL_COMPILE); glColor3f (1.0, 0.0, 0.0); /* current color red */ glBegin (GL_TRIANGLES); glVertex2f (0.0, 0.0); glVertex2f (1.0, 0.0); glVertex2f (0.0, 1.0); glEnd (); glTranslatef (1.5, 0.0, 0.0); /* move position */ glEndList (); glShadeModel (GL_FLAT); } static void drawLine (void) { glBegin (GL_LINES); glVertex2f (0.0, 0.5); glVertex2f (15.0, 0.5); glEnd (); } void display(void) { GLuint i; glClear (GL_COLOR_BUFFER_BIT); glColor3f (0.0, 1.0, 0.0); /* current color green */ for (i = 0; i < 10; i++) /* draw 10 triangles */ glCallList (listName); drawLine (); /* is this line green? NO! */ /* where is the line drawn? */ glFlush (); }注意点:
- 显示列表中的值不能在以后进行修改
- 但可以删除整个列表然后创建一个新的
调用显示列表
使用glCallList 来调用显示列表
显示列表的存储
只有表达式的值存储在显示列表中,看上面注意点的第1点,即使修改也无效
GLfloat color_vector[3] = {0.0, 0.0, 0.0}; glNewList(1, GL_COMPILE); glColor3fv(color_vector); glEndList(); color_vector[0] = 1.0;
如上,数组的修改并不会影响显示列表
并非所有的OpenGL函数都可以存储在显示列表中并执行,使用glNewList创建的一个显示列表后,房子其他显示列表内部则会出错.
创建多个列表
如果要创建多个列表同样还是需要glNewList和glEndList函数,如下
glNewList(1,GL_COMPILE); glVertex3fv(v1); glEndList(); glNewList(2,GL_COMPILE); glVertex3fv(v2); glEndList(); glNewList(3,GL_COMPILE); glVertex3fv(v3); glEndList();
在列表中调用列表
glNewList(4,GL_COMPILE); glBegin(GL_POLYGON); glCallList(1); glCallList(2); glCallList(3); glEnd(); glEndList();
这里需要小心的发生递归
管理显示列表索引
可以用GLboolean glIsList(GLuint list)函数来判断索引值是否存在
删除显示列表:调用glDeleteLists函数可以删除多个显示列表,从索引值开始
执行多个连续显示列表
先用glListBase指定一个偏移量,然后以其为即地址,创建多个显示列表
base = glGenLists (128); glListBase(base); glNewList(base+'A', GL_COMPILE); drawLetter(Adata); glEndList(); glNewList(base+'E', GL_COMPILE); drawLetter(Edata); glEndList(); glNewList(base+'P', GL_COMPILE); drawLetter(Pdata); glEndList(); glNewList(base+'R', GL_COMPILE); drawLetter(Rdata); glEndList(); glNewList(base+'S', GL_COMPILE); drawLetter(Sdata); glEndList(); glNewList(base+' ', GL_COMPILE); glTranslatef(8.0, 0.0, 0.0); glEndList();
然后调用glCallLists
static void printStrokedString(char *s) { GLsizei len = strlen(s); glCallLists(len, GL_BYTE, (GLbyte *)s); }
状态变量管理
如下代码
glNewList(listIndex,GL_COMPILE); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0); glVertex2f(0.0, 1.0); glEnd(); glTranslatef(1.5, 0.0, 0.0); glEndList(); glCallList(listIndex); glBegin(GL_LINES); glVertex2f(2.0,-1.0); glVertex2f(1.0, 0.0); glEnd();
在调用显示列表后,当前的颜色将被改变,有时候我们并不想在执行显示列表的时候更改状态,之前我们用过一组glPushMatrix和glPopMatrix的函数,变量也可以,可以调用glPushAttrib和glPopAttrib函数来维护变量的状态,如下
glNewList(listIndex,GL_COMPILE); glPushMatrix(); glPushAttrib(GL_CURRENT_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0); glVertex2f(0.0, 1.0); glEnd(); glTranslatef(1.5, 0.0, 0.0); glPopAttrib(); glPopMatrix(); glEndList();
这章好像已经在3.1版本废除了.不知道用处大不大的