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

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

注意:可以使用void glPointSize(GLfloat size);來設(shè)計(jì)像素點(diǎn)大小
通常使用下面的代碼來獲取點(diǎn)大小的范圍和它們之間最小的中間值:
GLfloat sizes[2]; //保存繪制點(diǎn)的尺寸范圍
GLfloat step; //保存繪制點(diǎn)尺寸的步長
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);
2、 繪制直線
glBegin(GL_LINES); // GL_LINES每兩個(gè)頂點(diǎn)定義一條直線
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(10.0f,10.0f,10.0f);
glEnd();
注意:
① 、void glLineWidth(GLfloat width) //設(shè)置線寬
② 、glEnable(GL_LINE_STIPPLE); //修改模式
③ 、glLineStipple(GLint factor,GLushort pattern);//將factor 設(shè)為2 會(huì)使模式中的每一位代表一行中2 個(gè)象素的開或關(guān)。pattern 為0X00FF,可以畫出點(diǎn)劃線
3、 多邊形的繪制
注意事項(xiàng):
① 、繞法
如果要反轉(zhuǎn)OpenGL 的默認(rèn)行為,可以調(diào)用函數(shù):
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 指定多邊形的哪一面受模式改變的影響
參數(shù)mode 用于指定新的繪圖模式。
GL_FILL 是默認(rèn)值,生成填充的多邊形;
GL_LINE 生成多邊形的輪廓;
GL_POINT 只畫出頂點(diǎn)。
GL_LINE 和GL_POINT 繪制的點(diǎn)和線受glEdgeFlag 所設(shè)置邊緣標(biāo)記的影響。
④ 、多邊形的繪制規(guī)則
⑤
4、 多面體的繪制
1. 深度測試
為了啟用深度測試,只要調(diào)用:
glEnable(GL_DEPTH_TEST);
如果要關(guān)閉深度測試,則只需調(diào)用glDisable(GL_DEPTH_TEST)即可。
另外為了使深度緩沖區(qū)正常完成深度測試功能,在每次渲染場景時(shí),必須先清除深度緩
沖區(qū):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2. 隱藏表面
5、
回調(diào)函數(shù)
void glutDisplayFunc(void (*func)(void) );
為當(dāng)前窗口設(shè)置顯示回調(diào)函數(shù)
void glutOverlayDisplayFunc(void (*func)(void) );
注冊當(dāng)前窗口的重疊層的顯示回調(diào)函數(shù)
void glutReshapeFunc(void (*Func)(int width, int height) );
指定當(dāng)窗口的大小改變時(shí)調(diào)用的函數(shù)
void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y) );
注冊當(dāng)前窗口的鍵盤回調(diào)函數(shù)
void glutMouseFunc(void (*func) (int button, int state, int x, int y));
注冊當(dāng)前窗口的鼠標(biāo)回調(diào)函數(shù)
func為注冊的鼠標(biāo)回調(diào)函數(shù),這個(gè)函數(shù)完成鼠標(biāo)事件的處理
button為鼠標(biāo)的按鍵,為以下定義的常量
GLUT_LEFT_BUTTON |
鼠標(biāo)左鍵 |
GLUT_MIDDLE_BUTTON |
鼠標(biāo)中鍵 |
GLUT_RIGHT_BUTTON |
鼠標(biāo)右鍵 |
state為鼠標(biāo)按鍵的動(dòng)作,為以下定義的常量
GLUT_UP |
鼠標(biāo)釋放 |
GLUT_DOWN |
鼠標(biāo)按下 |
x,y為鼠標(biāo)按下式,光標(biāo)相對(duì)于窗口左上角的位置
void glutMotionFunc(void (*func)(int x, int y));
void glutPassiveMotionFunc(void (*func)(int x, int y));
設(shè)置移動(dòng)回調(diào)函數(shù);設(shè)置當(dāng)前鼠標(biāo)移動(dòng)函數(shù)
Func為注冊的鼠標(biāo)移動(dòng)函數(shù)
x,y為鼠標(biāo)按下式,光標(biāo)相對(duì)于窗口左上角的位置
當(dāng)鼠標(biāo)在窗口中按下并移動(dòng)時(shí)調(diào)用glutMotionFunc注冊的回調(diào)函數(shù)
當(dāng)鼠標(biāo)在窗口中移動(dòng)時(shí)調(diào)用glutPassiveMotionFunc注冊的回調(diào)函數(shù)
void glutVisibilityFunc(void (*func) (int state) );
設(shè)置當(dāng)前窗口的可視回調(diào)函數(shù)
Func為指定的可視回調(diào)函數(shù)
state表示窗口的可視性,為以下常量:
GLUT_NOT_VISIBLE |
窗口完全不可見 |
GLUT_VISIBLE |
窗口可見或部分可見 |
這個(gè)函數(shù)設(shè)置當(dāng)前窗口的可視回調(diào)函數(shù),當(dāng)窗口的可視性改變時(shí),該窗口的可視回調(diào)函數(shù)被調(diào)用.只要窗口中的任何一個(gè)像素是可見的,或者他的任意一個(gè)子窗口中任意一個(gè)像素是可見的,GLUT則認(rèn)為窗口是可見的.
void glutEntryFunc(void (*func) (int state));
設(shè)置鼠標(biāo)的進(jìn)出窗口的回調(diào)函數(shù)
Func為注冊的鼠標(biāo)進(jìn)出回調(diào)函數(shù)
state為鼠標(biāo)的進(jìn)出狀態(tài),為以下常量之一:
GLUT_LEFT |
鼠標(biāo)離開窗口 |
GLUT_RIGHT |
鼠標(biāo)進(jìn)入窗口 |
當(dāng)窗口取得焦點(diǎn)或失去焦點(diǎn)時(shí)調(diào)用這個(gè)函數(shù),當(dāng)鼠標(biāo)進(jìn)入窗口區(qū)域并點(diǎn)擊時(shí),state為GLUT_RIGHT,當(dāng)鼠標(biāo)離開窗口區(qū)域點(diǎn)擊其他窗口時(shí),state為GLUT_LEFT.
void glutSpecialFunc(void (*func) (int key, int x, int y))
設(shè)置當(dāng)前窗口的特定鍵的回調(diào)函數(shù)
Func為注冊的特定鍵的回調(diào)函數(shù)
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為當(dāng)按下鍵時(shí)鼠標(biāo)的坐標(biāo),相對(duì)于窗口左上角,以像素為單位
注意:ESC,回車和delete鍵由ASCII碼產(chǎn)生.
void glutMenuStatusFunc(void (*func) (int status, int x, int y));
設(shè)置菜單狀態(tài)回調(diào)函數(shù)
func是注冊的菜單狀態(tài)回調(diào)函數(shù)
status是當(dāng)前是否使用菜單,為以下定義的常量
GLUT_MENU_IN_USE |
菜單正在使用 |
GLUT_MENU_NOT_IN_USE |
菜單未被使用 |
x,y是鼠標(biāo)按下式,光標(biāo)相對(duì)于窗口左上角的位置
這個(gè)函數(shù)時(shí)glut程序判定是否正在使用菜單,當(dāng)彈出菜單時(shí),調(diào)用注冊的菜單狀態(tài)回調(diào)函數(shù),同時(shí)status設(shè)置為常量 GLUT_MENU_IN_USE, 當(dāng)菜單使用完畢時(shí),也調(diào)用菜單狀態(tài)回調(diào)函數(shù),此時(shí)status變量變?yōu)?/span>GLUT_MENU_NOT_IN_USE.從已彈出的菜單中再彈出的菜單不產(chǎn)生菜單狀態(tài)回調(diào)過程.每個(gè)glut程序只有一個(gè)菜單狀態(tài)回調(diào)函數(shù).
glutSpaceballRotateFunc
glutSpaceballButtonFunc
glutButtonBoxFunc
glutDialsFunc
glutTabletMotionFunc
glutTabletButtonFunc
void glutMenuStatusFunc(void (*func) (int status, int x, int y));
設(shè)置菜單狀態(tài)回調(diào)函數(shù)
func為注冊的菜單狀態(tài)回調(diào)函數(shù)
status表示當(dāng)前是否使用菜單,為以下定義的常量
GLUT_MENU_IN_USE |
菜單正在使用 |
GLUT_MENU_NOT_IN_USE |
菜單未被使用 |
x,y表示鼠標(biāo)按下式,光標(biāo)相對(duì)于窗口左上角的位置
這個(gè)函數(shù)時(shí)glut程序判定是否正在使用菜單,當(dāng)彈出菜單時(shí),調(diào)用注冊的菜單狀態(tài)回調(diào)函數(shù),同時(shí)status設(shè)置為常量 GLUT_MENU_IN_USE, 當(dāng)菜單使用完畢時(shí),也調(diào)用菜單狀態(tài)回調(diào)函數(shù),此時(shí)status變量變?yōu)?/span>GLUT_MENU_NOT_IN_USE.從已彈出的菜單中再彈出的菜單不產(chǎn)生菜單狀態(tài)回調(diào)過程.每個(gè)glut程序只有一個(gè)菜單狀態(tài)回調(diào)函數(shù).
void glutIdleFunc(void (*func) (void));
設(shè)置空閑回調(diào)函數(shù)
func表示當(dāng)系統(tǒng)空閑時(shí)調(diào)用的函數(shù),它的形式為void func(void)
void glutTimerFunc(unsigned int msecs, void (*Func)(int value), int value);
注冊一個(gè)回調(diào)函數(shù),當(dāng)指定時(shí)間值到達(dá)后,由GLUT調(diào)用注冊的函數(shù)一次
msecs是等待的時(shí)間
Func是注冊的函數(shù)
value是指定的一個(gè)數(shù)值,用來傳遞到回調(diào)函數(shù)Func中
這個(gè)函數(shù)注冊了一個(gè)回調(diào)函數(shù),當(dāng)指定的毫秒數(shù)到達(dá)后,這個(gè)函數(shù)就調(diào)用注冊的函數(shù),value參數(shù)用來向這個(gè)注冊的函數(shù)中傳遞參數(shù).
posted on 2011-09-13 16:00
Yu_ 閱讀(526)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
Windows程序設(shè)計(jì)