摘 要: 介紹了在Windows系統(tǒng)平臺及Visual C++ 6.0的MFC基礎(chǔ)類庫環(huán)境下,,采用OpenGL技術(shù)與串口通信技術(shù)實現(xiàn)的飛行仿真系統(tǒng)的設(shè)計思想與程序?qū)崿F(xiàn)方法,。
關(guān)鍵詞: 虛擬現(xiàn)實 OpenGL 六維鼠標(biāo) 串行口
虛擬現(xiàn)實是一種創(chuàng)建和體驗虛擬世界的計算機系統(tǒng),。利用虛擬現(xiàn)實技術(shù),,計算機可以產(chǎn)生一個三維的虛擬環(huán)境,通過人的視覺、觸覺等作用于人[1],。 用戶以客觀世界的實際動作或以人類熟悉的方式操作虛擬系統(tǒng),,從而實現(xiàn)立體交互,使人產(chǎn)生身臨其境的感覺。虛擬現(xiàn)實系統(tǒng)一般由輸入設(shè)備,、輸出設(shè)備,、虛擬環(huán)境生成器和高性能的計算機系統(tǒng)四大部分構(gòu)成,。
目前,OpenGL在虛擬現(xiàn)實領(lǐng)域是功能較強,,最具發(fā)展前途的實現(xiàn)工具,。OpenGL是美國高級圖形和高性能計算機系統(tǒng)公司(SGI)所開發(fā)的三維圖形庫,在當(dāng)前已經(jīng)成為事實上的高性能圖形和交互式視景處理的標(biāo)準(zhǔn)[2],。OpenGL是一個獨立的工作平臺,,用它編寫的程序可以在不同的硬件平臺(如工作站或個人微機)中使用,也可以在多種操作系統(tǒng)(如Windows系列,、OS/2等)下運行,。
經(jīng)過近幾年來的發(fā)展,虛擬現(xiàn)實技術(shù)及設(shè)備被很多領(lǐng)域應(yīng)用,,而飛行仿真是最重要的應(yīng)用領(lǐng)域之一,。本文所研究的飛行仿真系統(tǒng)采用新型六維控制器(六自由度鼠標(biāo))作為輸入設(shè)備,監(jiān)視器作為輸出設(shè)備,,以O(shè)penGL作虛擬環(huán)境生成器,,構(gòu)成一套高性能計算機處理系統(tǒng)來實現(xiàn)高度仿真的飛行模擬器運動。
1 構(gòu)建應(yīng)用程序框架
應(yīng)用Visual C++ 6.0建立一個基于MFC的應(yīng)用程序框架,,并將VC庫文件opengl32.lib,、glu32.lib和glaux.lib包含在應(yīng)用程序中。
為使OpenGL函數(shù)庫的調(diào)用有效,,首先應(yīng)設(shè)置渲染窗口,。OpenGL的渲染處理完全不同于Windows的圖形設(shè)備接口GDI。要使Windows的窗口格式為OpenGL所接受,,需進(jìn)行下列設(shè)置,。
1.1 建立圖形操作描述表
OpenGL作圖窗口必須設(shè)置為WM_CLIPSIBLINGS和WM_CLIPCHILDREN風(fēng)格。
在Windows98/2000系統(tǒng)下,,窗口程序首先要處理設(shè)備描述表(Device Contexts,,DC),它包括若干在窗口上如何顯示圖形的信息,。而在OpenGL程序中,,必須創(chuàng)建圖形操作描述表(Rending Context,RC),,這是DC中專用于OpenGL的一種,。但是RC不同于其他的DC,它只需要一個句柄就可以任意調(diào)用OpenGL函數(shù),,而其他DC調(diào)用每個GDI函數(shù)時都需要一個句柄,。
使用時先通過wglCreateContext()函數(shù)創(chuàng)建一個RC,然后調(diào)用wglMakeCurrent()函數(shù)啟動它,就可在所定義的窗口內(nèi)調(diào)用OpenGL函數(shù)繪制飛行器了,。
m_pDC=new CClientDC(this),;
hrc=wglCreateContext(m_pDC->GetSafeHdc( ));
wglMakeCurrent(m_pDC->GetSafeHdc( ),,hrc),;
1.2 設(shè)置像素格式
像素格式指定設(shè)備的繪圖屬性,包括繪圖界面的顏色表示模式,、顏色位數(shù),、累積緩存區(qū)、深度緩存區(qū)和模板緩存區(qū)的位數(shù),。每個OpenGL顯示設(shè)備都支持某一特定的像素格式,。像素格式用PIXELFORMATDESCRIPTOR結(jié)構(gòu)來表示,通過設(shè)置這一結(jié)構(gòu)的成員值使之支持OpenGL,。建立了圖形操作描述表并初始化PIXELFORMATDESCRIPTOR結(jié)構(gòu)后,,應(yīng)以此結(jié)構(gòu)為變量調(diào)用ChoosePixelFormat( )函數(shù)為設(shè)備描述表選擇像素格式,最后調(diào)用SetPixelFormat( )將其設(shè)置為當(dāng)前像素格式,。
int pixelformat;
pixelformat=ChoosePixelFormat(m_pDC->GetSafeHdc( ),,&pfd),;
SetPixelFormat(m_pDC->GetSafeHdc( ),pixelformat,,&pfd),;
2 繪制場景
2.1 準(zhǔn)備工作
開始繪制場景之前,需要用背景顏色刷新顯存,。飛行器在天空的背景中飛行,,因此應(yīng)將清除顏色緩沖區(qū)的顏色設(shè)為淡藍(lán)色,然后刷新顏色緩沖區(qū)和深度緩沖區(qū),。
glClearColor(0.75,,0.75,1.0,,1.0),;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
準(zhǔn)備工作還要考慮計算機屏幕是二維的,,要用它顯示逼真的三維物體就要用到圖形變換技術(shù),。同時程序還要保證,當(dāng)用戶隨意改變窗口大小時,,飛行器不會變形失真,。因此需要定義初始的坐標(biāo)變換。視圖類的OnSize事件對這些問題進(jìn)行處理。
2.2 設(shè)置光照效果
創(chuàng)建三維立體的場景時,,添加光線效果對于飛行器的真實感非常重要,。OpenGL的光照模型將光照成分劃分為四個獨立的部分:發(fā)射光、環(huán)境光,、散射光和鏡面反射光,。OpenGL獨立計算這四種光照成分,然后將其結(jié)果疊加,,從而得到最終的效果,。
設(shè)置光照應(yīng)分二步進(jìn)行。首先使用glLightfv( )函數(shù)設(shè)置光源的屬性和值,,創(chuàng)建系統(tǒng)光源,。本文定義了四個GLfloat數(shù)組sunposition、suncolor,、sunambient和sunspecular,,分別作為光源位置、光源的散射光亮度,、環(huán)境光亮度和鏡面反射光亮度的屬性值,。然后用glEnable(GL_LIGHTING)啟動OpenGL的光照處理功能。再用glEnable(GL_LIGHT0)打開設(shè)置的光源,。
3 繪制飛行器
飛行器是一個較為復(fù)雜的三維圖形對象,,它需要使用二次曲面和多邊形鑲嵌工具來創(chuàng)作,并通過OpenGL的紋理映射技術(shù)給飛行器穿上漂亮的外衣,。
3.1 飛行器構(gòu)造原理
按照組成飛行器對象的幾何形體的特點,,可將飛行器構(gòu)造用二次曲面(quadric)和多邊形(polygon)表示。具體來說,,機頭用錐形表示,;機體是柱形;尾部的發(fā)動機用錐形的柱體來表示,;飛行器的頂棚可以用一個拉長的球體來表示,,把球體的透明度設(shè)為0.65,使之具有玻璃的效果,,這些部分是二次曲面,。例如機體繪制命令為:
gluCylinder(quadric,0.25,,0.25,,3.5,20,,2),;
而機翼和機尾的各個部分都是多邊形的,,應(yīng)使用多邊形鑲嵌工具來繪制。例如機尾繪制命令為:
gluTessBeginPolygon(tess,,NULL),;
gluTessBeginContour(tess);
for (i=0,;i<6,;i ++)
gluTessVertex(tess,tail[i],,tail[i]),;
gluTessEndContour(tess);
gluTessEndPolygon(tess),;
3.2 程序?qū)崿F(xiàn)方法
程序?qū)崿F(xiàn)應(yīng)用了顯示列表技術(shù),。OpenGL的顯示列表是事先存儲的用于稍后執(zhí)行的一組OpenGL命令序列。分析了飛行器的幾何形體構(gòu)造,、設(shè)置完繪制命令并進(jìn)行紋理貼圖美化飛行器外表后,,就可將各個部分的構(gòu)造程序代碼編輯到顯示列表里存儲起來了。
F16Body=glGenLists(1),;
glNewList(F16Body,,GL_COMPILE);
最后調(diào)用函數(shù)glEndList( ),,標(biāo)志一個顯示列表的結(jié)束,。
在視圖類的DrawScene( )事件的適當(dāng)位置用函數(shù)glCall-
List(F16Body)調(diào)用顯示列表,從而按照預(yù)先定義的順序執(zhí)行飛行器模型的繪制,。
4 六維鼠標(biāo)控制的飛行仿真系統(tǒng)總體設(shè)計
4.1 六維鼠標(biāo)的工作原理
現(xiàn)實中飛行器是可以進(jìn)行三維移動以及三維旋轉(zhuǎn)運動的,因此在飛行仿真系統(tǒng)中就需要一種可以實現(xiàn)上述運動模式的輸入控制設(shè)備,。這里選擇了一種新型并聯(lián)結(jié)構(gòu)六維控制器,,即六維鼠標(biāo)。
該六維鼠標(biāo)基于力控制原理,,通過集成A/D轉(zhuǎn)換器的動態(tài)應(yīng)變儀與計算機的COM1口(串行口1)相連,,采用串行通信機制。操作者握住鼠標(biāo),,向所要移動或轉(zhuǎn)動的方向用力,,鼠標(biāo)將受到的六維力傳遞到內(nèi)部的微型六維力敏感元件,接著通過鼠標(biāo)內(nèi)部機制生成與該力成正比的電壓信號,,并將電壓信號放大后采集進(jìn)計算機,,利用力Jacobian矩陣求出鼠標(biāo)受到的空間作用力情況[3]。六維鼠標(biāo)的控制系統(tǒng)軟件實現(xiàn)將三個力分量分別乘以某個大于零的系數(shù),,生成飛行器作空間直線運動的位移分量,,從而控制仿真系統(tǒng)中飛行器的平移運動,;將三個力矩分量經(jīng)過一定算法的變換后產(chǎn)生飛行器繞X、Y,、Z三個坐標(biāo)軸轉(zhuǎn)動的角位移,,從而控制飛行器的旋轉(zhuǎn)運動, 在算法中應(yīng)用到了六維鼠標(biāo)的標(biāo)定矩陣G6×6。具體變換算法請查閱文獻(xiàn)3,。圖1描述了六維鼠標(biāo)的工作原理流程,。
4.2 仿真系統(tǒng)總體設(shè)計
六維鼠標(biāo)和計算機之間采用串口通信,所以在程序設(shè)計中選用了MSComm控件,。該控件通過串行端口傳送和接收數(shù)據(jù),,從而為應(yīng)用程序?qū)崿F(xiàn)串行通信功能[4]。MSComm控件將通信的大部分底層操作都封裝在控件內(nèi)部,,應(yīng)用程序只需獲取和設(shè)置相應(yīng)的控件屬性即可,,簡化了編程的復(fù)雜度。在Visual C++ 6.0中使用該控件的基本流程如圖2所示,。
本仿真系統(tǒng)中當(dāng)控件插入工程后,,應(yīng)將串口初始化及打開命令放在視圖類的OnCreate()事件中。在應(yīng)用程序建立時就打開串口,,準(zhǔn)備接收鼠標(biāo)數(shù)據(jù),。
應(yīng)用MSComm控件的OnComm( )事件作為對六維鼠標(biāo)輸入數(shù)據(jù)的響應(yīng)事件,并在事件處理中實現(xiàn)對飛行器的運動控制,。首先檢測串口的GetCommEvent( )事件,,如果該事件返回值為2,表示接收緩沖區(qū)內(nèi)的字符數(shù)達(dá)到Rthreshold值,,發(fā)生接收事件(comEvReceive),。接下來編寫接收數(shù)據(jù)的過程,實現(xiàn)將鼠標(biāo)傳輸?shù)臄?shù)據(jù)轉(zhuǎn)化為三個平移分量(Xp,、Yp,、Zp)和三個旋轉(zhuǎn)分量(Xr、Yr,、Zr),。將Xp、Yp,、Zp,、Xr、Yr,、Zr六個控制變量傳遞給DrawScene( )函數(shù),,在飛行器繪制之前修改視景坐標(biāo)系,從而控制飛行器的運動,。
glTranslatef(Xp,,0.0f,,0.0f);
glTranslatef(0.0f,,Yp/10,,0.0f);
glTranslatef(0.0f,,0.0f,,-Zp);
glRotated(Xr-37,,1.0,,0.0,0.0),;
glRotated(Yr-7,,0.0,1.0,,0.0),;
glRotated(Zr-2,0.0,,0.0,,1.0);
glCallList(F16Body),;
系統(tǒng)總體實現(xiàn)流程如圖3所示,。
5 結(jié) 論
本文所開發(fā)的飛行器仿真系統(tǒng)使用Visual C++ 6.0作為軟件平臺,應(yīng)用OpenGL來開發(fā)具有六維運動能力的飛行模擬器和高度真實感的三維地形,,以六維鼠標(biāo)作為飛行器的控制輸入設(shè)備,,通過串行通信機制控制計算機中的仿真系統(tǒng)。用戶通過給六維鼠標(biāo)施加不同方向,、不同大小的力來自由控制系統(tǒng)中飛行模擬器的運動,,實現(xiàn)飛行器在虛擬地形環(huán)境中的三維移動和三維轉(zhuǎn)動,從而實現(xiàn)對真實世界中飛行器運動的仿真,。
參考文獻(xiàn)
1 毛玉姣,,王梅,,陳遠(yuǎn).虛擬現(xiàn)實技術(shù)及其應(yīng)用.圖書情報知識,,1997;(4)
2 戴達(dá)強,,姜曉彤,,朱欣華.OpenGL在圖形仿真系統(tǒng)中的應(yīng)用.現(xiàn)代電子技術(shù),2001,;(9)
3 趙現(xiàn)朝,,金振林.六維鼠標(biāo)中力矩與轉(zhuǎn)角轉(zhuǎn)換的一種新方法. 計算機工程,,2002;(7)
4 李現(xiàn)勇.Visual C++串口通信技術(shù)與工程實踐.北京:人民郵電出版社,,2002