摘 要:現(xiàn)代仿真技術(shù)已經(jīng)不滿足于單純的數(shù)字仿真,為了更好的表達(dá)效果,視景仿真作為人機(jī)交互的手段,成為了必然的選擇。對(duì)于基于OpenGL的魚(yú)雷仿真系統(tǒng)進(jìn)行了詳細(xì)的描述。為了能更方便的建立復(fù)雜的三維模型,應(yīng)用了3DS作為OpenGL的輔助建模工具,同時(shí)利用OpenGL讀取3DS模型。建立了仿真的框架,十分詳細(xì)的講述了仿真渲染的過(guò)程,同時(shí)應(yīng)用了一種提高渲染速度的新方法。最后以仿真圖的形式給出了仿真結(jié)果,探討了繼續(xù)努力的方向。
關(guān)鍵詞:視景仿真;OpenGL;3DS;魚(yú)雷;渲染;VC++;編程
中圖分類(lèi)號(hào):TP391文獻(xiàn)標(biāo)志碼:A文章編號(hào):1671-7953(2009)01-0037-04
Fish Torpedo Simulation and Rendering with OpenGL and 3DS
LI Huan-huan
(computer college of Qinghua University,Beijing 100001,China)
Abstract: Modern simulation technology is not good enough with simple digital simulation.For better effect, visual simulation method,a human-machine interaction method has become inevitable choice.Torpedoes simulation system Based on OpenGL is discussed in detail. In order to build complex 3d model of application more conveniently, 3ds is used as OpenGL modeling tools.Simultaneous it reads 3ds model.The simulation framework is established, the process of simulation and rendering are shown detailed. A new method to improve rendering speed is applied. Finally the simulation diagram for results is demonstrated, and future work is discussed.
Key words: visual simulation;OpenGL;3DS;fish torpedo;rendering;VC++;computer programing
隨著計(jì)算機(jī)圖形技術(shù)的發(fā)展,可視仿真技術(shù)并已得到了比較廣泛的應(yīng)用。可視仿真將數(shù)據(jù)結(jié)果轉(zhuǎn)換為圖形或動(dòng)畫(huà)方式,使仿真結(jié)果可視化并具有直觀性。多媒體仿真通過(guò)將仿真所產(chǎn)生的信息和數(shù)據(jù)轉(zhuǎn)換成為可被感受的場(chǎng)景、圖示和過(guò)程,它充分利用多媒體手段,將可視化、臨場(chǎng)感、交互、激發(fā)想象結(jié)合到一起產(chǎn)生一種沉浸感,使仿真中的人機(jī)交互方式向自然更靠近了一步。使人可以“進(jìn)入”這種虛擬的環(huán)境直接觀察事物的內(nèi)在變化,并與事物發(fā)生相互作用,給人一種“身臨其境”的真實(shí)感。本文就基于OpenGL和3Dmax建立了魚(yú)雷可視化仿真系統(tǒng)[1]。
1 penGL生成動(dòng)畫(huà)
OpenGL是一個(gè)圖形發(fā)生器的軟件接口,它包括了100多個(gè)圖形操作函數(shù)[2]。OpenGL作為一個(gè)與硬件無(wú)關(guān)的圖形接口,它的圖形操作函數(shù)非?;?、靈活,提供了多種三維圖形的繪制方式。屏幕上所繪的圖形都是由像素組成的,每個(gè)像素都有一個(gè)固定的顏色或帶有相應(yīng)點(diǎn)的其它信息,如深度信息。因此在繪制圖形時(shí),內(nèi)存中必須為每個(gè)像素均勻地保存數(shù)據(jù)。這塊為所有像素保存數(shù)據(jù)的內(nèi)存就叫緩存(Buffer),系統(tǒng)中所有這類(lèi)緩存統(tǒng)稱為幀緩存(Frame Buffer)。OpenGL 幀緩存由以下四種緩存組成:顏色緩存(Color Buffer)、深度緩存(Depth Buffer)、模板緩存(Stencil Buffer)和累積緩存(Accumulation Buffer)。OpenGL 提供了雙緩存,用來(lái)制作動(dòng)畫(huà)。也就是說(shuō)它提供前后臺(tái)兩個(gè)緩存,當(dāng)一個(gè)緩存用于顯示的時(shí)候,另一個(gè)用于繪制圖形,在繪制完成后再交換,依次循環(huán)形成動(dòng)畫(huà)。通常用圖1所示流程開(kāi)發(fā)[3]。

2 魚(yú)雷建模
2.1 基于3Dmax的建模
建??梢詰?yīng)用OpenGL直接實(shí)現(xiàn),但在三維圖形程序中,經(jīng)常要繪制許多復(fù)雜的圖形,單純利用OpenGL的實(shí)例庫(kù)提供的基本幾何體構(gòu)造就顯得比較麻煩,本文在三維實(shí)體的建模工程中采用3DS建模工具進(jìn)行模型的編輯(如圖2所示),最后通過(guò)將模型的數(shù)據(jù)以通用的圖形格式3DS輸出存儲(chǔ),供應(yīng)用程序的使用[4]。

2.2 OpenGl讀取三維圖形
將3DS文件讀入相應(yīng)的數(shù)據(jù)結(jié)構(gòu)中,主要包括讀入當(dāng)前形體對(duì)象的頂點(diǎn)列表、面列表、紋理映射坐標(biāo)、平移矩陣,讀入默認(rèn)材質(zhì)、物體塊、當(dāng)前材質(zhì)塊的信息,讀入一個(gè)RGB三元組、紋理、物體主塊等信息。
3 OpenGL的渲染
OpenGL共有約115個(gè)圖形函數(shù)。利用這些函數(shù),能夠產(chǎn)生明暗、紋理映射、反走樣、光照、運(yùn)動(dòng)模糊、霧化、融合等圖形效果[5]。在Window98/NT平臺(tái)下,GDI是原始窗口的圖形接口,能夠把數(shù)據(jù)繪制到屏幕、內(nèi)存、打印機(jī)等。GDI實(shí)現(xiàn)這些是通過(guò)一個(gè)設(shè)備上下文(Device Content 簡(jiǎn)稱DC)來(lái)實(shí)現(xiàn)的。它的調(diào)用均傳送給DC,由DC來(lái)實(shí)現(xiàn)具體的操作。就像GDI需要建立設(shè)備上下文以繪制圖形一樣,OpenGL需要建立繪圖上下文。(Rendering Content 簡(jiǎn)稱RC)來(lái)繪制圖形。與每個(gè)GDI調(diào)用需要為其指定一個(gè)DC不同,OpenGL引入了當(dāng)前RC的概念,所有的操作都是針對(duì)當(dāng)前RC的。盡管在一個(gè)線程中可以有多RC,但是在任意時(shí)刻該線程中僅允許有一個(gè)當(dāng)前RC。RC不能直接完成繪圖,必須與特定的DC相聯(lián)系,在繪圖時(shí)OpenGL將繪圖參數(shù)傳遞給RC,RC再將其經(jīng)過(guò)一定的變換后傳遞給它所關(guān)聯(lián)的DC,完成具體的繪制工作。
3.1 渲染環(huán)境初始化
對(duì)于仿真的渲染,首先要進(jìn)行OpenGL渲染環(huán)境初始化。本文主要按照以下的設(shè)置方式來(lái)完成渲染環(huán)境的設(shè)置:
1)通過(guò)Initial函數(shù)完成對(duì)OpenGL的初始化,主要完成視圖模式、變換模式的設(shè)置。這些初始設(shè)置主要是通過(guò)glMatrixMode(),glLoadIdentity(),gluPerspective(),glMatrixMode()等函數(shù)調(diào)用來(lái)實(shí)現(xiàn)的。而且在初始化階段,調(diào)用了Windows專用OpenGL庫(kù)函數(shù)來(lái)建立Windows視圖與OpenGL窗口的聯(lián)系。本文主要調(diào)用了wglCreateContext()函數(shù)來(lái)創(chuàng)建圖形描述表,調(diào)用wglMakeCurrent()函數(shù)來(lái)啟用這個(gè)圖形描述表。
2)通過(guò)CreateRGBPaleete()函數(shù)來(lái)設(shè)置繪圖的調(diào)色板。
3)通過(guò)調(diào)用SetupPixelFormat()函數(shù)來(lái)為指定的設(shè)備內(nèi)容設(shè)置象素格式。
其中用到的象素存貯格式為:
PIXELFORMATDESCRIPTOR pfd =
{ sizeof(PIXELFORMATDESCRIPTOR),// 結(jié)構(gòu)的大小
1,// 版本號(hào)
PFD_DRAW_TO_WINDOW | // 支持窗口模式
PFD_SUPPORT_OPENGL | // 支持OpenGL
PFD_DOUBLEBUFFER,// 雙緩沖
PFD_TYPE_RGBA,// RGBA 模式
24,// 24位顏色深度
0,0,0,0,0,0,// 忽略顏色位
0,// 無(wú)α緩沖
0,// 忽略位移位
0,// 無(wú)累加器緩沖
0,0,0,0,// 忽略累加位
32,// 32位深度緩沖
0,// 無(wú)模板緩沖
0,// 無(wú)輔助緩沖
PFD_MAIN_PLANE,// 主繪圖層
0,// 保留
0,0,0 // 忽略層掩碼
};
4)調(diào)用ComponentFromIndex()函數(shù)從顏色索引獲取該索引對(duì)應(yīng)的RGB顏色分量
5)調(diào)用DrawScene()函數(shù)繪制三維葉片圖形。
3.2 OPENGL渲染視圖的視角變換
在這里,我們相關(guān)變換與真實(shí)生活中的照相機(jī)拍攝過(guò)程進(jìn)行類(lèi)比,使得OPENGL環(huán)境中的三維視圖變換更容易理解,本文中所進(jìn)行的相關(guān)變換主要包括[5]:
1)三維圖形到二維基元級(jí)的任意角度變換。類(lèi)似于將照相機(jī)固定在三角架上并使相機(jī)對(duì)準(zhǔn)場(chǎng)景,這個(gè)變換屬于OPENGL中的視圖變化。
2)三維視角范圍大小的變換。類(lèi)似于選擇相機(jī)鏡頭或者放大倍數(shù),這個(gè)變化屬于OPENGL中的投影變化。
3)視圖的遠(yuǎn)近變換。類(lèi)似于決定最終照片尺寸的大小,比如想要得到的使一張經(jīng)過(guò)放大后的照片,這個(gè)變換屬于OPENGL中的視區(qū)變化。
4)三維立體圖與投影變換。類(lèi)似于使想要拍攝的場(chǎng)景處于取景框中的合適位置,這個(gè)變化屬于OPENGL中的模型變化。
在本文中主要是通過(guò)調(diào)用glRotatef(TYPE angle,TYPE x,TYPE y,TYPE z)來(lái)實(shí)現(xiàn)相對(duì)于原點(diǎn)的旋轉(zhuǎn);通過(guò)調(diào)用glTranslatef(TYPE x,TYPE y,TYPE z)來(lái)實(shí)現(xiàn)平移變換,這些平移變換包括x,y,z三個(gè)方向的平移;通過(guò)調(diào)用glScalef(TYPE x,TYPE y,TYPE z)函數(shù)來(lái)實(shí)現(xiàn)大小比例縮放,當(dāng)參數(shù)大于1時(shí)表示放大,小于1時(shí)則為縮??;通過(guò)調(diào)用gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)函數(shù)來(lái)實(shí)現(xiàn)觀察的視角范圍和視圖的遠(yuǎn)近調(diào)節(jié),參數(shù)fovy表示視角范圍的大小,zNear和zFar分別表示視圖可以調(diào)節(jié)的最近距離和最遠(yuǎn)距離。
3.3 三維視圖的光照渲染
由于真實(shí)世界與模擬場(chǎng)景的差別之一在于:真實(shí)世界存在各種強(qiáng)度的光照,而模擬場(chǎng)景則沒(méi)有自然的光照,必須人為的為模型添加光照。而OpenGL近似的將光線分解成紅、綠、籃三種成分,光源的顏色則就取決于它所發(fā)出的紅、綠、藍(lán)光的和。表面的材質(zhì)特征則是由這個(gè)表面在各個(gè)方向反射的紅、綠、藍(lán)光的百分比決定。雖然OpenGL的光照方程僅是一種近似的算法,但與實(shí)際是十分接近的,并且可以達(dá)到很快的計(jì)算速度。OpenGL的光照模型假定光源只對(duì)吸收或反射光線的表面產(chǎn)生影響,同時(shí)認(rèn)為每個(gè)表面都可以由不同屬性的材質(zhì)構(gòu)成,材質(zhì)本身也可能產(chǎn)生光線,并能將入射光線散射到各個(gè)方向,或者像鏡子等其它光滑表面那樣將大部分光線反射到特定方向。OpenGL的光照模型將光照分成四個(gè)獨(dú)立的成分:發(fā)射光,環(huán)境光,散射光,鏡面反射光,將四種成分獨(dú)立的計(jì)算,然后疊加到一起。一般需要先選擇某一特定光照模型,并設(shè)置這個(gè)光照模型的位置,使得光照效果最合適,最后才定義其它的材質(zhì)屬性等等性質(zhì)。
3.4 渲染加速
由于采集的數(shù)據(jù)較大而且重構(gòu)精度較高,所以反算出的控制點(diǎn)很多,在進(jìn)行渲染時(shí),需要一定的時(shí)間。如果對(duì)渲染后的圖像進(jìn)行變換(平移、旋轉(zhuǎn))時(shí),顯示速度會(huì)更慢。為了提高曲面的繪制效率,采取了圖形優(yōu)化技術(shù)-顯示列表。 顯示列表是一組存儲(chǔ)起來(lái)的OpenGL命令。引用顯示列表時(shí),按順序執(zhí)行其中的OpenGL命令,可以在程序中不同地方使用這些命令。與子程序不同的是,這些命令是經(jīng)過(guò)編譯的,執(zhí)行效率高,從而可以有效地提供OpenGL的繪圖性能。OpenGL顯示列表是一系列命令的高速緩存,而不是內(nèi)存中的動(dòng)態(tài)數(shù)據(jù)庫(kù),不必進(jìn)行內(nèi)存管理,使繪圖性能大幅度地提高。即使使用顯示列表只繪制一個(gè)簡(jiǎn)單圖形,也不會(huì)比EXECUTE模式的速度慢。
創(chuàng)建和執(zhí)行顯示列表的步驟是:1)建一個(gè)顯示列表,使用一對(duì)函數(shù)glNewList(Gluint list, Glenum mode)和glEndlist(void)來(lái)標(biāo)志顯示列表的開(kāi)始和結(jié)束,兩者之間的命令被定義為一個(gè)由list標(biāo)識(shí)的顯示列表,若把這些命令放入顯示列表而不執(zhí)行時(shí),mode為GL-COMPILE,而把這些命令放入顯示列表并同時(shí)立即執(zhí)行時(shí),mode為GL-COMPILE-AND-EXECUTE。顯示列表只存儲(chǔ)數(shù)值,在創(chuàng)建顯示列表后,即使所引用的數(shù)值有改變,也不會(huì)影響顯示列表的內(nèi)容。2)執(zhí)行一個(gè)顯示列表,在創(chuàng)建顯示列表后,可以使用glCallList調(diào)用標(biāo)識(shí)為list的顯示列表,可以對(duì)同一個(gè)顯示列表調(diào)用多次。調(diào)用時(shí),顯示列表中的命令將按排列的順序依次執(zhí)行[5-6]。
3.5 漢字顯示
在雙緩沖區(qū)模式下顯示文本的基本思想是:將字符當(dāng)作一般的OpenGL 物體來(lái)處理,用wglUseOutlines或 wglUseFontBitmaps為每個(gè)字生成一個(gè)List,為每個(gè)字調(diào)用 glCallList()或?yàn)橐粋€(gè)字符串調(diào)用glCallLists()。
在OpenGL設(shè)計(jì)時(shí)考慮了非ASCII 字符集文字的需求,因此在OpenGL中使用漢字是不成為問(wèn)題的。如果只使用英文字符,可以使用下面代碼:
在OpenGL初始化的末尾建立字體:#define LISTBASE 1000
wglUseFontBitmaps(Hdc,0,255,LISTBASE);
在需要輸出文字的地方調(diào)用:char pMyString=“ OpenGL Text Info”;
glListBase(LISTBASE);
glCallLists(strlen(pMyString),GL_UNSIGNED_BYTE,pMyString);
但用這種方法不能顯示中文,原因是中文字符的編碼(國(guó)際碼)使用的是雙字節(jié)編碼。解決問(wèn)題的方法是根據(jù)文本串中字符的特性對(duì)其進(jìn)行分別處理,對(duì)于ASCII碼字符,按通常的方法創(chuàng)建顯示列表,即用單字節(jié)變量作為first參數(shù)的值調(diào)用wglUseOutlines()函數(shù);對(duì)于中文字符,用雙字節(jié)變量作為first參數(shù)的值調(diào)用wglUseOutlines()函數(shù)。
4 仿真系統(tǒng)結(jié)構(gòu)框架
仿真演示系統(tǒng)所要求的基本內(nèi)容包括:1)接收彈道計(jì)算仿真結(jié)果并發(fā)布系統(tǒng)仿真過(guò)程的啟動(dòng)、終止命令及時(shí)間基準(zhǔn)等標(biāo)志;2)仿真系統(tǒng)動(dòng)畫(huà)演示及聲音媒體表現(xiàn);3)可視化駕馭功能,如控制演示系統(tǒng)的視點(diǎn)方向、視區(qū)大小、移動(dòng)、旋轉(zhuǎn)、圖形的放大縮小等。以上部分必須有機(jī)的聯(lián)系在一起,才能真正實(shí)現(xiàn)實(shí)時(shí)動(dòng)畫(huà)演示,這三部分存在著大量的數(shù)據(jù)交互更新,以保證仿真計(jì)算與真實(shí)感圖形輸出的同步及其交互控制對(duì)仿真產(chǎn)生立即作用。

5 結(jié)論
仿真結(jié)果如圖4所示[7]。從圖4可以看到,整個(gè)仿真系統(tǒng)包含兩部分:內(nèi)部數(shù)字仿真計(jì)算和視景仿真輸出,由于篇幅的原因,本文只詳細(xì)講述了OpenGL的視景仿真部分,注意力放在了外部特征的逼真度上,這還要配合準(zhǔn)確的內(nèi)部模型,才能真正模擬真實(shí)物理世界。從結(jié)果上看,本系統(tǒng)能夠準(zhǔn)確模擬魚(yú)雷的特征,但各種各樣的目標(biāo)OpenGL建模并不是很完全(如艦船等),這都將是進(jìn)一步努力的方向。
參考文獻(xiàn)
[1]HOU PENG,HE NAIGANG,SHEN GONGXUN, The Realizing of Visualized Simulation Based on OpenGL in Strapdown Inertial Navigation System[J].
MEASUREMENT CONTROL TECH NOL
OGY,2002(3):45-47.
[2] OPEGL company.OpenGL API Documentation Overview[D].http://www.opengl. org/ documentation/
[3] ZHANG Wei-li.Doyle Knight and Don Smith:automated Design of a Three Dimensional Subsonic Diffuser[J].AIAA Paper 2000-0665.
[4] S.KENNEDY,G.MAESTRI,et al.3D Studio Max[M].New Riders Publishing,1998.
[5] RANDI J.ROST,OpenGL(R) Shading Language [M].Addison-Wesley Professional,2 edition (February 4,2006)
[6] PDFCube 0.0.3 improves its rendering routines based on OpenGL,http://www. opengl.org/,2008.12.
[7] SIMON PREMOZE,MICHAEL ASHIKHMIN,Rendering Natural Waters[J].Proceedings of Pacific Graphics'2000,23-30.