OpenGL学习十二:显示列表

显示列表可以提高性能,因为他可以存储OPENGL的函数,供以后使用,如果需要多次重绘同一个几何图形,或者如果一次需要多次调用的用于更改状态的函数,把这些函数存储在显示列表中(将显示列表中的矩阵结果集保存,后续使用不需要重复计算以提高性能)

当通过网络在另外一台远程计算机上运算OPENGL程序时,把绘画命令保存在显示列表中具有特别重要意义,由于显示列表是服务器的一部分,这样可以减少网络通信,提高性能

显示列表更像是命令缓存器,而不是动态数据库,也就是说当显示列表创建后,就无法修改。同时显示列表的创建也存在一定的系统开销,因此一个小的显示列表未必会提升性能
命名和创建,执行显示列表
1.申请索引值
  Gluint listName = glGenLists (Glsizei range);
  分配range个连续的,以前未分配的显示列表索引,返回值为连续索引的起始
2.指定显示列表的开始
  glNewList (listName, mode);
  mode:GL_COMPILE
       GL_COMPILE_AND_EXECUTE
3.OPENGL指令

4.显示列表定义结束
   glEndList ();
5.执行显示列表
   glCallList (listName);
层次式显示列表
可以创建层次式显示列表,这是一种在glNewList()与glEndList()之间调用glCallList()执行其他显示列表的显示列表
 glNewList (listName, mode);
 glCallList (name1);
 glCallList (name2);
 glCallList (name3);
 glCallList (name4);
 glEndList ();
显示层次最少的嵌套层次是64,可能更高,通过GL_MAX_LIST_NESTING 属性查询
管理显示列表索引
Glboolean glIsList(Gluint list)
void glDeleteLists(Gluint listm,Glsizei range)
执行多个显示列表
 glListBase(base);
指定一个偏移量,它将与glCallLists()函数中的显示列表索引值想加,以获取最终的显示列表索引,显示列表基址对于glCallList(),glNewList()无任何效果
glCallLists (GLsizei n, GLenum type, const GLvoid *lists);
执行n个显示列表
type:GL_BYTE
GL_UNSIGNED_BYTE
GL_SHORT
GL_UNSIGNED_SHORT
GL_INT
GL_UNSIGNED_INT
GL_FLOAT
GL_2_BYTES
GL_3_BYTES
GL_4_BYTES

举例:
   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();

char *test1 = "A SPARE SERAPE APPEARS AS";
GLsizei len = strlen(s);
glCallLists(len, GL_BYTE, (GLbyte *)s);

显示列表管理状态变量
显示列表可以包含用于修改opengl状态变量值的函数,这些值在执行显示列表时被修改,并且这些值在显示列表执行完仍然会保持,简单的说,假如在显示列表中设置 glColor(1,0,0), 在显示列表执行完成后,设置的颜色依然起作用。

有时候,我们希望显示列表的修改对后面不产生影响,这就需要进行恢复属性
  glNewList (listName, mode);
   glPushMatrix();
   glPushAttrib(GL_CURRENT_BIT)
    ...
   do_some_draw();

   glPopAttrib()
   glPopMatrix();
  glEndList ();

 显示列表Demo:

#include "header.h"

GLuint listName;

static void init (void)
{
   listName = glGenLists (1);
   glNewList (listName, GL_COMPILE);
      glColor3f (1.0, 0.0, 0.0); 
      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); 
   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); 
   for (i = 0; i < 10; i++)   
      glCallList (listName);
   drawLine ();  
                
   glFlush ();
}

void reshape(int w, int h)
{
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   if (w <= h) 
      gluOrtho2D (0.0, 2.0, -0.5 * (GLfloat) h/(GLfloat) w, 
         1.5 * (GLfloat) h/(GLfloat) w);
   else 
      gluOrtho2D (0.0, 2.0 * (GLfloat) w/(GLfloat) h, -0.5, 1.5); 
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}


int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize(650, 50);
   glutCreateWindow(argv[0]);
   init ();
   glutReshapeFunc (reshape);
   glutDisplayFunc (display);
   glutKeyboardFunc (keyboard);
   glutMainLoop();
   return 0;
}

 

多个显示列表Demo

 

#include "header.h"
#include <string.h>

#define PT 1
#define STROKE 2
#define END 3

typedef struct charpoint {
   GLfloat   x, y;
   int    type;
} CP;

CP Adata[] = {
   { 0, 0, PT}, {0, 9, PT}, {1, 10, PT}, {4, 10, PT}, 
   {5, 9, PT}, {5, 0, STROKE}, {0, 5, PT}, {5, 5, END}
};

CP Edata[] = {
   {5, 0, PT}, {0, 0, PT}, {0, 10, PT}, {5, 10, STROKE},
   {0, 5, PT}, {4, 5, END}
};

CP Pdata[] = {
   {0, 0, PT}, {0, 10, PT},  {4, 10, PT}, {5, 9, PT}, {5, 6, PT}, 
   {4, 5, PT}, {0, 5, END}
};

CP Rdata[] = {
   {0, 0, PT}, {0, 10, PT},  {4, 10, PT}, {5, 9, PT}, {5, 6, PT}, 
   {4, 5, PT}, {0, 5, STROKE}, {3, 5, PT}, {5, 0, END}
};

CP Sdata[] = {
   {0, 1, PT}, {1, 0, PT}, {4, 0, PT}, {5, 1, PT}, {5, 4, PT}, 
   {4, 5, PT}, {1, 5, PT}, {0, 6, PT}, {0, 9, PT}, {1, 10, PT}, 
   {4, 10, PT}, {5, 9, END}
};


static void drawLetter(CP *l)
{
   glBegin(GL_LINE_STRIP);
   while (1) {
      switch (l->type) {
         case PT:
			 if(l->y==0)
			 {
				 glColor3f(1.0,0.0,0.0);
			 }
            glVertex2i(l->x,l->y);
            break;
         case STROKE:
            glVertex2i(l->x,l->y);
            glEnd();
            glBegin(GL_LINE_STRIP);
            break;
         case END:
            glVertex2i(l->x,l->y);
            glEnd();
            glTranslatef(8.0, 0.0, 0.0);
            return;
      }
      l++;
   }
}
GLuint base;

static void init (void)
{
   GLuint base;

   glShadeModel (GL_FLAT);

   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();
}

char *test1 = "A SPARE SERAPE APPEARS AS";
char *test2 = "APES PREPARE RARE PEPPERS";

static void printStrokedString(char *s)
{
  
   GLsizei len = strlen(s);
  
   glCallLists(len, GL_BYTE, (GLbyte *)s);
}

void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f(1.0, 1.0, 1.0);
   glPushMatrix();
   glScalef(2.0, 2.0, 2.0);
   glTranslatef(10.0, 30.0, 0.0);
   printStrokedString(test1);
   glPopMatrix();
   glPushMatrix();
   glScalef(2.0, 2.0, 2.0);
   glTranslatef(10.0, 13.0, 0.0);
   printStrokedString(test2);
   glPopMatrix();
   glFlush();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case ' ':
         glutPostRedisplay();
         break;
      case 27:
         exit(0);
   }
}


int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (440, 120);
   glutCreateWindow ("stroke");
   init ();
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutDisplayFunc(display);
   glutMainLoop();
   return 0;
}

 

你可能感兴趣的:(OpenGL)