




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、word計(jì) 算 機(jī) 圖 形 學(xué)課程設(shè)計(jì)報(bào)告一、實(shí)驗(yàn)題目三維真實(shí)感圖形設(shè)計(jì)與繪制1題目?jī)?nèi)容說(shuō)明:此題目要求應(yīng)用OpenGL的光照技術(shù)和紋理技術(shù)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的三維真實(shí)感圖形的程序設(shè)計(jì)。具體要求實(shí)現(xiàn)功能: 1通過(guò)對(duì)話方式實(shí)現(xiàn)交互式設(shè)計(jì)光照模型功能。 2實(shí)現(xiàn)三維模型紋理映射功能 3用鼠標(biāo)跟蹤球方法實(shí)現(xiàn)三維模型的空間旋轉(zhuǎn)2實(shí)現(xiàn)鼠標(biāo)跟蹤球方法程序二、需求分析真實(shí)感圖形的設(shè)計(jì)與繪制,是計(jì)算機(jī)圖形學(xué)中的一個(gè)重要研究領(lǐng)域,也是三維實(shí)體造型系統(tǒng)和特征造型系統(tǒng)的重要組成局部。一般地,三維實(shí)體在計(jì)算機(jī)顯示屏上有三種表現(xiàn)形式:簡(jiǎn)單線框圖、線框消隱圖和真實(shí)感圖形。其中,簡(jiǎn)單線框圖能夠粗略表達(dá)實(shí)體的形狀,但由于簡(jiǎn)單線框圖的
2、二義性,從而導(dǎo)致表達(dá)其的實(shí)體形狀具有不確定性。而線框消隱圖雖然能反映實(shí)體各外表間的相互遮擋關(guān)系,從而到達(dá)消除簡(jiǎn)單線框圖產(chǎn)生的二義性的目的,但是這兩者一樣地只能反映實(shí)體的幾何形狀和實(shí)體間的相互關(guān)系,而不能反映實(shí)體外表的特征,如外表的顏色、材質(zhì)、紋理等。所以,只有真實(shí)感圖形才能表現(xiàn)實(shí)體的這些特征,因此,在三維實(shí)體造型中,生成三維實(shí)體的光照模型,進(jìn)行實(shí)體的真實(shí)感繪制與顯示占有重要的地位,是很有必要的,也是我做此設(shè)計(jì)的初衷。 在設(shè)計(jì)中,我主要使用Opengl繪制真實(shí)感圖形,它作為一種強(qiáng)大的三維圖形開(kāi)發(fā)工具,通過(guò)便捷的編程接口提供了處理光照和物體材質(zhì)、顏色屬性等通用功能。真實(shí)感圖形學(xué)是計(jì)算機(jī)圖形的核心內(nèi)
3、容之一,是最能直接反映圖形學(xué)魅力的分支。尋求能準(zhǔn)確地描述客觀世界中各種現(xiàn)象與景觀的數(shù)學(xué)模型,并逼真地再現(xiàn)這些現(xiàn)象與景觀,是圖形學(xué)的一個(gè)重要研究課題。很多自然景物難以用幾何模型描述,如煙霧、植物、水波、火焰等。本文所討論的幾種建模及繪制技術(shù)都超越了幾何模型的限制,能夠用簡(jiǎn)單的模型描述復(fù)雜的自然景物。在計(jì)算機(jī)的圖形設(shè)備上實(shí)現(xiàn)真實(shí)感圖形必須完成的四個(gè)根本任務(wù)。1. 三維場(chǎng)景的描述。三維造型。2. 將三維幾何描述轉(zhuǎn)換成為二維透視圖。透視變換。3. 確定場(chǎng)景中的所有可見(jiàn)面。消隱算法,可見(jiàn)面探測(cè)算法。4. 計(jì)算場(chǎng)景中可見(jiàn)面的顏色。根據(jù)基于光學(xué)物理的光照模型計(jì)算可見(jiàn)面投射到觀察者眼中的光亮度大小和色彩組成。
4、三、設(shè)計(jì)簡(jiǎn)介及設(shè)計(jì)方案論述3.1設(shè)計(jì)簡(jiǎn)介為了實(shí)現(xiàn)本程序的兩大功能,方案采用OPENGL圖形庫(kù)并調(diào)用一系列WINDOWS API采用C/C+語(yǔ)言編寫(xiě)。首先,應(yīng)熟悉OPENGL在WIN32平臺(tái)下的相關(guān)API,以及其余WINDOWS窗口交互的相關(guān)接口方法,來(lái)構(gòu)建窗口的內(nèi)容。其次,熟悉了解OPENGL庫(kù)函數(shù)在窗體中實(shí)現(xiàn)繪圖,實(shí)現(xiàn)圖形的旋轉(zhuǎn)、光照、紋理等功能的相關(guān)函數(shù)。最后,實(shí)現(xiàn)OPENGL與WINDOWS的交互的過(guò)程,完成程序及注釋。3.2 OPENGL圖形庫(kù)簡(jiǎn)介3.2.1 OPENGL特點(diǎn) 從程序開(kāi)發(fā)人員的角度來(lái)看,OpenGL 是一組繪圖命令的API 集合。利用這些API 能夠方便地描述二維和三維
5、幾何物體,并控制這些物體按某種方式繪制到顯示緩沖區(qū)中。OpenGL 的API 集合提供了物體描述、平移、旋轉(zhuǎn)、縮放、光照、紋理、材質(zhì)、象素、位圖、文字、交互以及提高顯示性能等方面的功能,根本涵蓋了開(kāi)發(fā)二、三維圖形程序所需的各個(gè)方面。與一般的圖形開(kāi)發(fā)工具相比,OpenGL 具有以下幾個(gè)突出特點(diǎn):(1)應(yīng)用廣泛 (2)跨平臺(tái)性 (3)高質(zhì)量和高性能 (4)出色的編程特性 (5)網(wǎng)絡(luò)透明性3.2.2 OPENGL工作順序 OpenGL 的工作順序就是一個(gè)從定義幾何要素到把象素段寫(xiě)入幀緩沖區(qū)的過(guò)程。在屏幕上顯示圖象的主要步驟是以下3 步:1構(gòu)造幾何要素(點(diǎn)、線、多邊形、圖像、位圖),創(chuàng)立對(duì)象的數(shù)學(xué)描述
6、。在三維空間放置對(duì)象,選擇有利的觀察點(diǎn)。2計(jì)算對(duì)象的顏色,這些顏色可能直接定義,或由光照條件及紋理間接給出。3光柵化,把對(duì)象的數(shù)學(xué)描述和顏色信息轉(zhuǎn)換到屏幕的象素。3.3 OPENGL簡(jiǎn)單編程方法3.3.1 OPENGL根本語(yǔ)法 OpenGL 根本函數(shù)均使用gl 作為函數(shù)名的前綴,如glClearColor();實(shí)用函數(shù)那么使用glu 作為函數(shù)名的前綴,如gluSphere()。OpenGL 根本常量的名字以GL_開(kāi)頭,如GL_LINE_LOOP;實(shí)用常量的名字以GLU_開(kāi)頭,如GLU_FILL。一些函數(shù)如glColor*()(定義顏色值),函數(shù)名后可以接不同的后綴以支持不同的數(shù)據(jù)類(lèi)型和格式。如
7、glColor3b()、glColor3d()、glColor3f()和glColor3bv()等,這幾個(gè)函數(shù)在功能上是相似的,只是適用于不同的數(shù)據(jù)類(lèi)型和格式,其中3 表示該函數(shù)帶有三個(gè)參數(shù),b、d、f 分別表示參數(shù)的類(lèi)型是字節(jié)型、雙精度浮點(diǎn)型和單精度浮點(diǎn)型,v 那么表示這些參數(shù)是以向量數(shù)組形式出現(xiàn)的。OpenGL 還定義了一些特殊的類(lèi)型名,如GLfloat,GLvoid。它們其實(shí)就是C 中的float 和void。在gl.h 文件中可以看到以下定義:typedef float GLfloat;typedef void GLvoid;一些根本的數(shù)據(jù)類(lèi)型都有類(lèi)似的定義。3.3.2 OPENGL狀
8、態(tài)機(jī)制 OpenGL 的工作方式是一種狀態(tài)機(jī)制,它可以進(jìn)行各種狀態(tài)或模式設(shè)置,這些狀態(tài)或模式在重新改變它們之前一直有效。例如,當(dāng)前顏色就是一個(gè)狀態(tài)變量,在這個(gè)狀態(tài)改變之前,繪制的每個(gè)象素都將使用該顏色,直到當(dāng)前顏色被設(shè)置為其它顏色為止。OpenGL 中大量地使用了這種狀態(tài)機(jī)制,如顏色模式、投影模式、單雙顯示緩存區(qū)的設(shè)置、背景色的設(shè)置、光源的位置和特性等等。3.3.3 OPENGL根本結(jié)構(gòu) OpenGL 程序的根本結(jié)構(gòu)可分為三個(gè)局部: 第一局部是初始化局部,主要是設(shè)置一些OpenGL 的狀態(tài)開(kāi)關(guān),如顏色模式(RGBA 或ALPHA 等)的選擇,是否作光照處理(假設(shè)有的話,還需設(shè)置光源的特性),深
9、度檢驗(yàn),裁剪等等。這些狀態(tài)一般都用函數(shù)glEnable(),glDisable()來(lái)設(shè)置,中為相應(yīng)的狀態(tài)。第二局部設(shè)置觀察坐標(biāo)系下的取景模式和取景框位置及大小。主要利用了三個(gè)函數(shù):1 函數(shù)void glViewport(left, top, right, bottom):設(shè)置在屏幕上的窗口大小,四個(gè)參數(shù)描述屏幕窗口四個(gè)邊界坐標(biāo)(以象素表示);2函數(shù)void glOrtho(left, right, bottom, top, near, far):設(shè)置投影方式為正交投影(平行投影),其取景體積觀察體是一個(gè)各面均為矩形的六面體;3函數(shù)void gluPerspective(fovy, aspect
10、, zNear, zFar):設(shè)置投影方式為透視投影,其取景體積觀察體是一個(gè)截頭錐體棱臺(tái),在這個(gè)體積內(nèi)的物體投影到錐體的頂點(diǎn)。第三局部是OpenGL 的主要局部,使用OpenGL 的庫(kù)函數(shù)構(gòu)造幾何物體對(duì)象的數(shù)學(xué)描述,包括點(diǎn)線面的位置和拓?fù)潢P(guān)系,幾何變換,光照處理等。3.4 OPENGL及WINDOWS 坐標(biāo)系OPENGL的三維坐標(biāo)系如圖3-1所示:XOY平面為屏幕所在ZXYO圖3-1 OPENGL三維坐標(biāo)系WINDOWS的窗體坐標(biāo)如圖3-2所示:XYO圖3-2WINDOWS窗體二維坐標(biāo)系3.5、WINDOWS消息機(jī)制 消息機(jī)制是Windows應(yīng)用程序的核心,在Windows中發(fā)生的一切都可以用
11、消息來(lái)表示,消息用于告訴操作系統(tǒng)發(fā)生了什么,所有的Windows應(yīng)用程序都是消息驅(qū)動(dòng)的,除了WM_COMMAND消息,所有以WM_為前綴的消息都是標(biāo)準(zhǔn)的Windows消息,如窗口、鼠標(biāo)移動(dòng)、窗口大小改變等,程序啟動(dòng)或退出甚至每一段固定的時(shí)間都會(huì)產(chǎn)生標(biāo)準(zhǔn)Windows消息。Windows消息控制中心一般是三層結(jié)構(gòu),其頂端就是Windows內(nèi)核。Windows內(nèi)核維護(hù)著一個(gè)消息隊(duì)列,第二級(jí)控制中心從這個(gè)消息隊(duì)列中獲取屬于自己管轄的消息,后做出處理,有些消息直接處理掉,有些還要發(fā)送給下一級(jí)窗體(Window)或控件Control。第二級(jí)控制中心一般是各Windows應(yīng)用程序的Application對(duì)
12、象。第三級(jí)控制中心就是Windows窗體對(duì)象,每一個(gè)窗體都有一個(gè)默認(rèn)的窗體過(guò)程,這個(gè)過(guò)程負(fù)責(zé)處理各種接收到的消息。1、消息的組成:一個(gè)消息由一個(gè)消息名稱(chēng)UINT,和兩個(gè)參數(shù)WPARAM,LPARAM。當(dāng)用戶(hù)進(jìn)行了輸入或是窗口的狀態(tài)發(fā)生改變時(shí)系統(tǒng)都會(huì)發(fā)送消息到某一個(gè)窗口。例如當(dāng)菜單轉(zhuǎn)中之后會(huì)有WM_COMMAND消息發(fā)送,WPARAM的高字中HIWORD(wParam)是命令的ID號(hào),對(duì)菜單來(lái)講就是菜單ID。當(dāng)然用戶(hù)也可以定義自己的消息名稱(chēng),也可以利用自定義消息來(lái)發(fā)送通知和傳送數(shù)據(jù)。2、誰(shuí)將收到消息:一個(gè)消息必須由一個(gè)窗口接收。在窗口的過(guò)程WNDPROC中可以對(duì)消息進(jìn)行分析,對(duì)自己感興趣的消息進(jìn)
13、行處理。例如你希望對(duì)菜單項(xiàng)選擇擇進(jìn)行處理那么你可以定義對(duì)WM_COMMAND進(jìn)行處理的代碼,如果希望在窗口中進(jìn)行圖形輸出就必須對(duì)WM_PAINT進(jìn)行處理。3、未處理的消息到那里去了:M$為窗口編寫(xiě)了默認(rèn)的窗口過(guò)程,這個(gè)窗口過(guò)程將負(fù)責(zé)處理那些你不處理消息。正因?yàn)橛辛诉@個(gè)默認(rèn)窗口過(guò)程我們才可以利用Windows的窗口進(jìn)行開(kāi)發(fā)而不必過(guò)多關(guān)注窗口各種消息的處理。例如窗口在被拖動(dòng)時(shí)會(huì)有很多消息發(fā)送,而我們都可以不予理睬讓系統(tǒng)自己去處理。4、窗口句柄:說(shuō)到消息就不能不說(shuō)窗口句柄,系統(tǒng)通過(guò)窗口句柄來(lái)在整個(gè)系統(tǒng)中唯一標(biāo)識(shí)一個(gè)窗口,發(fā)送一個(gè)消息時(shí)必須指定一個(gè)窗口句柄說(shuō)明該消息由那個(gè)窗口接收。而每個(gè)窗口都會(huì)有自己
14、的窗口過(guò)程,所以用戶(hù)的輸入就會(huì)被正確的處理。例如有兩個(gè)窗口共用一個(gè)窗口過(guò)程代碼,你在窗口一上按下鼠標(biāo)時(shí)消息就會(huì)通過(guò)窗口一的句柄被發(fā)送到窗口一而不是窗口二。一個(gè)消息從產(chǎn)生到被一個(gè)窗口響應(yīng),其中有5個(gè)步驟: 1) 系統(tǒng)中發(fā)生了某個(gè)事件。 2) Windows把這個(gè)事件翻譯為消息,然后把它放到消息隊(duì)列中。 3) 應(yīng)用程序從消息隊(duì)列中接收到這個(gè)消息,把它存放在TMsg記錄中。 4) 應(yīng)用程序把消息傳遞給一個(gè)適當(dāng)?shù)拇翱诘拇翱谶^(guò)程。 5) 窗口過(guò)程響應(yīng)這個(gè)消息并進(jìn)行處理。 步驟3和4構(gòu)成了應(yīng)用程序的消息循環(huán)。消息循環(huán)往往是Windows應(yīng)用程序的核心,因?yàn)橄⒀h(huán) 使一個(gè)應(yīng)用程序能夠響應(yīng)外部的事件。消息循
15、環(huán)的任務(wù)就是從消息隊(duì)列中檢索消息,然后把消息傳遞給適當(dāng)?shù)拇翱凇H绻㈥?duì)列中沒(méi)有消息,Windows就允許其他應(yīng)用程序處理它們的消息。 Windows操作系統(tǒng)最大的特點(diǎn)就是其圖形化的操作界面,其圖形化界面是建立在其消息處理機(jī)制這個(gè)根底之上的3.6 大體設(shè)計(jì)方案綜上所述,在本程序中。首先使用相關(guān)的WINDOWS API創(chuàng)立窗口,其次實(shí)現(xiàn)程序的相應(yīng)功能:1 使用OPENGL相應(yīng)庫(kù)函數(shù)畫(huà)出三維圖形。2 使之旋轉(zhuǎn)起來(lái)。3 在窗體中響應(yīng)鼠標(biāo)事件,控制正方體的旋轉(zhuǎn)。程序流程圖如圖3-3所示:WINMAIN主程序?qū)⒊绦蚣せ畈⑦M(jìn)入消息循環(huán)程序激活由CreateGLWindow()創(chuàng)立窗體創(chuàng)立窗體成功由函數(shù)In
16、itialize()初始化OPENGL調(diào)用相關(guān)參數(shù)由Draw()在窗體中實(shí)現(xiàn)繪圖旋轉(zhuǎn)由LoadTexture()實(shí)現(xiàn)紋理貼圖 程序完成由DestroyWindowGL()銷(xiāo)毀窗口,推出消息循環(huán),結(jié)束程序。圖3-3 程序流程圖程序的大體內(nèi)容以及機(jī)構(gòu)已經(jīng)構(gòu)造成型,功能局部還需要進(jìn)一步的細(xì)化。顯然在消息循環(huán)中的內(nèi)容還遠(yuǎn)不止這些,還需參加響應(yīng)以下事件:1 當(dāng)窗口大小發(fā)生變化時(shí),重置窗口。2 響應(yīng)鼠標(biāo)事件,并改變相對(duì)應(yīng)的參數(shù)值,來(lái)改變旋轉(zhuǎn)速度。3 響應(yīng)窗口中斷事件,如關(guān)閉事件、屏保事件。4四、詳細(xì)設(shè)計(jì)4.1 OPENGL的繪制工作上面提到完成OPENGL的繪制工作主有兩個(gè)主要方面的工作需要完成:1OPE
17、NGL的初始化。2OPENGL的繪制工作,其中包括了是圖形旋轉(zhuǎn),紋理。以下我們分別來(lái)完成。4.1.1 OPENGL的初始化工作通過(guò)查找資料OPENGL的初始化工作由如下庫(kù)函數(shù)過(guò)程來(lái)完成glShadeModel(GL_SMOOTH); / 啟用陰影平滑啟用smooth shading(陰影平滑)。陰影平滑通過(guò)多邊形精細(xì)的混合色彩,并對(duì)外部光進(jìn)行平滑。glClearColor(1.0f, 0.0f, 1.0f, 0.5f); / 紫色背景色彩值的范圍從0.0f到1.0f。0.0f代表最黑的情況,1.0f就是最亮的情況。glClearColor 后的第一個(gè)參數(shù)是Red Intensity(紅色分量)
18、,第二個(gè)是綠色,第三個(gè)是藍(lán)色。最大值也是1.0f,代表特定顏色分量的最亮情況。接下來(lái)的三個(gè)函數(shù)必須做的是關(guān)于depth buffer(深度緩存)的。將深度緩存設(shè)想為屏幕后面的層。深度緩存不斷的對(duì)物體進(jìn)入屏幕內(nèi)部有多深進(jìn)行跟蹤。幾乎所有在屏幕上顯示3D場(chǎng)景OpenGL程序都使用深度緩存。它的排序決定那個(gè)物體先畫(huà)。這樣您就不會(huì)將一個(gè)圓形后面的正方形畫(huà)到圓形上來(lái)。深度緩存是OpenGL十分重要的局部。glClearDepth(1.0f); / 設(shè)置深度緩存glEnable(GL_DEPTH_TEST); / 啟用深度測(cè)試glDepthFunc(GL_LEQUAL); / 所作深度測(cè)試的類(lèi)型接下來(lái)是透
19、視圖修飾使透視圖好看些:glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);/ 真正精細(xì)的透視修正4.1.2 OPENGL的主體繪制工作首先使用glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 去除屏幕和深度緩存然后使用glLoadIdentity();重置當(dāng)前的模型觀察矩陣,確定繪制好圖形的位置glTranslatef(0.0f,0.0f,z);移入屏幕 z 個(gè)單位。函數(shù)glTranslatef(x, y, z)作用為沿著 X, Y 和 Z 軸移動(dòng)。繪制圖形函數(shù):void Draw (voi
20、d)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/ 清晰的畫(huà)面和深度緩沖glLoadIdentity();/ 重置當(dāng)前點(diǎn)矩陣glTranslatef(-1.5f,0.0f,-6.0f);/ 往左移到屏幕上1.5個(gè)單位為6.0 glPushMatrix();/ 準(zhǔn)備動(dòng)態(tài)改變 glMultMatrixf(Transform.M);/ 采用動(dòng)態(tài)變換glColor3f(0.75f,0.75f,1.0f);/glBindTexture(GL_TEXTURE_2D, texture0);Torus(0.30f,1.00f); glPopMatrix
21、(); glLoadIdentity();glTranslatef(1.5f,0.0f,-6.0f); glPushMatrix(); glMultMatrixf(Transform.M);glColor3f(1.0f,0.75f,0.75f);glBindTexture(GL_TEXTURE_2D, texture1);gluSphere(quadratic,1.3f,20,20); glPopMatrix();glFlush ();/ 刷新4.2 鼠標(biāo)控制圖形的旋轉(zhuǎn)首先我們把鼠標(biāo)坐標(biāo)映射到-1,1之間,它很簡(jiǎn)單:MousePt.X = (MousePt.X / (Width -1) / 2
22、) -1);MousePt.Y = -(MousePt.Y / (Height -1) / 2)-1);下面我們計(jì)算這個(gè)長(zhǎng)度,如果它大于軌跡球的邊界,我們將簡(jiǎn)單的把z軸設(shè)為0,否那么我們把z軸設(shè)置為這個(gè)二維點(diǎn)映射到球面上對(duì)應(yīng)的z值。 一旦我們有了兩個(gè)點(diǎn),就可以計(jì)算它的法向量了和旋轉(zhuǎn)角了。下面我們從構(gòu)造函數(shù)開(kāi)始,完整的講解這個(gè)類(lèi):ArcBall_t:ArcBall_t(GLfloat NewWidth, GLfloat NewHeight)當(dāng)點(diǎn)擊鼠標(biāo)時(shí),記錄點(diǎn)擊的位置 void ArcBall_t:click(const Point2fT* NewPt)當(dāng)拖動(dòng)鼠標(biāo)時(shí),記錄當(dāng)前鼠標(biāo)的位置,并計(jì)算出
23、旋轉(zhuǎn)的量。void ArcBall_t:drag(const Point2fT* NewPt, Quat4fT* NewRot)如果窗口大小改變,設(shè)置鼠標(biāo)移動(dòng)的范圍void ArcBall_t:setBounds(GLfloat NewWidth, GLfloat NewHeight)下面是完成計(jì)算所要用到的數(shù)據(jù)結(jié)果,都是一些矩陣和向量Matrix4fT Transform = 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ;Matrix3fT Las
24、tRot = 1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f, 0.0f, 1.0f ;Matrix3fT ThisRot = 1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f, 0.0f, 1.0f ;ArcBallT ArcBall(640.0f, 480.0f);Point2fT MousePt;bool isClicked = false; / 是否點(diǎn)擊鼠標(biāo)bool isRClicked = false; / 是否右擊鼠標(biāo)bool isDragging = false; / 是否拖動(dòng)為了更新鼠標(biāo)的移動(dòng)范圍,我們?cè)诤瘮?shù)Reshap
25、eGL中參加下面一行:void ReshapeGL (int width, int height) . . . ArcBall.setBounds(GLfloat)width, (GLfloat)height); / 更新鼠標(biāo)的移動(dòng)范圍/ 處理鼠標(biāo)的按鍵操作LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam). . .case WM_MOUSEMOVE:MousePt.s.X = (GLfloat)LOWORD(lParam);MousePt.s.Y = (GLfloat)HIWORD(
26、lParam);isClicked = (LOWORD(wParam) & MK_LBUTTON) true : false;isRClicked = (LOWORD(wParam) & MK_RBUTTON) true : false;break;case WM_LBUTTONUP: isClicked = false; break;case WM_RBUTTONUP: isRClicked = false; break;case WM_LBUTTONDOWN: isClicked = true; break;case WM_RBUTTONDOWN: isRClicked =
27、 true; break;. . .4.3三維模型紋理映射紋理映射是一個(gè)相當(dāng)復(fù)雜的過(guò)程,這節(jié)只簡(jiǎn)單地表達(dá)一下最根本的執(zhí)行紋理映射所需的步驟。根本步驟如下: 一、定義紋理; 二、控制濾波; 三、說(shuō)明映射方式; 四、繪制場(chǎng)景,給出頂點(diǎn)的紋理坐標(biāo)和幾何坐標(biāo)。二維紋理定義的函數(shù)是:void glTexImage2D(GLenum target,GLint level,GLint components,GLsizei width, glsizei height,GLint border,GLenum format,GLenum type, const GLvoid *pixels);4.4重置OPENG
28、L窗口下面的代碼的作用是重新設(shè)置OpenGL場(chǎng)景的大小,而不管窗口的大小是否已經(jīng)改變(假定您沒(méi)有使用全屏模式)。甚至您無(wú)法改變窗口的大小時(shí)(例如您在全屏模式下),它至少仍將運(yùn)行一次-在程序開(kāi)始時(shí)設(shè)置我們的透視圖。OpenGL場(chǎng)景的尺寸將被設(shè)置成它顯示時(shí)所在窗口的大小。GLvoid ReSizeGLScene(GLsizei width, GLsizei height)/ 重置OpenGL窗口大小if (height=0)/ 防止被零除height=1;/ 將Height設(shè)為1glViewport(0, 0, width, height);/ 重置當(dāng)前的視口下面幾行為透視圖設(shè)置屏幕。意味著越遠(yuǎn)的
29、東西看起來(lái)越小。這么做創(chuàng)立了一個(gè)現(xiàn)實(shí)外觀的場(chǎng)景。此處透視按照基于窗口寬度和高度的45度視角來(lái)計(jì)算。0.1f,100.0f是我們?cè)趫?chǎng)景中所能繪制深度的起點(diǎn)和終點(diǎn)。 glMatrixMode(GL_PROJECTION)指明接下來(lái)的兩行代碼將影響projection matrix(投影矩陣)。投影矩陣負(fù)責(zé)為我們的場(chǎng)景增加透視。 glLoadIdentity()近似于重置。它將所選的矩陣狀態(tài)恢復(fù)成其原始狀態(tài)。調(diào)用 glLoadIdentity()之后我們?yōu)閳?chǎng)景設(shè)置透視圖。glMatrixMode(GL_MODELVIEW)指明任何新的變換將會(huì)影響 modelview matrix(模型觀察矩陣)。模
30、型觀察矩陣中存放了我們的物體訊息。最后我們重置模型觀察矩陣glMatrixMode(GL_PROJECTION);/ 選擇投影矩陣glLoadIdentity();/ 重置投影矩陣/ 設(shè)置視口的大小gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);/ 選擇模型觀察矩陣glLoadIdentity();/ 重置模型觀察矩陣4.4 WINDOWS中OPENGL窗體設(shè)置及創(chuàng)立 WINDOWS中OPENGL的窗體的設(shè)置及創(chuàng)立主要有以下幾個(gè)大的方面,其中具體細(xì)節(jié)不再闡述:
31、1相關(guān)變量的設(shè)置HGLRC hRC=NULL;/ 窗口著色描述表句柄HDC hDC=NULL;/ OpenGL渲染描述表句柄HWND hWnd=NULL;/ 保存我們的窗口句柄HINSTANCE hInstance;/ 保存程序的實(shí)例第一行設(shè)置的變量是Rendering Context(著色描述表)。每一個(gè)OpenGL都被連接到一個(gè)著色描述表上。著色描述表將所有的OpenGL調(diào)用命令連接到Device Context(設(shè)備描述表)上。我將OpenGL的著色描述表定義為 hRC 。要讓您的程序能夠繪制窗口的話,還需要?jiǎng)?chuàng)立一個(gè)設(shè)備描述表,也就是第二行的內(nèi)容。Windows的設(shè)備描述表被定義為 hD
32、C 。DC將窗口連接到GDI(Graphics Device Interface圖形設(shè)備接口)。而RC將OpenGL連接到DC。第三行的變量 hWnd 將保存由Windows給我們的窗口指派的句柄。最后,第四行為我們的程序創(chuàng)立了一個(gè)Instance(實(shí)例)。2取得窗口實(shí)例,定義窗口類(lèi)并注冊(cè)3創(chuàng)立窗口并檢查窗口是否成功創(chuàng)立。我們將傳遞CreateWindowGL()所需的所有參數(shù)。如擴(kuò)展風(fēng)格、類(lèi)名字(與您在注冊(cè)窗口類(lèi)時(shí)所用的名字相同)、窗口標(biāo)題、窗體風(fēng)格、窗體的左上角坐標(biāo)(0,0 是個(gè)平安的選擇)、窗體的寬和高。我們沒(méi)有父窗口,也不想要菜單,這些參數(shù)被設(shè)為NULL。還傳遞了窗口的實(shí)例,最后一個(gè)參
33、數(shù)被設(shè)為NULL。4OPENGL提供了有限數(shù)量的像素模式,它包括的屬性有顏色模式,深度緩沖區(qū),等等內(nèi)容。像素模式與渲染窗口、設(shè)備環(huán)境、以及所支持的數(shù)據(jù)類(lèi)型相關(guān)聯(lián)。在創(chuàng)立一個(gè)渲染環(huán)境之前,必須使用一種適當(dāng)?shù)南袼馗袷?,既PIXELFORMATDESCRIPTO來(lái)進(jìn)行設(shè)置5創(chuàng)立窗口成功并響應(yīng)相應(yīng)的事件。如重置窗口大小和推出。之后將它設(shè)為前端窗口(給它更高的優(yōu)先級(jí)),并將焦點(diǎn)移至此窗口。然后調(diào)用ReshapeGL(int width, int height) 將屏幕的寬度和高度設(shè)置給透視OpenGL屏幕。4.5完成WINDOWS主程序 創(chuàng)立WINDOWS主程序,首先創(chuàng)立OPENGL 窗口,并等待消息。
34、其次響應(yīng)一系列的鼠標(biāo)事件,和鍵盤(pán)事件。最后銷(xiāo)毀窗口,結(jié)束程序。其中的細(xì)節(jié)問(wèn)題不再闡述,見(jiàn)附錄中的完整代碼。五、程序測(cè)試及成果繪制程序在windows XP、VC6.0下成功運(yùn)行,記錄其各功能截圖如下: 1.程序生成三維真實(shí)感圖形截圖 2.以下兩張圖片是通過(guò)鼠標(biāo)旋轉(zhuǎn)得到的不同視覺(jué)的圖片6、 課程體會(huì)與總結(jié)軟件工程專(zhuān)業(yè)經(jīng)過(guò)三年的課程學(xué)習(xí),已經(jīng)積累了相關(guān)高級(jí)語(yǔ)言程序設(shè)計(jì)的根本知識(shí)。在學(xué)習(xí)了這么多的專(zhuān)業(yè)課程之后,如何表達(dá)本專(zhuān)業(yè)的實(shí)用性在以后的學(xué)習(xí)和生活中,如何能夠更好的應(yīng)用所學(xué)的內(nèi)容成為我一直在思考的問(wèn)題。通過(guò)本次課程設(shè)計(jì):畫(huà)出三維真實(shí)感圖形并使之旋轉(zhuǎn)這一題目,這一題目考察了程序設(shè)計(jì)自頂而下、逐步細(xì)化
35、的相關(guān)根本思想。使用WINDOWS相關(guān)API和時(shí)下流行的OPENGL圖形庫(kù)來(lái)解決程序的核心問(wèn)題。這就很好的表達(dá)了知識(shí)的實(shí)用性原那么。在以后的日子中可能很長(zhǎng)一段時(shí)間里,OPENGL還不會(huì)從歷史舞臺(tái)退去。微軟依舊會(huì)在主流編程平臺(tái)上提供對(duì)OPENGL 的支持。OPENGL結(jié)合WINDOWS并使用C/C+語(yǔ)言來(lái)渲染可視化平面或立體程序的方法,依舊不失為一個(gè)好的途徑。首先特別感謝鄧飛老師,在一開(kāi)始就為我們提供的使用OPENGL 圖形庫(kù)的思路,講解了計(jì)算機(jī)圖形學(xué)的根本思想。感謝黃地龍老師的悉心指導(dǎo)以及對(duì)于WINDOWS坐標(biāo)系的講解。七、參考文獻(xiàn) <<計(jì)算機(jī)圖形學(xué)根底第二版>> 陸楓
36、 何云峰 編著 OPENGL編程指南原書(shū)第七版OPENGL紅寶書(shū)李軍 徐波等(譯) 機(jī)械工業(yè)出版社八、附源代碼1.ArcBall.h /* * * Filename: ArcBall.h */#ifndef _ArcBall_h#define _ArcBall_h#ifdef _DEBUG# include "assert.h"#else# define assert(x) #endif typedef union Tuple2f_t struct GLfloat X, Y; s; GLfloat T2; Tuple2fT; typedef union Tuple3f_t
37、struct GLfloat X, Y, Z; s; GLfloat T3; Tuple3fT; typedef union Tuple4f_t struct GLfloat X, Y, Z, W; s; GLfloat T4; Tuple4fT; typedef union Matrix3f_t struct union GLfloat M00; GLfloat XX; GLfloat SX; ; union GLfloat M10; GLfloat XY; ; union GLfloat M20; GLfloat XZ; ; union GLfloat M01; GLfloat YX; ;
38、 union GLfloat M11; GLfloat YY; GLfloat SY; ; union GLfloat M21; GLfloat YZ; ; union GLfloat M02; GLfloat ZX; ; union GLfloat M12; GLfloat ZY; ; union GLfloat M22; GLfloat ZZ; GLfloat SZ; ; s; GLfloat M9; Matrix3fT; /A single precision floating point 3 by 3 matrix. typedef union Matrix4f_t struct un
39、ion GLfloat M00; GLfloat XX; GLfloat SX; ; union GLfloat M10; GLfloat XY; ; union GLfloat M20; GLfloat XZ; ; union GLfloat M30; GLfloat XW; ; union GLfloat M01; GLfloat YX; ; union GLfloat M11; GLfloat YY; GLfloat SY; ; union GLfloat M21; GLfloat YZ; ; union GLfloat M31; GLfloat YW; ; union GLfloat
40、M02; GLfloat ZX; ; union GLfloat M12; GLfloat ZY; ; union GLfloat M22; GLfloat ZZ; GLfloat SZ; ; union GLfloat M32; GLfloat ZW; ; union GLfloat M03; GLfloat TX; ; union GLfloat M13; GLfloat TY; ; union GLfloat M23; GLfloat TZ; ; union GLfloat M33; GLfloat TW; GLfloat SW; ; s; GLfloat M16; Matrix4fT;
41、 /A single precision floating point 4 by 4 matrix. /"Inherited" types#define Point2fT Tuple2fT #define Quat4fT Tuple4fT #define Vector2fT Tuple2fT #define Vector3fT Tuple3fT #define FuncSqrt sqrtf# define Epsilon 1.0e-5 inline static void Point2fAdd(Point2fT* NewObj, const Tuple2fT* t1) as
42、sert(NewObj && t1); NewObj->s.X += t1->s.X; NewObj->s.Y += t1->s.Y; inline static void Point2fSub(Point2fT* NewObj, const Tuple2fT* t1) assert(NewObj && t1); NewObj->s.X -= t1->s.X; NewObj->s.Y -= t1->s.Y; inline static void Vector3fCross(Vector3fT* NewObj, co
43、nst Vector3fT* v1, const Vector3fT* v2) Vector3fT Result; /safe not to initialize assert(NewObj && v1 && v2); Result.s.X = (v1->s.Y * v2->s.Z) - (v1->s.Z * v2->s.Y); Result.s.Y = (v1->s.Z * v2->s.X) - (v1->s.X * v2->s.Z); Result.s.Z = (v1->s.X * v2->s.Y)
44、 - (v1->s.Y * v2->s.X); *NewObj = Result; inline static GLfloat Vector3fDot(const Vector3fT* NewObj, const Vector3fT* v1) assert(NewObj && v1); return (NewObj->s.X * v1->s.X) + (NewObj->s.Y * v1->s.Y) + (NewObj->s.Z * v1->s.Z); inline static GLfloat Vector3fLengthSqua
45、red(const Vector3fT* NewObj) assert(NewObj); return (NewObj->s.X * NewObj->s.X) + (NewObj->s.Y * NewObj->s.Y) + (NewObj->s.Z * NewObj->s.Z); inline static GLfloat Vector3fLength(const Vector3fT* NewObj) assert(NewObj); return FuncSqrt(Vector3fLengthSquared(NewObj); inline static vo
46、id Matrix3fSetZero(Matrix3fT* NewObj) NewObj->s.M00 = NewObj->s.M01 = NewObj->s.M02 = NewObj->s.M10 = NewObj->s.M11 = NewObj->s.M12 = NewObj->s.M20 = NewObj->s.M21 = NewObj->s.M22 = 0.0f; inline static void Matrix3fSetIdentity(Matrix3fT* NewObj) Matrix3fSetZero(NewObj); /t
47、hen set diagonal as 1 NewObj->s.M00 = NewObj->s.M11 = NewObj->s.M22 = 1.0f; inline static void Matrix3fSetRotationFromQuat4f(Matrix3fT* NewObj, const Quat4fT* q1) GLfloat n, s; GLfloat xs, ys, zs; GLfloat wx, wy, wz; GLfloat xx, xy, xz; GLfloat yy, yz, zz; assert(NewObj && q1); n =
48、(q1->s.X * q1->s.X) + (q1->s.Y * q1->s.Y) + (q1->s.Z * q1->s.Z) + (q1->s.W * q1->s.W); s = (n > 0.0f) (2.0f / n) : 0.0f; xs = q1->s.X * s; ys = q1->s.Y * s; zs = q1->s.Z * s; wx = q1->s.W * xs; wy = q1->s.W * ys; wz = q1->s.W * zs; xx = q1->s.X * xs; x
49、y = q1->s.X * ys; xz = q1->s.X * zs; yy = q1->s.Y * ys; yz = q1->s.Y * zs; zz = q1->s.Z * zs; NewObj->s.XX = 1.0f - (yy + zz); NewObj->s.YX = xy - wz; NewObj->s.ZX = xz + wy; NewObj->s.XY = xy + wz; NewObj->s.YY = 1.0f - (xx + zz); NewObj->s.ZY = yz - wx; NewObj->
50、s.XZ = xz - wy; NewObj->s.YZ = yz + wx; NewObj->s.ZZ = 1.0f - (xx + yy); inline static void Matrix3fMulMatrix3f(Matrix3fT* NewObj, const Matrix3fT* m1) Matrix3fT Result; /safe not to initialize assert(NewObj && m1); / alias-safe way. Result.s.M00 = (NewObj->s.M00 * m1->s.M00) + (NewObj->s.M01 * m1->s.M10) + (NewObj->s.M02 * m1->s.M20); Result.s.M01 = (NewObj->s.M00 * m1->s.M01) + (NewObj->s.M01 * m1->s.M11) + (NewObj->s.M02 * m1->s.M21); Result.s.M02 = (NewObj->s.M0
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年中國(guó)餐具洗滌用品研究報(bào)告
- 2025年度快遞業(yè)務(wù)客戶(hù)關(guān)系管理承包合同
- 2025年度綠色環(huán)保產(chǎn)業(yè)承包經(jīng)營(yíng)合同范本
- 2025年度電梯安全評(píng)估與整改服務(wù)合同
- 2025年度電子商務(wù)行業(yè)區(qū)塊鏈技術(shù)應(yīng)用合同
- 班級(jí)志愿者活動(dòng)計(jì)劃
- 團(tuán)隊(duì)激勵(lì)機(jī)制的設(shè)計(jì)計(jì)劃
- 促進(jìn)員工團(tuán)隊(duì)意識(shí)的措施計(jì)劃
- 理論學(xué)習(xí)與實(shí)踐應(yīng)用的結(jié)合計(jì)劃
- 績(jī)效考核體系年度優(yōu)化計(jì)劃
- 學(xué)前比較教育第二版全套教學(xué)課件
- 危重癥呼吸支持治療
- 操作工考核評(píng)分表
- 不忘教育初心-牢記教師使命課件
- 藥品不良反應(yīng)及不良反應(yīng)報(bào)告課件
- 俄羅斯水資源現(xiàn)狀分析
- FSC認(rèn)證培訓(xùn)材料
- 非法捕撈水產(chǎn)品罪
- Germany introduction2-德國(guó)國(guó)家介紹2
- 新概念第一冊(cè)單詞匯總帶音標(biāo)EXCEL版
- 作用于血液及造血器官的藥 作用于血液系統(tǒng)藥物
評(píng)論
0/150
提交評(píng)論