一、 工作原理
(1)、OpenGL流水線

命名約定:
(2)、顯示形狀
函數功能:設置初始顯示模式。
函數原型:void glutInitDisplayMode(unsigned int mode);
mode : mode可取以下值或其組合:
值 對應宏定義 意義
GLUT_RGB 0x0000 指定 RGB 顏色模式的窗口
GLUT_RGBA 0x0000 指定 RGBA 顏色模式的窗口
GLUT_INDEX 0x0001 指定顏色索引模式的窗口
GLUT_SINGLE 0x0000 指定單緩存窗口
GLUT_DOUBLE 0x0002 指定雙緩存窗口
GLUT_ACCUM 0x0004 窗口使用累加緩存
GLUT_ALPHA 0x0008 窗口的顏色分量包含 alpha 值
GLUT_DEPTH 0x0010 窗口使用深度緩存
GLUT_STENCIL 0x0020 窗口使用模板緩存
GLUT_MULTISAMPLE0x0080 指定支持多樣本功能的窗口
GLUT_STEREO 0x0100 指定立體窗口
GLUT_LUMINANCE 0x0200 窗口使用亮度顏色模型
2、再整形回調函數(邏輯笛卡兒坐標映射為物理屏幕的象素坐標)
glutReshapeFunc(ChangeSize); //
①、利用函數glViewport 定義視區:
void glViewport(GLint x,GLint y,GLsizei width,Glsizei height);
②、利用函數glOrtho 定義修剪區
void glOrtho(Gldouble left,Gldouble right,Gldouble bottom,Gldouble top,Gldouble near,Gldouble far);
調用函數glOrtho 之前,調用下面函數使坐標系“復位”。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //重置當前指定的矩陣為單位矩陣,使坐標系“復位”
3、 顯示回調函數
glutDisplayFunc(RenderScene);
顯示回調函數RenderScene 是調用OpenGL 渲染函數的地方。
① 、實際清除
glClear(GL_COLOR_BUFFER_BIT); //用當前清除色清除顏色緩沖區,即設定窗口的背景色
② 指定當前繪圖顏色 //調用glColor3f 設置
③ 圖形繪制
④ 刷新隊列 //glFlush()用于讓所有尚未執行的OpenGL 命令都被執行
由上面的程序可以看出,一個OpenGL 程序的基本結構主要包括以下幾個部分:
(1)定義窗口:包括指定窗口的大小、位置、顯示模式以及設置各種回調函數;
(2)初始化設置:清除各種緩沖區,并設置各種OpenGL 狀態,例如設置背景色,打開光照,設置紋理等等。
(3)繪制場景:利用OpenGL 函數繪制場景中的各種物體。
(4)變換:指定場景中需要顯示的范圍并指定由修剪區到視區的變換。
(5)結束運行:清除命令緩沖區,執行OpenGL 命令。
(3)顯示動畫
glutTimerFunc(unsigned int msecs,(*func) (int value),int value);
該函數與其他的回調函數不一樣的地方在于該函數只會被激發一次。為了實現連
續的動畫,必須在定時器函數中再次重新設置定時器回調函數。
注意1:顯示回調函數時的擦新方式。
glFlush()與glutSwapBuffers()的區別
簡單地說glFlush就是強制刷新吧,要知道OPENGL是使用一條渲染管線線性處理命令的,一般情況下,我們提交給OPENGL的指令并不是馬上送到驅動程序里執行的,而是放到一個緩沖區里面,等這個緩沖區滿了再一次過發到驅動程序里執行;很多時候只有幾條指令是填充不滿那個緩沖區的,這就是說這些指令根本沒有被發送到驅動里,所以我們要調用glFlush來強制把這些指令送到驅動里進行處理。
glutSwapBuffers其實就是交換緩沖區啦,估計是你的程序使用的是雙緩沖技術吧;用了這種技術的話,你所有的繪制都是繪制到一個后臺的緩沖區里面的,如果不交換緩沖區,就看不到繪制的東西了,就這么回事~
二、 繪圖
1、 繪點
glBegin(GL_POINTS); //的定點到放在函數glBegin 和glEnd 之間,由函數glBegin 的參數指定繪制圖元的類型,
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(10.0f,10.0f,10.0f);
glEnd();
glBegin的參數詳解:
GL_POINTS 單一點
GL_LINES 兩頂點創建一直線
GL_LINE_STRIP 創建線條,上一點是下一點的延伸
GL_LINE_LOOP 畫線條,最后一點與第一點相連。
GL_TRIANGLES 每三個頂點指定一個新三角形,并用當前顏色填充
GL_TRIANGLE_STRIP 創建相鄰的三角形

注意:可以使用void glPointSize(GLfloat size);來設計像素點大小
通常使用下面的代碼來獲取點大小的范圍和它們之間最小的中間值:
GLfloat sizes[2]; //保存繪制點的尺寸范圍
GLfloat step; //保存繪制點尺寸的步長
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);
2、 繪制直線
glBegin(GL_LINES); // GL_LINES每兩個頂點定義一條直線
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(10.0f,10.0f,10.0f);
glEnd();
注意:
① 、void glLineWidth(GLfloat width) //設置線寬
② 、glEnable(GL_LINE_STIPPLE); //修改模式
③ 、glLineStipple(GLint factor,GLushort pattern);//將factor 設為2 會使模式中的每一位代表一行中2 個象素的開或關。pattern 為0X00FF,可以畫出點劃線
3、 多邊形的繪制
注意事項:
① 、繞法
如果要反轉OpenGL 的默認行為,可以調用函數:
glFrontFace(GL_CW);
② 、明暗處理
void glShadeModel(GLenum mode);
GL_FLAT //平面明暗處理
GL_SMOOTH //光滑明暗處理
③ 、多邊形的模式
glPolygonMode(Glenum face,Glenum mode);
face
GL_FRONT,GL_BACK 或GL_FRONT_AND_BACK 指定多邊形的哪一面受模式改變的影響
參數mode 用于指定新的繪圖模式。
GL_FILL 是默認值,生成填充的多邊形;
GL_LINE 生成多邊形的輪廓;
GL_POINT 只畫出頂點。
GL_LINE 和GL_POINT 繪制的點和線受glEdgeFlag 所設置邊緣標記的影響。
④ 、多邊形的繪制規則
⑤
4、 多面體的繪制
1. 深度測試
為了啟用深度測試,只要調用:
glEnable(GL_DEPTH_TEST);
如果要關閉深度測試,則只需調用glDisable(GL_DEPTH_TEST)即可。
另外為了使深度緩沖區正常完成深度測試功能,在每次渲染場景時,必須先清除深度緩
沖區:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2. 隱藏表面
5、
回調函數
void glutDisplayFunc(void (*func)(void) );
為當前窗口設置顯示回調函數
void glutOverlayDisplayFunc(void (*func)(void) );
注冊當前窗口的重疊層的顯示回調函數
void glutReshapeFunc(void (*Func)(int width, int height) );
指定當窗口的大小改變時調用的函數
void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y) );
注冊當前窗口的鍵盤回調函數
void glutMouseFunc(void (*func) (int button, int state, int x, int y));
注冊當前窗口的鼠標回調函數
func為注冊的鼠標回調函數,這個函數完成鼠標事件的處理
button為鼠標的按鍵,為以下定義的常量
GLUT_LEFT_BUTTON |
鼠標左鍵 |
GLUT_MIDDLE_BUTTON |
鼠標中鍵 |
GLUT_RIGHT_BUTTON |
鼠標右鍵 |
state為鼠標按鍵的動作,為以下定義的常量
GLUT_UP |
鼠標釋放 |
GLUT_DOWN |
鼠標按下 |
x,y為鼠標按下式,光標相對于窗口左上角的位置
void glutMotionFunc(void (*func)(int x, int y));
void glutPassiveMotionFunc(void (*func)(int x, int y));
設置移動回調函數;設置當前鼠標移動函數
Func為注冊的鼠標移動函數
x,y為鼠標按下式,光標相對于窗口左上角的位置
當鼠標在窗口中按下并移動時調用glutMotionFunc注冊的回調函數
當鼠標在窗口中移動時調用glutPassiveMotionFunc注冊的回調函數
void glutVisibilityFunc(void (*func) (int state) );
設置當前窗口的可視回調函數
Func為指定的可視回調函數
state表示窗口的可視性,為以下常量:
GLUT_NOT_VISIBLE |
窗口完全不可見 |
GLUT_VISIBLE |
窗口可見或部分可見 |
這個函數設置當前窗口的可視回調函數,當窗口的可視性改變時,該窗口的可視回調函數被調用.只要窗口中的任何一個像素是可見的,或者他的任意一個子窗口中任意一個像素是可見的,GLUT則認為窗口是可見的.
void glutEntryFunc(void (*func) (int state));
設置鼠標的進出窗口的回調函數
Func為注冊的鼠標進出回調函數
state為鼠標的進出狀態,為以下常量之一:
GLUT_LEFT |
鼠標離開窗口 |
GLUT_RIGHT |
鼠標進入窗口 |
當窗口取得焦點或失去焦點時調用這個函數,當鼠標進入窗口區域并點擊時,state為GLUT_RIGHT,當鼠標離開窗口區域點擊其他窗口時,state為GLUT_LEFT.
void glutSpecialFunc(void (*func) (int key, int x, int y))
設置當前窗口的特定鍵的回調函數
Func為注冊的特定鍵的回調函數
key為按下的特定鍵,為以下定義的常量:
key常量 |
描述 |
GLUT_KEY_F1 |
F1功能鍵 |
GLUT_KEY_F2 |
F2功能鍵 |
GLUT_KEY_F3 |
F3功能鍵 |
GLUT_KEY_F4 |
F4功能鍵 |
GLUT_KEY_F5 |
F5功能鍵 |
GLUT_KEY_F6 |
F6功能鍵 |
GLUT_KEY_F7 |
F7功能鍵 |
GLUT_KEY_F8 |
F8功能鍵 |
GLUT_KEY_F9 |
F9功能鍵 |
GLUT_KEY_F10 |
F10功能鍵 |
GLUT_KEY_F11 |
F11功能鍵 |
GLUT_KEY_F12 |
F12功能鍵 |
GLUT_KEY_LEFT |
左方向鍵 |
GLUT_KEY_UP |
上方向鍵 |
GLUT_KEY_RIGHT |
右方向鍵 |
GLUT_KEY_DOWN |
下方向鍵 |
GLUT_KEY_PAGE_UP |
PageUp鍵 |
GLUT_KEY_PAGE_DOWN |
PageDown鍵 |
GLUT_KEY_HOME |
Home鍵 |
GLUT_KEY_END |
End鍵 |
GLUT_KEY_INSERT |
Insert鍵 |
x,y為當按下鍵時鼠標的坐標,相對于窗口左上角,以像素為單位
注意:ESC,回車和delete鍵由ASCII碼產生.
void glutMenuStatusFunc(void (*func) (int status, int x, int y));
設置菜單狀態回調函數
func是注冊的菜單狀態回調函數
status是當前是否使用菜單,為以下定義的常量
GLUT_MENU_IN_USE |
菜單正在使用 |
GLUT_MENU_NOT_IN_USE |
菜單未被使用 |
x,y是鼠標按下式,光標相對于窗口左上角的位置
這個函數時glut程序判定是否正在使用菜單,當彈出菜單時,調用注冊的菜單狀態回調函數,同時status設置為常量 GLUT_MENU_IN_USE, 當菜單使用完畢時,也調用菜單狀態回調函數,此時status變量變為GLUT_MENU_NOT_IN_USE.從已彈出的菜單中再彈出的菜單不產生菜單狀態回調過程.每個glut程序只有一個菜單狀態回調函數.
glutSpaceballRotateFunc
glutSpaceballButtonFunc
glutButtonBoxFunc
glutDialsFunc
glutTabletMotionFunc
glutTabletButtonFunc
void glutMenuStatusFunc(void (*func) (int status, int x, int y));
設置菜單狀態回調函數
func為注冊的菜單狀態回調函數
status表示當前是否使用菜單,為以下定義的常量
GLUT_MENU_IN_USE |
菜單正在使用 |
GLUT_MENU_NOT_IN_USE |
菜單未被使用 |
x,y表示鼠標按下式,光標相對于窗口左上角的位置
這個函數時glut程序判定是否正在使用菜單,當彈出菜單時,調用注冊的菜單狀態回調函數,同時status設置為常量 GLUT_MENU_IN_USE, 當菜單使用完畢時,也調用菜單狀態回調函數,此時status變量變為GLUT_MENU_NOT_IN_USE.從已彈出的菜單中再彈出的菜單不產生菜單狀態回調過程.每個glut程序只有一個菜單狀態回調函數.
void glutIdleFunc(void (*func) (void));
設置空閑回調函數
func表示當系統空閑時調用的函數,它的形式為void func(void)
void glutTimerFunc(unsigned int msecs, void (*Func)(int value), int value);
注冊一個回調函數,當指定時間值到達后,由GLUT調用注冊的函數一次
msecs是等待的時間
Func是注冊的函數
value是指定的一個數值,用來傳遞到回調函數Func中
這個函數注冊了一個回調函數,當指定的毫秒數到達后,這個函數就調用注冊的函數,value參數用來向這個注冊的函數中傳遞參數.
posted on 2011-09-13 16:00
Yu_ 閱讀(510)
評論(0) 編輯 收藏 引用 所屬分類:
Windows程序設計