版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 基于OpenGL的簡單3d游戲的設計與實現(xiàn)</p><p> 姓 名 </p><p> 系 別、 專 業(yè) </p><p> 導 師 、 職 稱 <
2、/p><p> 完 成 時 間 </p><p><b> 目 錄</b></p><p><b> 摘 要Ⅰ</b></p><p>
3、 AbstractⅡ</p><p> 1 OpenGL概述1</p><p> 1.1 OpenGL的特點及功能1</p><p> 1.2 OpenGL工作流程4</p><p> 1.3 OpenGL繪圖流程4</p><p> 2 系統(tǒng)分析與設計5</p><p>
4、; 2.1系統(tǒng)結構總框架設計6</p><p><b> 2.2系統(tǒng)目的7</b></p><p> 3 OpenGL的配置7</p><p> 3.1程序運行環(huán)境的配置7</p><p> 4 基礎類的實現(xiàn)7</p><p> 4.1頭文件包含類Stdafx7</p
5、><p> 4.2向量類Vector8</p><p> 4.3窗口類GLWindow9</p><p> 4.4位圖載入類CBMPLoader10</p><p> 4.4.1 BMP圖像文件格式11</p><p> 4.4.1位圖載入類CBMPLoader流程圖11</p><
6、p> 4.5基本框架的組成12</p><p><b> 5視角控制12</b></p><p> 5.1攝像機類結構圖12</p><p> 5.2設置攝像機的位置12</p><p> 5.3攝像機旋轉功能的實現(xiàn)13</p><p> 6 游戲場景設計16<
7、/p><p> 6.1地面的構造17</p><p> 6.2天空的構造19</p><p><b> 7 模型設計24</b></p><p> 7.1 模型概述24</p><p> 7.2 MD2格式說明24</p><p> 7.3編譯原理25&
8、lt;/p><p> 7.4 讀取MD2文件方法的實現(xiàn)26</p><p><b> 游戲運行截圖27</b></p><p> 注 釋30</p><p><b> 參考文獻31</b></p><p><b> 致 謝32</
9、b></p><p><b> 摘 要</b></p><p> 隨著電腦進入千家萬戶,人們對電腦游戲的要求也越來越高,而3D游戲正滿足人們對這方面的需求。人們對游戲的畫面,動畫的逼真度,易操作性以及游戲的思想,故事情節(jié)越來越重視。許多大型的3D游戲大部分都產自國外,而國內目前對3D游戲的制作還不夠成熟,特別是一些游戲畫面的逼真度,還有游戲的制作思想,以
10、及游戲的可玩性都尚有不足。近幾年國內制作的3D游戲也慢慢上了軌道,在這方面要加大對培養(yǎng)制作游戲人才的力度,力爭做到像《魔獸世界》一樣水平的3D游戲。目前使用openGL實現(xiàn)其游戲畫面方面的效果還是主流之一。本課題就是基于Visual Studio 2005 平臺的3D游戲,雖然目前的程序有些簡單,但這是為制作復雜3D游戲打下基礎。</p><p> 本游戲主要由四個部分組成:視角控制,天空,地面和模型載入。首先
11、要建立一些系統(tǒng)必備的基礎文件,如各種頭文件載入的一個文件集合Stdafx,以方便其他文件調用函數庫里的文件(如OpenGL庫文件,數學函數庫文件等)。在此基礎上建立一些如字體類(組要用來顯示數字的),向量類,位圖載入類和系統(tǒng)基礎框架類等系統(tǒng)運行必備的一些基礎類。建立好了這些游戲運行必備的一些基礎類后,我們就可以建立天空類,地形類了。然后用一個SkyAndTerrain把這兩個文件封裝起來。</p><p> 關
12、鍵詞:電腦;3D游戲;OpenGL;Visual Studio 2005</p><p><b> Abstract</b></p><p> With computers in every household, people are demanding more and more computer games, whereas the 3D game is to
13、 meet the needs of people in this area. People on the game screen, animation is realistic, easy to operate and game ideas, more and more emphasis on storyline. Many large-scale 3D game produced in most foreign countries,
14、 while domestic production of the current 3D game is not mature enough yet, especially the fidelity of the game screen, there are the production thought the game, and ga</p><p> 1 OpenGL概述</p><p&
15、gt; OpenGL作為一個性能優(yōu)越的圖形應用程序設計界面(API)適合于廣泛的計算機環(huán)境,從個人計算機、工作站到超級計算機,OpenGL都能實現(xiàn)高性能的三維圖形功能。由于許多在計算機界具有領導地位的計算機公司紛紛采用OpenGL作為三維圖形應用程序設計界面,OpenGL應用程序具有廣泛的移植性。OpenGL已成為目前的三維圖形開發(fā)標準。</p><p> OpenGL(OpenGL Graphics Lib
16、rary,開發(fā)性圖形庫)是目前用于開發(fā)可移植的、可交換的2D和3D圖形應用程序的首選環(huán)境,是行業(yè)領域中最為廣泛接納的2D/3D圖形API,也是目前應用最為廣泛的計算機圖形標準,其自誕生至今已催生了各種計算機平臺及設備上的數千優(yōu)秀應用程序。通過對OpenGL的特點、功能、工作流程和繪圖流程的學習,我們將會對OpenGL有一個初步的了解,建立起基本的概念。</p><p> 1.1 OpenGL的特點及功能<
17、/p><p> OpenGL作為一個性能優(yōu)越的圖形應用程序設計界面,具有以下幾個特點,如圖1.1所示</p><p> 圖1.1 OpenGL特點</p><p> 1.1.1 OpenGL的特點 [1]</p><p> 圖形質量高、性能好:在CAD/CAM/CAE、醫(yī)學圖像處理、虛擬實現(xiàn)、娛樂、廣告等不同領域中,開發(fā)人員可以利用Ope
18、nGL的這些能力自由發(fā)揮自己的創(chuàng)造力。</p><p> 標準化:OpenGL是唯一真正開放的、獨立于供應商的跨平臺的圖形標準。</p><p> 穩(wěn)定性:OpenGL已經在各種平臺上應用多年,它具有明確而控制良好的規(guī)范,并具有向后兼容性,使現(xiàn)有的應用程序不會失效。</p><p> 可靠性和可移植性:利用OpenGL技術開發(fā)的應用圖形軟件與硬件無關,只要硬件
19、支持OpenGL API 標準就可以了,也就是說,OpenGL應用可以運行在支持OpenGL API標準的任何硬件上。</p><p> 可擴展性:通過OpenGL擴展機制,可以利用API進行功能擴充。如今,許多OpenGL開發(fā)商在OpenGL核心技術規(guī)范的基礎上,增強了圖形繪制功能,從而使O</p><p> +能緊跟最新硬件發(fā)展和計算機圖形繪制算法的發(fā)展。對于硬件特性的升級可以體現(xiàn)
20、在OpenGL擴展機制及OpenGL API 中,一個成功的OpenGL擴展會被融入在未來的OpenGL版本中。</p><p> 可縮放性:基于OpenGL的應用程序可以在各種平臺上運行。</p><p> 易用性:OpenGL具有良好的結構、直觀的設計和邏輯命令。與其他的圖形程序包相比,OpenGL應用程序的代碼行數少。此外,OpenGL封裝了有關基本硬件信息,使開發(fā)人員無須針對具
21、體的硬件進行專門的設計。</p><p> 靈活性:盡管OpenGL有一套獨特的圖形處理標準,但各平臺開發(fā)商可以自由地開發(fā)適合各自系統(tǒng)的OpenGL執(zhí)行實例。在這些實例中,OpenGL功能可由特定的硬件實現(xiàn),也可用純軟件例程實現(xiàn),或者以軟硬件結合的方式實現(xiàn)。</p><p> 1.1.2 OpenGL的七大功能</p><p><b> 如圖1.2所
22、示:</b></p><p> 圖1.2 OpenGL功能</p><p><b> 各功能說明如下:</b></p><p> 建模:OpenGL圖形庫除了提供基本的點、線、多邊形的繪制函數外,還提供了復雜的三維物體(球,錐,多面體,茶壺等),以及復雜曲線和曲面(例如Bezier、Nurbs等曲線或曲面)繪制函數。</
23、p><p> 變換:OpenGL圖形庫的變換包括基本變換和投影變換?;咀儞Q有平移、旋轉、變比、鏡像4種變換,投影變換有平行投影(又稱正射投影)和透視投影兩種變換。</p><p> 顏色模式設置:OpenGL顏色模式有兩種,即RGBA模式和顏色索引模式(Color Index)模式。</p><p> 紋理映射(Texture Mapping):利用OpenGL
24、紋理映射功能可以十分逼真的表現(xiàn)物體表面細節(jié)。</p><p> 光照和材質設置:OpenGL光有輻射光(Emitted Light)、環(huán)境光(Ambient Light)、慢反射光(Biffuse Light)和鏡面光(Specular Light)。材質是用光反射率來表示。場景(Scene)中物體最終反映到人眼的顏色是紅、綠、藍、分量與材質紅、綠、藍分量的反射率相乘后形成的顏色。</p><
25、;p> 雙緩存動畫(Double Buffering):雙緩存即前臺緩存和后天緩存。后臺緩存計算場景、生產動畫,前天緩存顯示后臺緩存已經畫好的畫面。</p><p> 特殊效果:利用OpenGL還能實現(xiàn)深度暗示(Depth Cue)、運動模糊(Motion Blur)、融合(Blending)、反走樣(Antialiasing)和霧(Fog)等特殊效果。運動模糊和繪圖方式(motion-blured),
26、模擬物體運動時人眼觀察說感覺的動感現(xiàn)象。深度域效果(depth-of-effects)類似于照相機的鏡頭效果,模型在聚焦點處清晰,反之則模糊。</p><p> 1.2 OpenGL工作流程</p><p> OpenGL被設計成獨立于硬件、以流水線的方式工作,工作流程圖如圖3所示</p><p> 圖1.3 OpenGL工作流程圖</p>&l
27、t;p> OpenGL工作流程的輸入端可以是圖像或幾何圖元,但最終結果都是光柵化后的圖像。這些圖像進入幀緩沖區(qū)后,由硬件顯示在輸出設備上。OpenGL的所有繪圖對象(包括幾何圖元和圖像)既可以存儲在顯示列表中(延遲模式),也可以立即處理(立即模式)。</p><p> 對于圖像,OpenGL首先通過像素解包把其像素格式轉換成OpenGL內部格式,然后通過像素操作后直接光柵化輸出或者作為其他物體的表現(xiàn)紋理
28、。對于幾何圖元,OpenGL中的所有圖元都是用頂點來描述的。OpenGL首先通過頂點解包將不同格式的頂點轉化為內部的標準格式,然后對頂點及相關數據(坐標、顏色、法向量、紋理坐標、邊標識等)進行操作,在進行光柵化,最終得到可見的圖像。</p><p> 1.3 OpenGL繪圖流程</p><p> OpenGL的繪圖流程如圖1.4所示</p><p> 圖1.
29、4 OpenGL繪圖流程圖</p><p> 設置像素格式:主要包括建立OpenGL繪制風格、顏色模式、顏色位數、深度位數等。</p><p> 建立景物模型:根據基本圖形單元建立景物模型,并且對所建立的模型進行數學描述。在OpenGL中把點、線、多邊形、圖像和位圖都作為基本圖形單元。</p><p> 舞臺布景:把景物模型放在三維空間中合適的位置,并且設置視
30、點(Viewpoint)以觀察所感興趣的景觀。</p><p> 效果處理:設置物體對象的材質(顏色、光學性能及紋理映射等 ),加入光照和光照條件。</p><p> 光柵化:把景物模型的數學描述及其色彩信息轉換至可在計算機上顯示的像素信息,這個過程就是光柵化(rasterization)。</p><p><b> 2 系統(tǒng)分析與設計</b&
31、gt;</p><p> 2.1系統(tǒng)結構總框架設計</p><p> 本游戲系統(tǒng)主要分成四大模塊,這些模塊又是由若干個子模塊構成的,形成一個功能明確的游戲系統(tǒng)。系統(tǒng)結構總框架設計如圖2.1所示: </p><p><b> 圖2.1系統(tǒng)結構圖</b></p><p><b> 2.2系統(tǒng)目的</
32、b></p><p> 玩家以第一人稱視角觀察周圍環(huán)境,并可以進行旋轉視角,前后移動等操作。</p><p> 3 OpenGL的配置</p><p> 3.1程序運行環(huán)境的配置 </p><p> 在建立程序框架前首先要下好OpenGL庫文件,把解壓好的庫文件分別按如下路徑放到文件夾里, 對于VS2005可以如下設置[2]1
33、、把 glut.h 復制到 VC 安裝路徑下的 PlatFormSDK\include\gl 文件夾2、把 glut32.lib 復制到 VC 安裝路徑下的 PlatFormSDK\lib 文件夾3、把 glut32.dll 復制到 Windows\System32 文件夾4、在 VC 中創(chuàng)建控制臺應用程序,在選項中清除“使用預編譯頭”(以免影響可移植性)5、在 VC 中打開項目->屬性對話框進行如下設置:將“配置”下拉框
34、選則為“所有配置”,打開 “鏈接器--輸入”項。在“附加依賴項”中增加:OpenGL32.lib glu32.lib glut32.lib</p><p><b> 4 基礎類的實現(xiàn)</b></p><p> 4.1頭文件包含類Stdafx</p><p> 在Stdafx.h中包含了常用的頭文件,以方便其他文件的調用,這樣就不用
35、每個用到如下頭文件的文件都去寫這些頭文件了。</p><p><b> 常用頭文件:</b></p><p> #include <windows.h></p><p> #include <stdio.h></p><p> #include <math.h>
36、 </p><p> #include <time.h></p><p><b> gl頭文件:</b></p><p> #include <gl\gl.h> </p><p> #include <gl\glu.h></p
37、><p> #include <gl\glaux.h></p><p> #include <gl\glext.h></p><p> OpenGL鏈接庫文件:</p><p> #pragma comment(lib, "opengl32.lib")</p><p>
38、; #pragma comment(lib, "glu32.lib")</p><p> #pragma comment(lib, "glaux.lib")</p><p> 另外還進行了用算符重載的操作</p><p><b> 定義地面網格:</b></p>&l
39、t;p> const unsigned int MAP_WIDTH = 1024; //位圖的寬度 </p><p> const unsigned int CELL_WIDTH = 16; //單元格的寬度</p><p> 4.2 向量類Vector</p><p> 主要計算向量的點積和叉積(詳細參考附錄)<
40、/p><p><b> 算法的代碼實現(xiàn)為:</b></p><p><b> 點積:</b></p><p> float Vector3::dotProduct(const Vector3& v)</p><p><b> {</b></p><
41、;p> return ( x * v.x + y * v.y + z * v.z );</p><p><b> }</b></p><p><b> 叉積:</b></p><p> Vector3 Vector3::crossProduct(const Vector3& v)</p>
42、<p><b> {</b></p><p> Vector3 vec;</p><p> vec.x = y * v.z - z * v.y;</p><p> vec.y = z * v.x - x * v.z;</p><p> vec.z = x * v.y - y * v.x;</p
43、><p> return vec;</p><p><b> }</b></p><p> 4.3 窗口類GLWindow</p><p> 4.3.1 窗口類概述</p><p> 任何一個Windows程序都必須處理設備描述表(Device Context),它告訴Windows怎樣在一
44、窗口中顯示圖形信息。一個設備描述表(DC)說明了筆和畫刷的顏色繪制模式,調色盤信息,映射模式,以及其他Windows必須知道的怎樣顯示圖形的屬性。與其他的Windows應用程序一樣,OpenGL應用程序也必須應用DC。不過我們將其稱為著色描述表(Rendering Context,RC),由它通知Windows在窗口中繪制圖形。每一個OpenGL都被連接到一個RC上。RC將所有的OpenGL調用命令連接到DC上,應用程序必須在繪圖之前調
45、用專用函數wglCreateContext()創(chuàng)建自己的RC,調用wglMakeCurrent使其當前化,退出OpenGL時使RC非當前化。</p><p> 4.3.2 GLWindow.h及GLWindow.cpp主要要完成窗口的設置:</p><p> intm_WindowPosX; /**< 窗口的左上角的X位置*/</p><p&g
46、t; intm_WindowPosY; /**< 窗口的左上角的Y位置*/</p><p> intm_WindowWidth; /**< 窗口的寬度*/</p><p> intm_WindowHeight; /**< 窗口的高度*/</p><p> intm_Scre
47、enWidth; /**< 全屏的寬度*/</p><p> intm_ScreenHeight; /**< 全屏的高度*/</p><p> intm_BitsPerPixel; /**< 顏色位深*/</p><p> bool m_IsFullScreen
48、; /**< 是否全屏*/</p><p> 以及設置像素格式,設置像素格式首先要填充PIXELFORMATDESCRIPTOR結構,其默認設置如下</p><p> PIXELFORMATDESCRIPTOR pfd = /**< 設置像素描述結構*/</p><p><b> {</b></
49、p><p> sizeof(PIXELFORMATDESCRIPTOR),/**< 像素描述結構的大小*/ </p><p> 1, /**< 版本號*/</p><p> PFD_DRAW_TO_WINDOW|/**< 緩存區(qū)的輸出顯示在一個窗口中*/</p><p>
50、 PFD_SUPPORT_OPENGL|/**< 緩存區(qū)支持OpenGL繪圖*/</p><p> PFD_STEREO| /**< 顏色緩存區(qū)是立體緩存*/</p><p> PFD_DOUBLEBUFFER, /**< 顏色緩存區(qū)是雙緩存*/</p><p> PFD_TYPE_RGBA
51、, /**< 使用RGBA顏色格式*/</p><p> m_BitsPerPixel, /**< 顏色緩存區(qū)中顏色值所占的位深*/</p><p> 0, 0, 0, 0, 0, 0, /**< 使用默認的顏色設置*/</p><p> 0,
52、 /**< 無Alpha緩存*/</p><p> 0, /**< 顏色緩存區(qū)中alpha成分的移位計數*/</p><p> 0, /**< 無累計緩存區(qū)*/</p><p> 0, 0, 0, 0, /**< 累計緩存區(qū)無移位*/
53、</p><p> 32, /**< 32位深度緩存*/</p><p> 0, /**< 無蒙版緩存*/</p><p> 0, /**< 無輔助緩存區(qū)*/</p><p> PFD_MAIN_PLANE,
54、 /**< 必須為PFD_MAIN_PLANE,設置為主繪圖層*/</p><p> 0, /**< 表示OpenGL實現(xiàn)所支持的上層或下層平面的數量*/</p><p> 0, 0, 0 /**< 過時,已不再使用*/</p><p><
55、b> };</b></p><p> 4.4 位圖載入類CBMPLoader</p><p> 4.4.1 BMP圖像文件格式[3]</p><p> BMP是一種與硬件設備無關的圖像文件格式,使用非常廣。它采用位映射存儲格式,除了圖像深度可選以外,不采用其他任何壓縮,因此,BMP文件所占用的空間很大。BMP文件的圖像深度可選lbit、4b
56、it、8bit及24bit。BMP文件存儲數據時,圖像的掃描方式是按從左到右、從下到上的順序。</p><p> 由于BMP文件格式是Windows環(huán)境中交換與圖有關的數據的一種標準,因此在Windows環(huán)境中運行的圖形圖像軟件都支持BMP圖像格式。</p><p> 典型的BMP圖像文件由三部分組成:位圖文件頭數據結構,它包含BMP圖像文件的類型、顯示內容等信息;位圖信息數據結構,它
57、包含有BMP圖像的寬、高、壓縮方法,以及定義顏色等信息。</p><p> BMP 是(Windows 位圖 ) Windows 位圖可以用任何顏色深度(從黑白到 24 位顏色)存儲單個光柵圖像。Windows 位圖文件格式與其他 Microsoft Windows 程序兼容。它不支持文件壓縮,也不適用于 Web 頁。 從總體上看,Windows 位圖文件格式的缺點超過了它的優(yōu)點。為了保證照片圖像的質量,請使用
58、 PNG 、JPEG、TIFF 文件。BMP 文件適用于 Windows 中的墻紙。</p><p> 優(yōu)點:BMP 支持 1 位到 24 位顏色深度。</p><p> BMP 格式與現(xiàn)有 Windows 程序(尤其是較舊的程序)廣泛兼容。</p><p> 缺點: BMP 不支持壓縮,這會造成文件非常大。 BMP 文件不受 Web 瀏覽器支持。</p
59、><p> 4.4.1位圖載入類CBMPLoader流程圖</p><p><b> 如圖4.1所示:</b></p><p> 圖4.1 位圖載入類流程圖</p><p> 4.5 基本框架的組成</p><p> 鍵盤類和程序框架類(GLFrame):</p><p&
60、gt;<b> 鍵盤類:</b></p><p> class Keys </p><p><b> {</b></p><p> public: </p><p> Keys()
61、{ Clear(); } /** 構造函數*/</p><p> void Clear() { ZeroMemory(&m_KeyDown, sizeof(m_KeyDown)); }/** 清空所有的按鍵信息*/</p><p> bool IsPressed(unsigned int key){ return (key < MAX_KEYS) ? (
62、m_KeyDown[key] == true) : false; }/** 判斷某個鍵是否按下*/</p><p> void SetPressed(unsigned int key){ if (key < MAX_KEYS) m_KeyDown[key] = true; }/** 設置某個鍵被按下*/</p><p> void SetReleased(unsigned in
63、t key){ if (key < MAX_KEYS) m_KeyDown[key] = false; }/** 設置某個鍵被釋放*/</p><p><b> private:</b></p><p> static const unsigned int MAX_KEYS = 256;</p><p> bool m_KeyDow
64、n[MAX_KEYS];/**< 保存各按鍵的狀態(tài)*/</p><p><b> };</b></p><p> 在繼承類中完成以下函數的實現(xiàn)</p><p> GLApplication * GLApplication::Create(const char * class_name) //創(chuàng)建子類的一個實例
65、</p><p> bool Init();//執(zhí)行所有的初始化工作,如果成功函數返回true</p><p> void Uninit();//執(zhí)行所有的卸載工作</p><p> void Update(DWORD milliseconds);//執(zhí)行所有的更新操作,傳入的參數為兩次操作經過的時間,以毫秒
66、 //為單位</p><p> void Draw();//執(zhí)行所有的繪制操作</p><p> windowExtendedStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;/**< 使窗口具有3D外觀*/</p><p><b> 5視角控制</b><
67、;/p><p> 5.1攝像機類解構圖</p><p><b> 如圖5.1所示</b></p><p> 圖5.1 攝像機類結構圖</p><p> 5.2設置攝像機的位置</p><p> 攝像機類主要的功能是實現(xiàn)三維漫游。第一要做的事就是設置攝像機的位置:</p><
68、;p> 設置攝像機的位置,朝向和向上向量。設置函數為:</p><p> void Camera::setCamera( float positionX, float positionY, float positionZ,</p><p> float viewX, float viewY, float viewZ,</p><p>
69、float upVectorX, float upVectorY, float upVectorZ)</p><p> 5.3 攝像機旋轉功能的實現(xiàn)</p><p> 5.3.1 旋轉攝像機</p><p> 旋轉攝像機方向函數為:</p><p> void Camera::rotateView(float angle, float
70、 x, float y, float z)</p><p> Angle為旋轉的角度值,X,Y,Z為初始的位置。Angle值由庫函數獲取。</p><p> 下面是實現(xiàn)計算攝像機在空間中旋轉了angle弧度后,計算其視點View更新的值newView。</p><p> Vector3 view = m_View - m_Position;/** 計算方向向
71、量*/</p><p> /** 計算sin 和cos值*/</p><p> float cosTheta = (float)cos(angle);</p><p> float sinTheta = (float)sin(angle);</p><p> /** 計算旋轉向量的x值*/</p><p>
72、newView.x = (cosTheta + (1 - cosTheta) * x * x)* view.x;</p><p> newView.x += ((1 - cosTheta) * x * y - z * sinTheta)* view.y;</p><p> newView.x += ((1 - cosTheta) * x * z + y * sinTheta)
73、* view.z;</p><p> /** 計算旋轉向量的y值*/</p><p> newView.y = ((1 - cosTheta) * x * y + z * sinTheta)* view.x;</p><p> newView.y += (cosTheta + (1 - cosTheta) * y * y)* view.y;</p
74、><p> newView.y += ((1 - cosTheta) * y * z - x * sinTheta)* view.z;</p><p> /** 計算旋轉向量的z值*/</p><p> newView.z = ((1 - cosTheta) * x * z - y * sinTheta)* view.x;</p><p&
75、gt; newView.z += ((1 - cosTheta) * y * z + x * sinTheta)* view.y;</p><p> newView.z += (cosTheta + (1 - cosTheta) * z * z)* view.z;</p><p> /** 更新攝像機的方向*/</p><p> m_View = m_
76、Position + newView;</p><p> 5.3.2 攝像機于鼠標相連</p><p> 設置鼠標位置在屏幕中心,如果鼠標不移動,則不用更新其位置。用鼠標旋轉攝像機的重要函數為</p><p> void Camera::setViewByMouse()</p><p><b> {</b><
77、;/p><p> POINT mousePos; /**< 保存當前鼠標位置*/</p><p> int middleX = GetSystemMetrics(SM_CXSCREEN) >> 1; /**< 得到屏幕寬度的一半*/</p><p> int middleY = GetSystemMetri
78、cs(SM_CYSCREEN) >> 1; /**< 得到屏幕高度的一半*/</p><p> float angleY = 0.0f; /**< 攝像機左右旋轉角度*/</p><p> float angleZ = 0.0f; /**< 攝像機上下旋轉角度*
79、/</p><p> static float currentRotX = 0.0f;</p><p> 用函數GetCursorPos(&mousePos);得到當前鼠標位置。</p><p> 5.3.3 注意事項</p><p> 實時跟蹤攝像機的上下的旋轉角度如果上下旋轉弧度大于1.0(或者小于-1.0),則
80、要截取到1.0(或-1.0)并旋轉,要不就會出現(xiàn)本該看的的物體不在我們的視野之內,跑到視野外去了,這就不符合我們的期望了。</p><p> 5.3.4 前后移動和速度Speed相關</p><p> 前后移動最重要的就是要和移動速度關聯(lián)起來,根據物體的速度時刻改變攝像機的位置。前后移動的函數為moveCamera(float speed)。前后移動攝像機其主要的就是要和攝像機的速度聯(lián)
81、系起來</p><p> void Camera::moveCamera(float speed)</p><p><b> {</b></p><p> /** 計算方向向量*/</p><p> Vector3 vector = m_View - m_Position;</p><p>
82、; vector = vector.normalize(); /**< 單位化*/</p><p> /** 更新攝像機*/</p><p> m_Position.x += vector.x * speed; /**< 根據速度更新位置*/</p><p> m_Position.z += vector.z * speed
83、;</p><p> m_Position.y += vector.y * speed;</p><p> m_View.x += vector.x * speed; /**< 根據速度更新方向*/</p><p> m_View.y += vector.y * speed;</p><p> m_View.z += v
84、ector.z * speed;</p><p><b> }</b></p><p> 以下是鍵盤與攝像機前后移動關聯(lián)的主要實現(xiàn)代碼</p><p> /** 鍵盤按鍵響應*/</p><p> if(m_Keys.IsPressed(VK_SHIFT)) /**<
85、; 按下SHIFT鍵時加速*/</p><p><b> {</b></p><p> m_Camera.setSpeed(0.6f);</p><p><b> }</b></p><p> if(!m_Keys.IsPressed(VK_SHIFT))</p><p&
86、gt;<b> {</b></p><p> m_Camera.setSpeed(0.2f);</p><p><b> }</b></p><p> if(m_Keys.IsPressed(VK_UP) || m_Keys.IsPressed('W')) /**< 向上方向鍵或'
87、W'鍵按下*/</p><p> m_Camera.moveCamera(m_Camera.getSpeed()); /**< 移動攝像機*/</p><p> if(m_Keys.IsPressed(VK_DOWN) || m_Keys.IsPressed('S')) /**< 向下方向鍵或'S'鍵按下*/<
88、/p><p> m_Camera.moveCamera(-m_Camera.getSpeed()); /**< 移動攝像機*/</p><p> if(m_Keys.IsPressed(VK_LEFT) || m_Keys.IsPressed('A')) /**< 向左方向鍵或'A'鍵按下*/</p><p&g
89、t; m_Camera.yawCamera(-m_Camera.getSpeed()); /**< 移動攝像機*/</p><p> if(m_Keys.IsPressed(VK_RIGHT) || m_Keys.IsPressed('D')) /**< 向右方向鍵或'D'鍵按下*/</p><p> m_Camera.y
90、awCamera(m_Camera.getSpeed()); /**< 移動攝像機*/</p><p><b> }</b></p><p><b> 6 游戲場景設計</b></p><p><b> 6.1地面的構造</b></p><p>
91、; 6.1.1 地形可視化的概念</p><p> 地形可視化是一門以研究數字地形模型(Digital Terrain Model)或數字高程域( Digital Elevation Field)的顯示、簡化、仿真等為內容的學科,并以計算幾何作為其重要的基礎知識,它屬于計算機圖形學的一個分支。</p><p> 6.1.2 數據基礎</p><p> 未被處
92、理的用于地形三維顯示的數據稱為原始數據,一般被分為矢量和柵格兩種形式。其中矢量數據包括線矢量數據、地形特征點數據等,柵格數據主要指數字高程模型DEM數據和紋理圖像數據。其中DEM數據是地形三維顯示中最重要的數據,它的精度、質量直接影響到后續(xù)的顯示效果。DEM 數據也可以由線矢量數據生成,初始的DEM數據由于顯示水平的不同要求,也可以用不同方法簡化或內插為適應新需求的數據,這些數據稱為再生數據。原始數據與再生數據共同組成地形可視化的數據基
93、礎。</p><p> 6.1.3 顯示理論與方法</p><p> 對已知地形數據進行三維顯示,一般要先經過投影變換、消隱和裁剪處理、顏色與光照處理、紋理映射四個基本步驟,之后還可以根據需要在模型上疊加相應的地物模型、矢量要素等。這些理論與方法均是計算機圖形學中真實感圖形生成算法的重要組成部分。</p><p> 6.1.4用OpenGL構造三維地形景觀流程
94、圖</p><p> 如圖4.2.1所示:</p><p> 圖6.1 OpenGL構造三維地形景觀基本流程圖</p><p> 6.1.5 具體實現(xiàn)</p><p> ?。?)數據準備及預處理 用于構造三維地形景觀的數據包括DEM數據和紋理數據。DEM數據的</p><p> 處理包括不同格式DEM間的轉
95、化、DEM 數據簡化、格網DEM 與TIN間的相互轉化等;紋理數據的處理包括圖像格式轉化、圖像裁切等。</p><p> ?。?)設置基本參數 在用OpenGL繪制三維地形模型和進行紋理映射前,需要設置相關的景觀參數值。這些參數包括光源性質(鏡射光、漫射光和環(huán)境光)、光源方位(距離和方向)、顏色模式(索引模式或RGBA模式)、明暗處理方式(平滑處理或平面處理)、紋理映射方式等。除此之外還需設定視點位置和視線
96、方向。這些參數設置都可以通過對OpenGL的相關函數的參數選擇來實現(xiàn)。</p><p> ?。?)構造地形模型三維地形模型的基本構造通常是以三角面為單元的。三角面的明亮程度除取決于光源和明暗處理方式外,還受到點與面的法向量的影響。一般點的法向量取值為其周圍面法向量的均值。在圖3中P點的法向量即可表示為與其相鄰的四個面法向量N1、N2、N3、N4的和的平均值。</p><p> 這樣三維模
97、型的構造可由下列程序給出:</p><p> glBegin(GL_TRIANGLES_STRIP);</p><p> glNormal3fv(N0); //設置頂點法向量</p><p> glVertex3f(v0); //設置頂點坐標</p><p> glNormal3fv(N1);</p><
98、p> glVertex3f(v1);</p><p><b> ……</b></p><p><b> glEnd();</b></p><p> 構造模型的同時,還可以對模型進行平移、旋轉和縮放等變換,以實現(xiàn)各種不同的模型造型。</p><p> (4)投影變換 投影變換一般分
99、為透視投影變換和正射投影變換兩類。投影方式的選擇取決于顯示的內容和用途。由于透視投影類似于人眼對客觀世界的觀察方式,因而廣泛應用于三維地形模擬、飛行仿真、步行穿越仿真等模擬人眼視覺效果的研究領域。但如果需要觀察模型某一個側面不帶有形變的景觀,則更多采用正射投影方式,如制作地形暈渲圖則一般采用正射投影方式。OpenGL只繪制位于視景體內的對象,在設置投影變換時要充分考慮模型的大小以便選擇合適的視景體范圍。</p><p
100、> 圖6.2 表示用于透視投影變換的視景體</p><p> 圖6.3 表示用于正射投影變換的視景體</p><p> (5)視口變換 視口是指計算機屏幕中的矩形繪圖區(qū)域,它用窗口坐標來度量,反映了屏幕上的像素位置。視口相對于窗口的左下角。視口變換的目的就是將三維空間坐標映射為計算機屏幕上的二維平面坐標。視口變換用函數glViewport()實現(xiàn),視口的寬高比通常等于視景體
101、的寬高比,否則視口內顯示的圖形將會發(fā)生形變。根據視口變換后視口內每一點的z坐標值,OpenGL可以自動實現(xiàn)消隱功能,使得靠近視點的目標能夠遮擋視口同一位置遠離視點的目標。</p><p> (6)紋理映射 紋理映射是建立逼真三維地形景觀的重要手段,不采用紋理映射所得到的地形模</p><p> 型僅僅是具有明暗效果的光照模型,光照模型可以按照高程值進行過渡著色或分層設色。它能夠直觀地
102、反映地表起伏狀況,但不能重現(xiàn)地表的真實面貌。</p><p> 一般紋理映射的思路是把紋理圖像“貼”到由DEM數據所構成的三維模型上。其關鍵是實現(xiàn)影像與DEM之間的正確套合,使每個DEM格網點與其所在的圖像位置一一對應。為提高紋理映射的運算效率,通常采用預處理好的與DEM坐標相對應的圖像作為紋理以免除紋理坐標的計算。用OpenGL函數進行紋理映射的基本步驟為:</p><p> 紋理定
103、義:用glTexImage2D*()函數說明所映射的紋理內容。其中包括紋理數據的指針、紋理的大小、紋理的類別(灰度或彩色)等。</p><p> 紋理控制:說明紋理以何種方式映射到三維模型表面上。OpenGL 提供了多種映射方式,其中包括紋理濾波、重復與縮限,其函數為glTexParameter*()。</p><p> 紋理的映射方式說明:在紋理映射過程中,可以用紋理來調整三維模型的
104、顏色或者將紋理與三維模型原來的顏色進行融合,其調用函數為glTexEnv*()。</p><p> 三維模型頂點的紋理坐標與幾何坐標定義及場景繪制:幾何坐標決定了頂點在屏幕上的繪制位置,調用函數為glVertex*();紋理坐標決定紋理圖像中哪一個紋理單元賦予該頂點,調用函數為glTexCoord*();再在glBegin()中選擇一定的繪制參數如:GL_QUAD_STRIP 或GL_TRLANGLE_STRI
105、P等,就可以實現(xiàn)帶紋理的場景繪制。</p><p><b> 6.2天空的構造</b></p><p> 相對于構造地面,構造天空顯的簡單許多,本實驗是用五張連續(xù)的天空圖片,夠成一個天空盒。并伴隨著攝像機的移動而移動,始終以攝像機為中心,這樣在玩家看起來就像是永遠也走不到天邊。相對于其他的構造天空的方法,這種方法明顯的優(yōu)勢是其計算量少,代碼自然也少了許多,有利于游
106、戲的運行。當然他的變化性就少了,缺乏新鮮感。</p><p> OpenGL的坐標系于數學里德坐標系有一點區(qū)別,如圖4.2.1所示為OpenGL的坐標系;圖4.2.2為數學里的坐標系。</p><p> 圖6.3 OpenGL的坐標系 圖6.4 世界坐標系</p><p> 下圖為OpenGL天空構造時,要載
107、入的五張bmp格式的位圖所要綁定的紋理空間圖,除去地面的5張位圖。</p><p><b> 五張?zhí)炜瘴粓D為:</b></p><p> 圖6.5 背面位圖back.bmp</p><p> 圖6.6前面位圖Font.bmp</p><p> 圖6.7 左邊位圖Left.bmp</p><p&
108、gt; 圖6.8右邊位圖 Right.bmp</p><p> 圖6.9 天空紋理載入坐標圖</p><p> 本實驗是用CBMPLoader m_texture[5];將五張下好的天空紋理圖分別載入到如上圖所示的空間中,分別為前(front)、后(back)、左(left)、右(right)、上(top)。在每次進行矩陣變換前都要用glPushMatrix()進行入棧,然后用gl
109、PopMatrix()出棧,這樣操作不至于影響后面的矩陣操作。glTranslate()的作用是每一次操作都把當前所在的位置作為原點。glRotatef()每一次操作都是相對于當前原點的(而不是屏幕的中央)</p><p><b> 其基本步驟如下:</b></p><p> 第一步 定義數組用來保存文件名:</p><p> char
110、*bmpName[] = { "back","front","top","left","right"};</p><p> for(int i=0; i< 5; i++)</p><p><b> {</b></p><p> spr
111、intf(filename,"data/%s",bmpName[i]);</p><p> strcat(filename,".bmp");</p><p> 第二步:生成紋理對象數組</p><p> glGenTextures(1, &m_texture[i].ID); </p>&l
112、t;p> 第三步:通過使用glBindTexture選擇紋理對象,來完成該紋理對象的定義。</p><p> glBindTexture(GL_TEXTURE_2D, m_texture[i].ID); </p><p> 第四步:在繪制景物之前通過glBindTexture,為該景物加載相應的紋理。 gluBuild2DMipmaps(GL_TEXTURE_2D, GL
113、_RGB, m_texture[i].imageWidth,</p><p> m_texture[i].imageHeight, GL_RGB, GL_UNSIGNED_BYTE,</p><p> m_texture[i].image);</p><p> 第五步:在程序結束之前調用glDeleteTextures刪除紋理對象。</p>&l
114、t;p> 這里定義了一個析構函數:CSkyBox::~CSkyBox()來實現(xiàn)釋放所占用的內存</p><p> CSkyBox::~CSkyBox()</p><p><b> {</b></p><p> for(int i =0 ;i< 5; i++)</p><p><b> {&
115、lt;/b></p><p> m_texture[i].FreeImage();</p><p> glDeleteTextures(1,&m_texture[i].ID);</p><p><b> }</b></p><p><b> }</b></p>&
116、lt;p> 如下是一部分核心代碼的實現(xiàn):</p><p> glPushMatrix(); glTranslatef(m_CameraPos.x,m_CameraPos.y,m_CameraPos.z);</p><p> glRotatef(yRot,0.0f,1.0f,0.0f);<
117、/p><p> /** 繪制背面*/</p><p> glBindTexture(GL_TEXTURE_2D, m_texture[0].ID);//GL_TEXTURE_2D:繪制2D紋理</p><p> glBegin(GL_QUADS);</p><p> /** 指定紋理坐標和頂點坐標*/</p><p
118、> glTexCoord2f(1.0f, 0.0f); glVertex3f( width, -height, -length);</p><p> glTexCoord2f(1.0f, 1.0f); glVertex3f( width, height, -length); </p><p> glTexCoord2f(0.0f, 1.0f); glVertex3f( -
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于OpenGL的3D射擊游戲的設計與實現(xiàn).pdf
- 基于OpenGL ES的3D游戲技術的研究與實現(xiàn).pdf
- 基于OpenGL的3D游戲場景編輯器的設計與實現(xiàn).pdf
- 基于torque游戲引擎的3d游戲的設計與實現(xiàn)-畢業(yè)論文
- 基于DirectX的3D游戲設計與實現(xiàn).pdf
- 基于OpenGL的3D粒子特效系統(tǒng)設計與實現(xiàn).pdf
- 3D棒球游戲的設計與實現(xiàn).pdf
- 3D游戲引擎的設計與實現(xiàn).pdf
- 3d光立方系統(tǒng)的設計與實現(xiàn)【畢業(yè)設計】
- 3D云游戲平臺的設計與實現(xiàn).pdf
- 3D游戲渲染引擎的設計與實現(xiàn).pdf
- 3D外景游戲引擎的設計與實現(xiàn).pdf
- 基于DirectX 11的3D游戲引擎的設計與實現(xiàn).pdf
- 基于OGRE的3D網絡游戲引擎設計與實現(xiàn).pdf
- 基于directx9.0的3d游戲設計
- 軍事3D網絡游戲引擎的設計與實現(xiàn).pdf
- 基于游戲引擎3D GAMESTUDIO的虛擬校園系統(tǒng)設計與實現(xiàn).pdf
- 基于OpenGL的3D在線監(jiān)測系統(tǒng)研究與實現(xiàn).pdf
- 3D角色游戲中AI引擎的設計與實現(xiàn).pdf
- 畢業(yè)設計---鍋爐3d模型設計
評論
0/150
提交評論