Display Lists in OpenGL (L6)

2015-11-24_100143

Lesson 6 要介紹的是如何將 object 陣列化,簡言之,就是把 object 定義在額外的BuildLists() 內,透過 glCallList 這個 function 來調用,而不用每次都在 painGL() 內定義六面體各個面的位置。

● Color Array

static GLfloat boxcol[5][3] = {1.0f, 1.0f, 1.0f,
 1.0f, 0.0f, 0.0f,
 1.0f, 1.0f, 0.0f,
 0.0f, 1.0f, 0.0f,
 0.0f, 1.0f, 1.0f};
static GLfloat topcol[5][3] = {0.5f, 0.5f, 0.5f,
 0.5f, 0.0f, 0.0f,
 0.5f, 0.3f, 0.0f,
 0.0f, 0.5f, 0.0f,
 0.0f, 0.5f, 0.5f};

首先先定義各階層的顏色,最上層是 texture 原色,再來是紅色、黃色、綠色以及青綠色。

● Build Lists


void myopenGL::BuildLists()
{
 box = glGenLists(2); // build two list and return the pointer of the first list
 glNewList(box, GL_COMPILE);
 glBegin(GL_QUADS);
 //bottom
 glNormal3f(0.0f,-1.0f,0.0f);
 glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
 glTexCoord2f(0.0f,1.0f); glVertex3f( 1.0f,-1.0f,-1.0f);
 glTexCoord2f(0.0f,0.0f); glVertex3f( 1.0f,-1.0f, 1.0f);
 glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0f,-1.0f, 1.0f);
 //front
 glNormal3f(0.0f,0.0f,1.0f);
 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 1.0f);
 glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f,-1.0f, 1.0f);
 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
 glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
 //back
 glNormal3f(0.0f,0.0f,-1.0f);
 glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
 glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0f, 1.0f,-1.0f);
 glTexCoord2f(0.0f,1.0f); glVertex3f( 1.0f, 1.0f,-1.0f);
 glTexCoord2f(0.0f,0.0f); glVertex3f( 1.0f,-1.0f,-1.0f);
 //right
 glNormal3f(1.0f,0.0f,0.0f);
 glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f,-1.0f,-1.0f);
 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f,-1.0f);
 glTexCoord2f(0.0f,1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
 glTexCoord2f(0.0f,0.0f); glVertex3f( 1.0f,-1.0f, 1.0f);
 //left
 glNormal3f(-1.0f,0.0f,0.0f);
 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
 glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0f,-1.0f, 1.0f);
 glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
 glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f,-1.0f);
 glEnd();
 glEndList();

top = box+1;
 glNewList(top, GL_COMPILE);
 glBegin(GL_QUADS);
 //top
 glNormal3f(0.0f,1.0f,0.0f);
 glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f,-1.0f);
 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
 glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f,-1.0f);
 glEnd();
 glEndList();

}

BuildLists() 是新的 function ,就是將所要繪畫的物件目錄化。

box = glGenLists(2) 表示建立兩個 list 而且將 第一個 list 的 pointer 指向到 box 這個 integer 上。另一個就是 top。這裡建兩個 list 主要目的是在於 top 與其他 box 五面的顏色會不一樣,所以用此區分。

glNewList(box, GL_COMPILE) 表示告訴 opengl 將建立的 object 存在 box 這個 pointer 裡面,GL_COMPILE 的意思是告訴 opengl 要提前建立這個 object 就不需要在 runtime 時還要去理解 object 的內容與型態。

創建好了新的 BuildLists() 後,為了要在每個 texture 上染色,所以在 initializeGL() 裡面要加入 glEnable(GL_COLOR_MATERIAL) 如果不啟動的話,所有的 texture 將會顯示原始的顏色。

● painGL()


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture[2]);

if(Light)
 glEnable(GL_LIGHTING);
else
 glDisable(GL_LIGHTING);

for(int yloop = 1; yloop < 6; yloop++)
{
 for(int xloop = 0; xloop < yloop; xloop++)
 {
 glLoadIdentity();
 // position the cubes
 glTranslatef(1.4f+xloop*2.8f-yloop*1.4f, (8.0f-yloop*2.4f)-0.7f, -20.0f);
 glRotatef(45.0f-2.0f*yloop+rota_x, 1.0f, 0.0f, 0.0f);
 glRotatef(45.0f+rota_y, 0.0f, 1.0f, 0.0f);

glColor3fv(boxcol[yloop-1]);
 glCallList(box);
 glColor3fv(topcol[yloop-1]);
 glCallList(top);

}
}

透過 xloopyloop 來定義要繪畫的數量,第一列畫一個 object,第二列畫兩個,第三列畫三個...直到畫到第五列。

glColor3fv(boxcol[yloop-1] 表示選取的顏色。glColor3fv,v 代表 vector,只要給定 RGB 顏色的第一個 pointer 位置即可。

glCallList(box)glCallList(top) 則是調用剛已經定義好的 Object List。

 

 


reference : http://nehe.gamedev.net/tutorial/display_lists/15003/

Leave a Reply

Your email address will not be published. Required fields are marked *