嵌套顯示列表
為了支援更加複雜的繪圖,顯示列表還支援嵌套,即在glNewList()和glEndList()建立顯示列表的過程中使用glCallList()或glCallLists()調用已經定義過的顯示列表。產生列表的嵌套層數從理論上來說可以支援2^31-2級,但是實際上有兩個原因無法支援這麼多,一是當嵌套層數增加較多時,僅僅建立顯示列表就需要耗費大量的資源和時間;二是即便可以建立多級嵌套,但超過64級OpenGL就不再顯示了。另外,使用glGetIntegerv(GL_MAX_LIST_NESTING, &level)可以得到level的值是64,因此超過64級的顯示列表嵌套其實是沒有意義的。不過64層嵌套已經完全可以滿足我們的應用程式的需要了。
下面我們利用嵌套來實現一個奧林匹克五環旗圖案。
void CreateLists()
{
list = glGenLists(3);
if(list)
{
//第一個顯示列表繪製10個立方體
glNewList(list, GL_COMPILE);
for(int i=0; i<10; i++)
{
glPushMatrix();
glRotatef(36*i,0.0,0.0,1.0) ;
glTranslatef(10.0,0.0,0.0) ;
DrawCube();
glPopMatrix();
}
glEndList();
//第二個顯示列表很簡單,僅僅畫一線段
glNewList(list+1, GL_COMPILE);
for(i=0; i<20; i++)
{
glPushMatrix();
glRotatef(18*i,0.0,0.0,1.0) ;
glTranslatef(15.0,0.0,0.0) ;
glBegin(GL_LINES);
glVertex3f(-1, 0,0);
glVertex3f(1,0,0);
glEnd();
glPopMatrix();
}
glEndList();
//這裡開始的第三個顯示列表嵌套了前面兩個顯示列表
glNewList(list+2, GL_COMPILE);
for(i=0; i<3; i++) //上面三個圓環
{
glPushMatrix();
glTranslatef(25*i, 0, 0);
glCallList(list); //第一個顯示列表
glCallList(list+1); //第二個顯示列表
glPopMatrix();
}
for(i=0; i<2; i++) //下面兩個圓環
{
glPushMatrix();
glTranslatef(12,0,0);
glTranslatef(25*i, -10, 0);
glCallList(list);
glCallList(list+1);
glPopMatrix();
}
glEndList();
}
}
void glMain()
{
static int angle =0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); //載入單位矩陣
glTranslatef(-25.0f, 0.0f, -80.0f);
glBindTexture(GL_TEXTURE_2D, g_Texture[0]); // 選擇紋理
glCallList(list+2);
angle++;
SwapBuffers(g_hDC);//交換前後緩衝區
}
程式運行結果是5個圓環組成五環圖案,每個圓環由10個立方體組成,並且在圓環外面圍繞著類似發光的線段,效果6-3所示。
其實繪製圓環使用auxSolidTorus()更加方便,不過這裡是為了說明嵌套顯示列表的調用。