在今天的opengl的課程以及實驗中,我們學習了如何使用頂點數組的方法來繪制圖形,但相信還有很多同學對它的實際使用方法不太了解,我們就用我們今天實驗課上的實例來簡單講解一下
題目及要求
繪制一個正六面體,正面以填充方式繪制,背面以輪廓線的形式繪制,坐標自擬
思路解析
首先,我們需要定義一個數組,用來存放所有的頂點,為了方便理解,我們可以畫一個草圖:
這樣,我們就可以寫出頂點坐標數組:
1 //存放所有頂點坐標的數組 2 float vertex_list[][3] = 3 { 4 {0,0,0}, 5 {1,0,0}, 6 {1,1,0}, 7 {0,1,0}, 8 9 {0,1,1}, 10 {1,1,1}, 11 {1,0,1}, 12 {0,0,1} 13 };
接下來,我們需要一個頂點坐標的索引數組,索引數組用來表示的是頂點被繪制的順序,每個點的編號代表的是頂點坐標數組中該點對應的下標。
例如,點(0,0,0)用數組表示為 vertex_list[0],則(0,0,0)為0號點,則上述數組中所有點的編號為:
我們將頂點編號完畢之后,我們就可以來定義點的繪制順序了。
我們用0123的順序繪制第一個面,4567的順序繪制第二個面,2761的順序繪制第二個面,3450的順序繪制第四個面。
寫成數組形式如下:
1 //存放數組索引的數組,可以近似地理解為頂點被繪制的順序 2 int index_list[] = 3 { 4 0,1,2,3, 5 4,5,6,7, 6 2,7,6,1, 7 3,4,5,0 8 };
這樣一來,四個側面都繪制完畢,由於上下兩個面直接由四個側面拼接而成了,所以沒有必要非要繪制。
頂點數組和索引數組都被定義完畢,接下來我們可以進行正式的代碼書寫了。
完整代碼及其結果
1 #include<gl/glut.h> 2 //存放所有頂點坐標的數組 3 float vertex_list[][3] = 4 { 5 {0,0,0}, 6 {1,0,0}, 7 {1,1,0}, 8 {0,1,0}, 9 10 {0,1,1}, 11 {1,1,1}, 12 {1,0,1}, 13 {0,0,1} 14 }; 15 16 //存放數組索引的數組,可以近似地理解為頂點被繪制的順序 17 int index_list[] = 18 { 19 0,1,2,3, 20 4,5,6,7, 21 2,7,6,1, 22 3,4,5,0 23 }; 24 25 void display(void) 26 { 27 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 28 glOrtho(-1, 2, -1, 2, -1, 2); //設置屏幕的顯示范圍 29 glPolygonMode(GL_FRONT, GL_FILL); //設置正面為填充類型 30 glPolygonMode(GL_BACK, GL_LINE); //設置背面為輪廓線類型 31 glFrontFace(GL_CCW); //將逆時針設置為正面 32 glRotatef(45, -1, 1, 0); //將圖形旋轉一下以便看得更直觀 33 34 glEnableClientState(GL_VERTEX_ARRAY); //啟用頂點數組 35 glVertexPointer(3, GL_FLOAT, 0, vertex_list); //指定頂點數組 36 //按照索引數組中指出的數組依次調用glVertex函數,16表示的是調用的次數 37 glDrawElements(GL_QUADS, 16, GL_UNSIGNED_INT, index_list); 38 39 glFlush(); 40 } 41 int main(int argc, char**argv) 42 { 43 glutInit(&argc, argv); 44 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); 45 glutInitWindowPosition(200, 200); 46 glutInitWindowSize(500, 500); 47 glutCreateWindow("正六面體"); 48 glutDisplayFunc(display); 49 glutMainLoop(); 50 return 0; 51 }