計算機圖形學(xué)課程設(shè)計三維真實感圖形設(shè)計與繪制_第1頁
計算機圖形學(xué)課程設(shè)計三維真實感圖形設(shè)計與繪制_第2頁
計算機圖形學(xué)課程設(shè)計三維真實感圖形設(shè)計與繪制_第3頁
計算機圖形學(xué)課程設(shè)計三維真實感圖形設(shè)計與繪制_第4頁
計算機圖形學(xué)課程設(shè)計三維真實感圖形設(shè)計與繪制_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、word計 算 機 圖 形 學(xué)課程設(shè)計報告一、實驗題目三維真實感圖形設(shè)計與繪制1題目內(nèi)容說明:此題目要求應(yīng)用OpenGL的光照技術(shù)和紋理技術(shù)實現(xiàn)一個簡單的三維真實感圖形的程序設(shè)計。具體要求實現(xiàn)功能: 1通過對話方式實現(xiàn)交互式設(shè)計光照模型功能。 2實現(xiàn)三維模型紋理映射功能 3用鼠標(biāo)跟蹤球方法實現(xiàn)三維模型的空間旋轉(zhuǎn)2實現(xiàn)鼠標(biāo)跟蹤球方法程序二、需求分析真實感圖形的設(shè)計與繪制,是計算機圖形學(xué)中的一個重要研究領(lǐng)域,也是三維實體造型系統(tǒng)和特征造型系統(tǒng)的重要組成局部。一般地,三維實體在計算機顯示屏上有三種表現(xiàn)形式:簡單線框圖、線框消隱圖和真實感圖形。其中,簡單線框圖能夠粗略表達(dá)實體的形狀,但由于簡單線框圖的

2、二義性,從而導(dǎo)致表達(dá)其的實體形狀具有不確定性。而線框消隱圖雖然能反映實體各外表間的相互遮擋關(guān)系,從而到達(dá)消除簡單線框圖產(chǎn)生的二義性的目的,但是這兩者一樣地只能反映實體的幾何形狀和實體間的相互關(guān)系,而不能反映實體外表的特征,如外表的顏色、材質(zhì)、紋理等。所以,只有真實感圖形才能表現(xiàn)實體的這些特征,因此,在三維實體造型中,生成三維實體的光照模型,進(jìn)行實體的真實感繪制與顯示占有重要的地位,是很有必要的,也是我做此設(shè)計的初衷。 在設(shè)計中,我主要使用Opengl繪制真實感圖形,它作為一種強大的三維圖形開發(fā)工具,通過便捷的編程接口提供了處理光照和物體材質(zhì)、顏色屬性等通用功能。真實感圖形學(xué)是計算機圖形的核心內(nèi)

3、容之一,是最能直接反映圖形學(xué)魅力的分支。尋求能準(zhǔn)確地描述客觀世界中各種現(xiàn)象與景觀的數(shù)學(xué)模型,并逼真地再現(xiàn)這些現(xiàn)象與景觀,是圖形學(xué)的一個重要研究課題。很多自然景物難以用幾何模型描述,如煙霧、植物、水波、火焰等。本文所討論的幾種建模及繪制技術(shù)都超越了幾何模型的限制,能夠用簡單的模型描述復(fù)雜的自然景物。在計算機的圖形設(shè)備上實現(xiàn)真實感圖形必須完成的四個根本任務(wù)。1. 三維場景的描述。三維造型。2. 將三維幾何描述轉(zhuǎn)換成為二維透視圖。透視變換。3. 確定場景中的所有可見面。消隱算法,可見面探測算法。4. 計算場景中可見面的顏色。根據(jù)基于光學(xué)物理的光照模型計算可見面投射到觀察者眼中的光亮度大小和色彩組成。

4、三、設(shè)計簡介及設(shè)計方案論述3.1設(shè)計簡介為了實現(xiàn)本程序的兩大功能,方案采用OPENGL圖形庫并調(diào)用一系列WINDOWS API采用C/C+語言編寫。首先,應(yīng)熟悉OPENGL在WIN32平臺下的相關(guān)API,以及其余WINDOWS窗口交互的相關(guān)接口方法,來構(gòu)建窗口的內(nèi)容。其次,熟悉了解OPENGL庫函數(shù)在窗體中實現(xiàn)繪圖,實現(xiàn)圖形的旋轉(zhuǎn)、光照、紋理等功能的相關(guān)函數(shù)。最后,實現(xiàn)OPENGL與WINDOWS的交互的過程,完成程序及注釋。3.2 OPENGL圖形庫簡介3.2.1 OPENGL特點 從程序開發(fā)人員的角度來看,OpenGL 是一組繪圖命令的API 集合。利用這些API 能夠方便地描述二維和三維

5、幾何物體,并控制這些物體按某種方式繪制到顯示緩沖區(qū)中。OpenGL 的API 集合提供了物體描述、平移、旋轉(zhuǎn)、縮放、光照、紋理、材質(zhì)、象素、位圖、文字、交互以及提高顯示性能等方面的功能,根本涵蓋了開發(fā)二、三維圖形程序所需的各個方面。與一般的圖形開發(fā)工具相比,OpenGL 具有以下幾個突出特點:(1)應(yīng)用廣泛 (2)跨平臺性 (3)高質(zhì)量和高性能 (4)出色的編程特性 (5)網(wǎng)絡(luò)透明性3.2.2 OPENGL工作順序 OpenGL 的工作順序就是一個從定義幾何要素到把象素段寫入幀緩沖區(qū)的過程。在屏幕上顯示圖象的主要步驟是以下3 步:1構(gòu)造幾何要素(點、線、多邊形、圖像、位圖),創(chuàng)立對象的數(shù)學(xué)描述

6、。在三維空間放置對象,選擇有利的觀察點。2計算對象的顏色,這些顏色可能直接定義,或由光照條件及紋理間接給出。3光柵化,把對象的數(shù)學(xué)描述和顏色信息轉(zhuǎn)換到屏幕的象素。3.3 OPENGL簡單編程方法3.3.1 OPENGL根本語法 OpenGL 根本函數(shù)均使用gl 作為函數(shù)名的前綴,如glClearColor();實用函數(shù)那么使用glu 作為函數(shù)名的前綴,如gluSphere()。OpenGL 根本常量的名字以GL_開頭,如GL_LINE_LOOP;實用常量的名字以GLU_開頭,如GLU_FILL。一些函數(shù)如glColor*()(定義顏色值),函數(shù)名后可以接不同的后綴以支持不同的數(shù)據(jù)類型和格式。如

7、glColor3b()、glColor3d()、glColor3f()和glColor3bv()等,這幾個函數(shù)在功能上是相似的,只是適用于不同的數(shù)據(jù)類型和格式,其中3 表示該函數(shù)帶有三個參數(shù),b、d、f 分別表示參數(shù)的類型是字節(jié)型、雙精度浮點型和單精度浮點型,v 那么表示這些參數(shù)是以向量數(shù)組形式出現(xiàn)的。OpenGL 還定義了一些特殊的類型名,如GLfloat,GLvoid。它們其實就是C 中的float 和void。在gl.h 文件中可以看到以下定義:typedef float GLfloat;typedef void GLvoid;一些根本的數(shù)據(jù)類型都有類似的定義。3.3.2 OPENGL狀

8、態(tài)機制 OpenGL 的工作方式是一種狀態(tài)機制,它可以進(jìn)行各種狀態(tài)或模式設(shè)置,這些狀態(tài)或模式在重新改變它們之前一直有效。例如,當(dāng)前顏色就是一個狀態(tài)變量,在這個狀態(tài)改變之前,繪制的每個象素都將使用該顏色,直到當(dāng)前顏色被設(shè)置為其它顏色為止。OpenGL 中大量地使用了這種狀態(tài)機制,如顏色模式、投影模式、單雙顯示緩存區(qū)的設(shè)置、背景色的設(shè)置、光源的位置和特性等等。3.3.3 OPENGL根本結(jié)構(gòu) OpenGL 程序的根本結(jié)構(gòu)可分為三個局部: 第一局部是初始化局部,主要是設(shè)置一些OpenGL 的狀態(tài)開關(guān),如顏色模式(RGBA 或ALPHA 等)的選擇,是否作光照處理(假設(shè)有的話,還需設(shè)置光源的特性),深

9、度檢驗,裁剪等等。這些狀態(tài)一般都用函數(shù)glEnable(),glDisable()來設(shè)置,中為相應(yīng)的狀態(tài)。第二局部設(shè)置觀察坐標(biāo)系下的取景模式和取景框位置及大小。主要利用了三個函數(shù):1 函數(shù)void glViewport(left, top, right, bottom):設(shè)置在屏幕上的窗口大小,四個參數(shù)描述屏幕窗口四個邊界坐標(biāo)(以象素表示);2函數(shù)void glOrtho(left, right, bottom, top, near, far):設(shè)置投影方式為正交投影(平行投影),其取景體積觀察體是一個各面均為矩形的六面體;3函數(shù)void gluPerspective(fovy, aspect

10、, zNear, zFar):設(shè)置投影方式為透視投影,其取景體積觀察體是一個截頭錐體棱臺,在這個體積內(nèi)的物體投影到錐體的頂點。第三局部是OpenGL 的主要局部,使用OpenGL 的庫函數(shù)構(gòu)造幾何物體對象的數(shù)學(xué)描述,包括點線面的位置和拓?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消息機制 消息機制是Windows應(yīng)用程序的核心,在Windows中發(fā)生的一切都可以用

11、消息來表示,消息用于告訴操作系統(tǒng)發(fā)生了什么,所有的Windows應(yīng)用程序都是消息驅(qū)動的,除了WM_COMMAND消息,所有以WM_為前綴的消息都是標(biāo)準(zhǔn)的Windows消息,如窗口、鼠標(biāo)移動、窗口大小改變等,程序啟動或退出甚至每一段固定的時間都會產(chǎn)生標(biāo)準(zhǔn)Windows消息。Windows消息控制中心一般是三層結(jié)構(gòu),其頂端就是Windows內(nèi)核。Windows內(nèi)核維護(hù)著一個消息隊列,第二級控制中心從這個消息隊列中獲取屬于自己管轄的消息,后做出處理,有些消息直接處理掉,有些還要發(fā)送給下一級窗體(Window)或控件Control。第二級控制中心一般是各Windows應(yīng)用程序的Application對

12、象。第三級控制中心就是Windows窗體對象,每一個窗體都有一個默認(rèn)的窗體過程,這個過程負(fù)責(zé)處理各種接收到的消息。1、消息的組成:一個消息由一個消息名稱UINT,和兩個參數(shù)WPARAM,LPARAM。當(dāng)用戶進(jìn)行了輸入或是窗口的狀態(tài)發(fā)生改變時系統(tǒng)都會發(fā)送消息到某一個窗口。例如當(dāng)菜單轉(zhuǎn)中之后會有WM_COMMAND消息發(fā)送,WPARAM的高字中HIWORD(wParam)是命令的ID號,對菜單來講就是菜單ID。當(dāng)然用戶也可以定義自己的消息名稱,也可以利用自定義消息來發(fā)送通知和傳送數(shù)據(jù)。2、誰將收到消息:一個消息必須由一個窗口接收。在窗口的過程WNDPROC中可以對消息進(jìn)行分析,對自己感興趣的消息進(jìn)

13、行處理。例如你希望對菜單項選擇擇進(jìn)行處理那么你可以定義對WM_COMMAND進(jìn)行處理的代碼,如果希望在窗口中進(jìn)行圖形輸出就必須對WM_PAINT進(jìn)行處理。3、未處理的消息到那里去了:M$為窗口編寫了默認(rèn)的窗口過程,這個窗口過程將負(fù)責(zé)處理那些你不處理消息。正因為有了這個默認(rèn)窗口過程我們才可以利用Windows的窗口進(jìn)行開發(fā)而不必過多關(guān)注窗口各種消息的處理。例如窗口在被拖動時會有很多消息發(fā)送,而我們都可以不予理睬讓系統(tǒng)自己去處理。4、窗口句柄:說到消息就不能不說窗口句柄,系統(tǒng)通過窗口句柄來在整個系統(tǒng)中唯一標(biāo)識一個窗口,發(fā)送一個消息時必須指定一個窗口句柄說明該消息由那個窗口接收。而每個窗口都會有自己

14、的窗口過程,所以用戶的輸入就會被正確的處理。例如有兩個窗口共用一個窗口過程代碼,你在窗口一上按下鼠標(biāo)時消息就會通過窗口一的句柄被發(fā)送到窗口一而不是窗口二。一個消息從產(chǎn)生到被一個窗口響應(yīng),其中有5個步驟: 1) 系統(tǒng)中發(fā)生了某個事件。 2) Windows把這個事件翻譯為消息,然后把它放到消息隊列中。 3) 應(yīng)用程序從消息隊列中接收到這個消息,把它存放在TMsg記錄中。 4) 應(yīng)用程序把消息傳遞給一個適當(dāng)?shù)拇翱诘拇翱谶^程。 5) 窗口過程響應(yīng)這個消息并進(jìn)行處理。 步驟3和4構(gòu)成了應(yīng)用程序的消息循環(huán)。消息循環(huán)往往是Windows應(yīng)用程序的核心,因為消息循環(huán) 使一個應(yīng)用程序能夠響應(yīng)外部的事件。消息循

15、環(huán)的任務(wù)就是從消息隊列中檢索消息,然后把消息傳遞給適當(dāng)?shù)拇翱?。如果消息隊列中沒有消息,Windows就允許其他應(yīng)用程序處理它們的消息。 Windows操作系統(tǒng)最大的特點就是其圖形化的操作界面,其圖形化界面是建立在其消息處理機制這個根底之上的3.6 大體設(shè)計方案綜上所述,在本程序中。首先使用相關(guān)的WINDOWS API創(chuàng)立窗口,其次實現(xiàn)程序的相應(yīng)功能:1 使用OPENGL相應(yīng)庫函數(shù)畫出三維圖形。2 使之旋轉(zhuǎn)起來。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()在窗體中實現(xiàn)繪圖旋轉(zhuǎn)由LoadTexture()實現(xiàn)紋理貼圖 程序完成由DestroyWindowGL()銷毀窗口,推出消息循環(huán),結(jié)束程序。圖3-3 程序流程圖程序的大體內(nèi)容以及機構(gòu)已經(jīng)構(gòu)造成型,功能局部還需要進(jìn)一步的細(xì)化。顯然在消息循環(huán)中的內(nèi)容還遠(yuǎn)不止這些,還需參加響應(yīng)以下事件:1 當(dāng)窗口大小發(fā)生變化時,重置窗口。2 響應(yīng)鼠標(biāo)事件,并改變相對應(yīng)的參數(shù)值,來改變旋轉(zhuǎn)速度。3 響應(yīng)窗口中斷事件,如關(guān)閉事件、屏保事件。4四、詳細(xì)設(shè)計4.1 OPENGL的繪制工作上面提到完成OPENGL的繪制工作主有兩個主要方面的工作需要完成:1OPE

17、NGL的初始化。2OPENGL的繪制工作,其中包括了是圖形旋轉(zhuǎn),紋理。以下我們分別來完成。4.1.1 OPENGL的初始化工作通過查找資料OPENGL的初始化工作由如下庫函數(shù)過程來完成glShadeModel(GL_SMOOTH); / 啟用陰影平滑啟用smooth shading(陰影平滑)。陰影平滑通過多邊形精細(xì)的混合色彩,并對外部光進(jìn)行平滑。glClearColor(1.0f, 0.0f, 1.0f, 0.5f); / 紫色背景色彩值的范圍從0.0f到1.0f。0.0f代表最黑的情況,1.0f就是最亮的情況。glClearColor 后的第一個參數(shù)是Red Intensity(紅色分量)

18、,第二個是綠色,第三個是藍(lán)色。最大值也是1.0f,代表特定顏色分量的最亮情況。接下來的三個函數(shù)必須做的是關(guān)于depth buffer(深度緩存)的。將深度緩存設(shè)想為屏幕后面的層。深度緩存不斷的對物體進(jìn)入屏幕內(nèi)部有多深進(jìn)行跟蹤。幾乎所有在屏幕上顯示3D場景OpenGL程序都使用深度緩存。它的排序決定那個物體先畫。這樣您就不會將一個圓形后面的正方形畫到圓形上來。深度緩存是OpenGL十分重要的局部。glClearDepth(1.0f); / 設(shè)置深度緩存glEnable(GL_DEPTH_TEST); / 啟用深度測試glDepthFunc(GL_LEQUAL); / 所作深度測試的類型接下來是透

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 個單位。函數(shù)glTranslatef(x, y, z)作用為沿著 X, Y 和 Z 軸移動。繪制圖形函數(shù):void Draw (voi

20、d)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/ 清晰的畫面和深度緩沖glLoadIdentity();/ 重置當(dāng)前點矩陣glTranslatef(-1.5f,0.0f,-6.0f);/ 往左移到屏幕上1.5個單位為6.0 glPushMatrix();/ 準(zhǔn)備動態(tài)改變 glMultMatrixf(Transform.M);/ 采用動態(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之間,它很簡單:MousePt.X = (MousePt.X / (Width -1) / 2

22、) -1);MousePt.Y = -(MousePt.Y / (Height -1) / 2)-1);下面我們計算這個長度,如果它大于軌跡球的邊界,我們將簡單的把z軸設(shè)為0,否那么我們把z軸設(shè)置為這個二維點映射到球面上對應(yīng)的z值。 一旦我們有了兩個點,就可以計算它的法向量了和旋轉(zhuǎn)角了。下面我們從構(gòu)造函數(shù)開始,完整的講解這個類:ArcBall_t:ArcBall_t(GLfloat NewWidth, GLfloat NewHeight)當(dāng)點擊鼠標(biāo)時,記錄點擊的位置 void ArcBall_t:click(const Point2fT* NewPt)當(dāng)拖動鼠標(biāo)時,記錄當(dāng)前鼠標(biāo)的位置,并計算出

23、旋轉(zhuǎn)的量。void ArcBall_t:drag(const Point2fT* NewPt, Quat4fT* NewRot)如果窗口大小改變,設(shè)置鼠標(biāo)移動的范圍void ArcBall_t:setBounds(GLfloat NewWidth, GLfloat NewHeight)下面是完成計算所要用到的數(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; / 是否點擊鼠標(biāo)bool isRClicked = false; / 是否右擊鼠標(biāo)bool isDragging = false; / 是否拖動為了更新鼠標(biāo)的移動范圍,我們在函數(shù)Reshap

25、eGL中參加下面一行:void ReshapeGL (int width, int height) . . . ArcBall.setBounds(GLfloat)width, (GLfloat)height); / 更新鼠標(biāo)的移動范圍/ 處理鼠標(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三維模型紋理映射紋理映射是一個相當(dāng)復(fù)雜的過程,這節(jié)只簡單地表達(dá)一下最根本的執(zhí)行紋理映射所需的步驟。根本步驟如下: 一、定義紋理; 二、控制濾波; 三、說明映射方式; 四、繪制場景,給出頂點的紋理坐標(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場景的大小,而不管窗口的大小是否已經(jīng)改變(假定您沒有使用全屏模式)。甚至您無法改變窗口的大小時(例如您在全屏模式下),它至少仍將運行一次-在程序開始時設(shè)置我們的透視圖。OpenGL場景的尺寸將被設(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、東西看起來越小。這么做創(chuàng)立了一個現(xiàn)實外觀的場景。此處透視按照基于窗口寬度和高度的45度視角來計算。0.1f,100.0f是我們在場景中所能繪制深度的起點和終點。 glMatrixMode(GL_PROJECTION)指明接下來的兩行代碼將影響projection matrix(投影矩陣)。投影矩陣負(fù)責(zé)為我們的場景增加透視。 glLoadIdentity()近似于重置。它將所選的矩陣狀態(tài)恢復(fù)成其原始狀態(tài)。調(diào)用 glLoadIdentity()之后我們?yōu)閳鼍霸O(shè)置透視圖。glMatrixMode(GL_MODELVIEW)指明任何新的變換將會影響 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)立主要有以下幾個大的方面,其中具體細(xì)節(jié)不再闡述:

31、1相關(guān)變量的設(shè)置HGLRC hRC=NULL;/ 窗口著色描述表句柄HDC hDC=NULL;/ OpenGL渲染描述表句柄HWND hWnd=NULL;/ 保存我們的窗口句柄HINSTANCE hInstance;/ 保存程序的實例第一行設(shè)置的變量是Rendering Context(著色描述表)。每一個OpenGL都被連接到一個著色描述表上。著色描述表將所有的OpenGL調(diào)用命令連接到Device Context(設(shè)備描述表)上。我將OpenGL的著色描述表定義為 hRC 。要讓您的程序能夠繪制窗口的話,還需要創(chuàng)立一個設(shè)備描述表,也就是第二行的內(nèi)容。Windows的設(shè)備描述表被定義為 hD

32、C 。DC將窗口連接到GDI(Graphics Device Interface圖形設(shè)備接口)。而RC將OpenGL連接到DC。第三行的變量 hWnd 將保存由Windows給我們的窗口指派的句柄。最后,第四行為我們的程序創(chuàng)立了一個Instance(實例)。2取得窗口實例,定義窗口類并注冊3創(chuàng)立窗口并檢查窗口是否成功創(chuàng)立。我們將傳遞CreateWindowGL()所需的所有參數(shù)。如擴(kuò)展風(fēng)格、類名字(與您在注冊窗口類時所用的名字相同)、窗口標(biāo)題、窗體風(fēng)格、窗體的左上角坐標(biāo)(0,0 是個平安的選擇)、窗體的寬和高。我們沒有父窗口,也不想要菜單,這些參數(shù)被設(shè)為NULL。還傳遞了窗口的實例,最后一個參

33、數(shù)被設(shè)為NULL。4OPENGL提供了有限數(shù)量的像素模式,它包括的屬性有顏色模式,深度緩沖區(qū),等等內(nèi)容。像素模式與渲染窗口、設(shè)備環(huán)境、以及所支持的數(shù)據(jù)類型相關(guān)聯(lián)。在創(chuàng)立一個渲染環(huán)境之前,必須使用一種適當(dāng)?shù)南袼馗袷?,既PIXELFORMATDESCRIPTO來進(jìn)行設(shè)置5創(chuàng)立窗口成功并響應(yīng)相應(yīng)的事件。如重置窗口大小和推出。之后將它設(shè)為前端窗口(給它更高的優(yōu)先級),并將焦點移至此窗口。然后調(diào)用ReshapeGL(int width, int height) 將屏幕的寬度和高度設(shè)置給透視OpenGL屏幕。4.5完成WINDOWS主程序 創(chuàng)立WINDOWS主程序,首先創(chuàng)立OPENGL 窗口,并等待消息。

34、其次響應(yīng)一系列的鼠標(biāo)事件,和鍵盤事件。最后銷毀窗口,結(jié)束程序。其中的細(xì)節(jié)問題不再闡述,見附錄中的完整代碼。五、程序測試及成果繪制程序在windows XP、VC6.0下成功運行,記錄其各功能截圖如下: 1.程序生成三維真實感圖形截圖 2.以下兩張圖片是通過鼠標(biāo)旋轉(zhuǎn)得到的不同視覺的圖片6、 課程體會與總結(jié)軟件工程專業(yè)經(jīng)過三年的課程學(xué)習(xí),已經(jīng)積累了相關(guān)高級語言程序設(shè)計的根本知識。在學(xué)習(xí)了這么多的專業(yè)課程之后,如何表達(dá)本專業(yè)的實用性在以后的學(xué)習(xí)和生活中,如何能夠更好的應(yīng)用所學(xué)的內(nèi)容成為我一直在思考的問題。通過本次課程設(shè)計:畫出三維真實感圖形并使之旋轉(zhuǎn)這一題目,這一題目考察了程序設(shè)計自頂而下、逐步細(xì)化

35、的相關(guān)根本思想。使用WINDOWS相關(guān)API和時下流行的OPENGL圖形庫來解決程序的核心問題。這就很好的表達(dá)了知識的實用性原那么。在以后的日子中可能很長一段時間里,OPENGL還不會從歷史舞臺退去。微軟依舊會在主流編程平臺上提供對OPENGL 的支持。OPENGL結(jié)合WINDOWS并使用C/C+語言來渲染可視化平面或立體程序的方法,依舊不失為一個好的途徑。首先特別感謝鄧飛老師,在一開始就為我們提供的使用OPENGL 圖形庫的思路,講解了計算機圖形學(xué)的根本思想。感謝黃地龍老師的悉心指導(dǎo)以及對于WINDOWS坐標(biāo)系的講解。七、參考文獻(xiàn) <<計算機圖形學(xué)根底第二版>> 陸楓

36、 何云峰 編著 OPENGL編程指南原書第七版OPENGL紅寶書李軍 徐波等(譯) 機械工業(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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論