代码改变世界

OpenGL学习笔记(8)显示列表

2010-10-25 23:22  Clingingboy  阅读(4868)  评论(0编辑  收藏  举报

 

            显示列表是一组存储在一起的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 ();
}
注意点:
  1. 显示列表中的值不能在以后进行修改
  2. 但可以删除整个列表然后创建一个新的

调用显示列表

使用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版本废除了.不知道用处大不大的