国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

三維場(chǎng)景虛擬漫游系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)

2012-09-18 02:19:26
關(guān)鍵詞:數(shù)據(jù)文件視點(diǎn)漫游

楊 剛

(陜西理工學(xué)院數(shù)學(xué)與計(jì)算機(jī)科學(xué)學(xué)院,陜西漢中 723000)

目前,基于Windows系統(tǒng)的虛擬現(xiàn)實(shí)系統(tǒng)的實(shí)現(xiàn)主要采用2種技術(shù):DirectX和 OpenGL。OpenGL是一個(gè)三維的計(jì)算機(jī)圖形和模型庫(kù),利用它可以實(shí)現(xiàn)專業(yè)級(jí)的仿真。同時(shí)相對(duì)DirectX而言,OpenGL的建模過程更簡(jiǎn)單、更靈活。在效果處理方面,OpenGL具有alpha處理能力,生成的圖形真實(shí)感強(qiáng)。本研究選用了OpenGL進(jìn)行系統(tǒng)開發(fā)。

1 系統(tǒng)的開發(fā)框架

OpenGL程序開發(fā)框架比較眾多,本研究選擇Win32 Application。選擇Win32而不使用MFC來(lái)開發(fā)應(yīng)用程序,是因?yàn)镸FC主要是用于基于窗口和文檔的應(yīng)用軟件的編程,它集成了大量的數(shù)據(jù)和方法,將許多煩瑣的任務(wù)如應(yīng)用程序初始化文檔處理和磁盤I/O封裝起來(lái),雖然這樣給使用者的編程帶來(lái)了巨大方便,但在編制基于圖形顯示和多媒體的應(yīng)用程序時(shí)會(huì)給編程人員帶來(lái)極大的麻煩[1]。

Win32 Application程序的入口函數(shù)是WinMain,此函數(shù)的原形是 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)。此函數(shù)用來(lái)調(diào)用窗口創(chuàng)建例程、處理窗口消息,并監(jiān)視人機(jī)交互。系統(tǒng)中其他函數(shù)見表1。

表1 程序中的函數(shù)

2 建立三維場(chǎng)景

2.1 場(chǎng)景文件的創(chuàng)建

OpenGL中場(chǎng)景的創(chuàng)建一般有3種方法:第1種方法是在3DS MAX或其他三維建模軟件中繪制好場(chǎng)景,然后將之讀入到OpenGL程序中[2];第2種方法是在OpenGL中建模,創(chuàng)建場(chǎng)景,這種方法比較繁瑣;第3種方法是讀入外部數(shù)據(jù)文件。本研究采用第3種方法讀入數(shù)據(jù)文件,這樣程序比較靈活,還可以根據(jù)需要加載不同的場(chǎng)景。數(shù)據(jù)文件采用文本格式,這樣效率較高。

系統(tǒng)中創(chuàng)建了一個(gè)場(chǎng)景文件 house.txt,文件部分內(nèi)容見表2。其中場(chǎng)景文件中每行的數(shù)據(jù)結(jié)構(gòu)為(x,y,z,u,v),(x,y,z)代表該頂點(diǎn)的坐標(biāo),(u,v)代表該頂點(diǎn)對(duì)應(yīng)的紋理坐標(biāo)。此文件定義的場(chǎng)景剖面圖如圖1所示。house.txt文件中數(shù)據(jù)的坐標(biāo)系如圖1所示,其中y軸的正向垂直xoz平面向上。

圖1 場(chǎng)景示意圖

2.2 場(chǎng)景數(shù)據(jù)的組織

三維場(chǎng)景中的數(shù)據(jù)信息比較豐富,而且數(shù)據(jù)量隨著場(chǎng)景復(fù)雜程度的增加而增加,因此在系統(tǒng)中必須將數(shù)據(jù)進(jìn)行歸類以便于處理。系統(tǒng)中定義了一系列結(jié)構(gòu)體用來(lái)組織場(chǎng)景中的大量數(shù)據(jù)。主要思想是把三維世界看做許多區(qū)段(區(qū)段可以是1個(gè)物體或房子等等)的集合。1個(gè)區(qū)段中包含許多三角形,1個(gè)三角形是由3個(gè)頂點(diǎn)組成,每個(gè)頂點(diǎn)含有x、y、z坐標(biāo)分量和此點(diǎn)對(duì)應(yīng)的紋理坐標(biāo)u、v。這樣程序中就需要定義以下結(jié)構(gòu):

typedef struct tagVERTEX{float x,y,z;float u,v;}VERTEX;//定義頂點(diǎn)結(jié)構(gòu)

typedef struct tagTRIANGLE{VERTEX vertex[3];}TRIANGLE; //定義三角形結(jié)構(gòu)

typedef struct tagSECTOR{int numtriangles;TRIANGLE*triangle;}SECTOR;//定義區(qū)段結(jié)構(gòu)

2.3 場(chǎng)景數(shù)據(jù)的讀入

函數(shù)SetupHouse()用來(lái)從文件中取得數(shù)據(jù)資料。此函數(shù)在運(yùn)行時(shí)需要調(diào)用函數(shù)readstr(),從數(shù)據(jù)文件中讀入一個(gè)有意義的行數(shù)據(jù),然后再把這些數(shù)據(jù)依次賦給區(qū)段的某個(gè)三角形的某個(gè)頂點(diǎn)的相應(yīng)變量,通過這種方式將數(shù)據(jù)文件中的數(shù)據(jù)存儲(chǔ)在內(nèi)存中。

表2 場(chǎng)景文件的部分內(nèi)容

2.4 加載位圖文件并轉(zhuǎn)化為紋理

系統(tǒng)中采用位圖進(jìn)行紋理映射[3]。LoadBMP()函數(shù)用來(lái)加載位圖文件(文件后綴擴(kuò)展名為bmp)。如果文件不存在,返回NULL值告知程序無(wú)法加載位圖。函數(shù)LoadGLTextures()調(diào)用LoadBMP()函數(shù)先加載位圖文件,然后將之創(chuàng)建為紋理。系統(tǒng)中創(chuàng)建3種紋理:Nearest Filtered Texture、Linear Filtered Texture 和 MipMapped Texture,這樣在程序運(yùn)行時(shí)可以通過鍵盤選擇不同的紋理樣式。創(chuàng)建Nearest Filtered Texture的代碼如下:

2.5 深度緩存

在屏幕顯示三維場(chǎng)景的OpenGL程序中都要使用深度緩存??梢詫⑸疃染彺嬖O(shè)想為屏幕后面的層,深度緩存不斷地對(duì)進(jìn)入屏幕內(nèi)部的深度進(jìn)行跟蹤,以便對(duì)場(chǎng)景進(jìn)行排序,決定哪個(gè)物體先繪制,哪個(gè)物體后繪制,這樣才能正確地顯示場(chǎng)景。這部分程序設(shè)計(jì)在函數(shù)InitGL()中,具體代碼如下:

3 虛擬場(chǎng)景的漫游

3.1 不同方向漫游的設(shè)計(jì)

在OpenGL中默認(rèn)的鏡頭位置在原點(diǎn)(0,0,0)。本系統(tǒng)中漫游的功能是通過變換場(chǎng)景而產(chǎn)生移動(dòng)或轉(zhuǎn)動(dòng)鏡頭的錯(cuò)覺實(shí)現(xiàn)的。具體是圍繞原點(diǎn)以與鏡頭相反的旋轉(zhuǎn)方向來(lái)旋轉(zhuǎn)場(chǎng)景,從而讓人產(chǎn)生鏡頭旋轉(zhuǎn)的錯(cuò)覺,同時(shí)以與鏡頭平移相反的方向來(lái)平移場(chǎng)景。

系統(tǒng)中鏡頭(或叫相機(jī)、視點(diǎn))的移動(dòng)是通過鍵盤上的幾個(gè)方向鍵控制的[4]:按“←”鍵可以使視點(diǎn)向左轉(zhuǎn)動(dòng);按“→”鍵可以使視點(diǎn)向右轉(zhuǎn)動(dòng);按“↑”鍵可以使視點(diǎn)向前移動(dòng);按“↓”鍵可以使視點(diǎn)向后移動(dòng);按“PgUp”鍵可以使視點(diǎn)向上偏移;按“PgDn”鍵可以使視點(diǎn)向下偏移。

由于鍵盤上每個(gè)鍵值都可以用0~255的1個(gè)數(shù)來(lái)代表,程序中定義了一個(gè)監(jiān)控鍵盤動(dòng)作的全局?jǐn)?shù)組:bool keys[256]。當(dāng)程序運(yùn)行過程中有鍵盤被按下或釋放時(shí)就捕捉這部分消息并標(biāo)記數(shù)組中對(duì)應(yīng)相應(yīng)鍵的組成員,這部分代碼添加在窗口消息處理函數(shù)LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)中。此函數(shù)中uMsg表示消息,wParam、lParam表示附加的消息內(nèi)容。如果有鍵被按下,通過讀取wParam的信息可以找出鍵值,將鍵盤數(shù)組keys[]相應(yīng)的數(shù)組組成員的值設(shè)為TRUE,這樣就可以通過查找key[]來(lái)得知什么鍵被按下。如果有鍵被釋放則將鍵盤數(shù)組keys[]相應(yīng)的數(shù)組組成員的值設(shè)為FALSE。

捕捉到相應(yīng)鍵盤消息后,將改變視點(diǎn)的代碼添加在函數(shù)WinMain()中。如按“↑”鍵可以使視點(diǎn)向前移動(dòng)的代碼如下:

3.2 漫游的實(shí)現(xiàn)

程序運(yùn)行后,系統(tǒng)提示用戶選擇窗口和全屏2種模式。全屏顯示下,漫游效果更為逼真、沉浸性更好。用戶可以用鍵盤中4個(gè)方向鍵進(jìn)行前進(jìn)、后退、左轉(zhuǎn)和右轉(zhuǎn)進(jìn)行漫游,用“PgUp”、“PgDn”兩個(gè)鍵進(jìn)行仰視和俯視的操作,還可以按下“F”鍵觀察同一位圖的3種不同紋理樣式生成不同場(chǎng)景的效果(按3次分別對(duì)應(yīng)3種變化)。

4 碰撞檢測(cè)的處理

如果不考慮碰撞檢測(cè)問題,在漫游過程中觀察者有時(shí)可能穿墻而過,故應(yīng)在系統(tǒng)中對(duì)這種情況進(jìn)行正確的處理。本系統(tǒng)處理方法[5]:記錄第1次動(dòng)作的視點(diǎn)位置,當(dāng)視點(diǎn)位置變換到一個(gè)新位置時(shí),判斷是否有墻面穿越新舊視點(diǎn)的連線,如果有,則這個(gè)視點(diǎn)位置變動(dòng)不能進(jìn)行,仍留在原位置,否則視點(diǎn)可以移動(dòng)到新的位置。如以按“↑”鍵由室內(nèi)向外穿過A1墻壁(見圖1所示,此墻在地面的投影為一線段,其左端點(diǎn)的坐標(biāo)為(-2,0,-2)、右端點(diǎn)的坐標(biāo)為(-0.5,0,-2))為例,需要在WinMain()函數(shù)中的檢測(cè)“↑”鍵被按下的代碼中添加新的內(nèi)容:

運(yùn)行表明以上代碼起到較好的作用,漫游時(shí)不會(huì)使視點(diǎn)穿過A1墻體。

5 結(jié)束語(yǔ)

運(yùn)用圖形程序庫(kù)和Visual C++6.0開發(fā)了一個(gè)三維場(chǎng)景漫游系統(tǒng)。系統(tǒng)實(shí)現(xiàn)中采用了光照、紋理映射、視點(diǎn)變換、碰撞檢測(cè)、全屏顯示等技術(shù),增強(qiáng)了虛擬場(chǎng)景的真實(shí)感和沉浸式交互性。

[1]樊雅萍,黃生學(xué),溫佩芝,等.基于OpenGL的機(jī)器人虛擬漫游系統(tǒng)開發(fā)[J].系統(tǒng)仿真學(xué)報(bào),2005,17(10):119-121.

[2]和平鴿工作室.OpenGL高級(jí)編程與可視化系統(tǒng)開發(fā)——高級(jí)編程篇[M].2版.北京:中國(guó)水利水電出版社,2006.

[3]劉興龍,王斌,張赭,等.農(nóng)業(yè)中三維地形可視化及其漫游技術(shù)的研究[J].農(nóng)機(jī)化研究,2008(9):179-181.

[4]郭蓬松,殷宏,晏峰,等.基于OpenGL的飛機(jī)虛擬場(chǎng)景漫游系統(tǒng)的實(shí)現(xiàn)[J].計(jì)算機(jī)工程與設(shè)計(jì),2005.26(7):1938-1941.

[5]李熳,張曙光,劉英.電力系統(tǒng)中基于多邊形與圖像繪制相結(jié)合的實(shí)時(shí)漫游[J].計(jì)算機(jī)工程與應(yīng)用,2003(11):222-224.

猜你喜歡
數(shù)據(jù)文件視點(diǎn)漫游
霹靂漫游堂
數(shù)據(jù)文件恢復(fù)專題問答
數(shù)據(jù)文件安全管控技術(shù)的研究與實(shí)現(xiàn)
SQL數(shù)據(jù)文件恢復(fù)工具
NASA漫游記
視點(diǎn)
河南電力(2016年5期)2016-02-06 02:11:24
讓你每天一元錢,物超所值——《今日視點(diǎn)—2014精萃》序
新聞前哨(2015年2期)2015-03-11 19:29:22
兩會(huì)視點(diǎn)
Tekla Structure數(shù)據(jù)文件交互格式分析
邊走邊看:漫游海底 夢(mèng)想成真
凌云县| 哈密市| 江都市| 龙井市| 贵德县| 郴州市| 广饶县| 赣州市| 屏山县| 新化县| 扎兰屯市| 锡林郭勒盟| 苏尼特左旗| 双江| 阳泉市| 炎陵县| 隆昌县| 咸丰县| 天等县| 韶山市| 高青县| 杭锦后旗| 西城区| 四平市| 东乡族自治县| 紫阳县| 梁山县| 奈曼旗| 吉隆县| 怀远县| 淳化县| 土默特右旗| 孝义市| 嘉禾县| 罗甸县| 卓资县| 绥宁县| 锦屏县| 九龙坡区| 斗六市| 阿瓦提县|