經歷前兩節課,想必大家能夠編寫一些基本的OpenGL小程序。但是對這個glBegin里的冬冬,還是心生困惑的。因此我將這里的基本類型給大家列下來。
我們在畫一個圖元的時候,通常如下,比如Helloj2ee繪制的北斗七星圖。
glBegin(g_geotype); glVertex2i(289, 190); // 繪制若干個點 glVertex2i(320, 128); glVertex2i(239, 67); glVertex2i(194, 101); glVertex2i(129, 83); glVertex2i(74, 74); glVertex2i(20,10); glEnd();
同樣是點,那么glBegin里面傳的參數不一樣,則繪制的圖形不一樣。OpenGL提供了以下10種基本幾何圖元。
GL_POINTS 為n個頂點的每一個都繪制一個點,以北斗七星為例,如果g_geotype = GL_POINTS,那么得到效果如下圖(點是人為標示上去,OpenGL繪制注記,並不像一般圖形平台那么容易)。
如果g_geotype = GL_LINES,一對頂點才被解釋為一條直線,直線之間並不連接,但是如果不湊巧是奇數個點,那么最后一個點不幸要被忽略掉,因此這里v7這個點就被忽略掉。
如果g_geotype = GL_LINE_STRIP,則是一系列的直線。即從v0到v1,一直到v7。如下圖所示:
如果g_geotype = GL_LINE_LOOP,和GL_LINE_STRIP相似,只不過構成一個線環,注意阿,它仍是線,而不是面,只不過是一個閉合的線。
如果g_geotype = GL_TRIANGLES,那么它是一系列的三角形,n只有是3的倍數,那么才能恰好所有點構成三角形,n不是3的倍數,剩下的點就會被忽略。
如果g_geotype = GL_TRIANGLE_STRIP,那么第一個三角形是v1,v3,v2,第二個三角形是v2,v4,v3,依次類推,注意三個點的順序。要保證所有的三角形是按相同方向繪制。
如果g_geotype = GL_TRIANGLE_FAN,和GL_TRIANGLE_STRIP類似,區別在於一直是以v1開始,v1,v3,v2 和v1 v4 v2等等。
如果g_geotype = GL_QUADS,則是一系列的四邊形,首先使用頂點v1,v2,v3,v4,然后不是4的倍數,只能忽略。
如果g_geotype = GL_QUAD_STRIP,繪制一系列四邊形,但是四邊形的順序是頂點 2n-1、2n、2n+2和2n+1定義了第n個四邊形。由於這並非是一個凸多邊形,因此會很怪異。
如果g_geotype = GL_POLYGON,則是繪制一個多邊形。點的個數必須大於等於3。多邊形本身不要相交,且最好是凸多邊形。如果頂點不滿足這些條件,也許正確,也許不正確。
該程序代碼如下所示。

#include <windows.h> #include <gl/Gl.h> #include <gl/glu.h> #include <gl/glut.h> #define E_POINTS 1 #define E_LINES 2 #define E_LINES_STRIP 3 #define E_LINE_LOOP 4 #define E_TRIANGLES 5 #define E_TRIANGLES_STRIP 6 #define E_TRIANGLES_FAN 7 #define E_QUADS 8 #define E_QUAD_STRIP 9 #define E_POLYGON 10 GLenum g_geotype = GL_POINTS; //<<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>> void myInit(void) { glClearColor(1.0, 1.0, 1.0, 0.0); // 設置背景顏色為亮白 glColor3f(0.0f, 0.0f, 0.0f); // 設置繪制顏色為黑 glPointSize(4.0); //設置點的大小為4*4像素 glMatrixMode(GL_PROJECTION);// 設置合適的投影矩陣-以后解釋 glLoadIdentity();// 以后解釋 gluOrtho2D(0.0, 480.0, 0.0, 320.0);// 以后解釋 // g_geotype = GL_POINTS; } //<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>> // 重繪函數 void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); // 清屏幕 glBegin(g_geotype); glVertex2i(289, 190); // 繪制若干個點 glVertex2i(320, 128); glVertex2i(239, 67); glVertex2i(194, 101); glVertex2i(129, 83); glVertex2i(74, 74); glVertex2i(20,10); glEnd(); glutSwapBuffers(); // 將所有輸出到顯示屏上 } void ProcessMenuEvents(int option) { switch(option) { case E_POINTS: g_geotype = GL_POINTS; break; case E_LINES: g_geotype = GL_LINES; break; case E_LINES_STRIP: g_geotype = GL_LINE_STRIP; break; case E_LINE_LOOP: g_geotype = GL_LINE_LOOP; break; case E_TRIANGLES: g_geotype = GL_TRIANGLES; break; case E_TRIANGLES_STRIP: g_geotype = GL_TRIANGLE_STRIP; break; case E_TRIANGLES_FAN: g_geotype = GL_TRIANGLE_FAN; break; case E_QUADS: g_geotype = GL_QUADS; break; case E_QUAD_STRIP: g_geotype = GL_QUAD_STRIP; break; case E_POLYGON: g_geotype = GL_POLYGON; break; } } //<<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>> void main(int argc, char **argv) { glutInit(&argc, argv); // 初始化工具包 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 設置顯式模式 glutInitWindowSize(640,480); // 設置窗口大小 glutInitWindowPosition(100, 150); // 設置窗口位置 glutCreateWindow("my first attempt"); // 打開屏幕窗口 myInit(); glutDisplayFunc(myDisplay); // 注冊繪制函數 glutIdleFunc(myDisplay); glutCreateMenu(ProcessMenuEvents); glutAddMenuEntry("POINTS",E_POINTS); glutAddMenuEntry("LINES",E_LINES); glutAddMenuEntry("LINES_STRIP",E_LINES_STRIP); glutAddMenuEntry("LINE_LOOP",E_LINE_LOOP); glutAddMenuEntry("TRIANGLES",E_TRIANGLES); glutAddMenuEntry("TRIANGLES_STRIP",E_TRIANGLES_STRIP); glutAddMenuEntry("TRIANGLES_FAN",E_TRIANGLES_FAN); glutAddMenuEntry("QUADS",E_QUADS); glutAddMenuEntry("QUAD_STRIP",E_QUAD_STRIP); glutAddMenuEntry("POLYGON",E_POLYGON); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); // 進入主循環 }