虛擬現實技術基礎與應用代碼-8 綜合實例_第1頁
虛擬現實技術基礎與應用代碼-8 綜合實例_第2頁
虛擬現實技術基礎與應用代碼-8 綜合實例_第3頁
虛擬現實技術基礎與應用代碼-8 綜合實例_第4頁
虛擬現實技術基礎與應用代碼-8 綜合實例_第5頁
已閱讀5頁,還剩5頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、8.3.2場景模型的構建建立了消防車的3ds模型后,我們就可以來定義一個消防車類了。消防車類中包含車 身、云梯、吊籃成員對象,這些對象通過前節介紹的3ds載入類C3DSLoader來定義。此外 我們在吊籃上安置一個消防水槍來模擬噴水效果,為此用前章定義好的粒子系統類 CparticleSys來定義一個水槍效果對象。為實現云梯的交互運動,增加了云梯水平旋轉的 變量theta,和俯仰運動的變量phi。車身的運動由變量Position來控制。其消防車類的定 義如下:注:以下代碼寫在文件Motor.h中#include gl/glut.h”#include H3DSLoader.hH#inchide

2、Particle.hclass CMotor/消防車類( public:float Position3;車位置float theta;云梯支架旋轉角float phi;云梯俯仰角定義3ds載入對象C3DSLoader m_3DSMotor;車 身C3DSLoader m_3DSSupport;云梯支架C3DSLoader m_3DSLadder;云梯C3DSLoader m_3DSBasket;籃子CParticleSys m_WaterGun;水 槍效果CMotorQ;構造函數virtual y Motor。;析構函數void Dra wMotor();繪制車void Init();初始化;

3、車身模型,云梯模型和吊籃模型的載入以及水槍的初始化通過成員函數Init來完成, 其實現形式如下:注:以下代碼寫在文件Motor.cpp中void CMotor: :IiutO (m_3DSMotor.Load3DSModel(H3DSModel 武警學院車身 1.3DS”); m_3DSSupport.Load3DSModel(n3DSModel 云梯支架.3ds”); m_3DSLadder.Load3DSModel(n3DSModel 云梯.3ds“); m_3DSBasket.Load3DSModelC3DSModel 吊籃.3ds“); m_WaterGiin. SetPosition

4、(0,0,0);水槍位置m_WaterGun.SetMode(0.5 JOO, 10 廣 0.8 J); /粒子系統模式設置 m_Watei,Gun.Init(PI/2,PI/3); 水 槍方向消防車的繪制過程在成員函數DrawMotor中來完成,其實現形式如下: 注:以下代碼寫在文件Motor.cpp中 void CMotor:DrarMotor()glPusliMatiix();車身glColor3f(l .0,1.0,1.0);glRotatef(90,0.0,1.0,0.0);車的面向glScalef(1.0, 1.0, 1.0); m_3DSMotor.DrawO;旋轉支架glSca

5、lef(1.0, 1.0, 1.0);glTranslatef(0.0f?73.0f,-130.0f);glRotatef(theta,0.0,1.0,0.0); 支架旋轉m_3DSSupport.Draw();云梯glScalef(1.0, 1.0, 1.0);glTranslatef(0.0f?27.0f,0.0f);glRotatef(phi, 1 0?0.0,0.0);云梯俯仰m_3DSLadder.Draw();/籃glTranslatef(O.Ofr 10.0280.00;glRotatef(phi, 1.000,0.0);籃保持水平m_3DSBasket.Draw();/水槍gl

6、Translatef(0.0f,50.0f,0.0f);glScalef(5.0, 5.0, 5.0); m_Wateijiin.DrawSys();glPopMatrix();定義一個地面類Cground,其類的定義形式如下:注:以下代碼寫在文件Grouiid.h中#iiiclude CBMPTexture.h”class CGroimdpublic:CBMPTexture textObj;地面紋理floatlength;長度floatwidth;寬度floatheight;局度CGroiuid0();構造函數CGround(chai, file255); 構造函數virtual CGrou

7、nd();析構函數void Render0;繪制void Iiiit();初始化類Cground中通過構造函數來載入位圖文件,并對成員對象textObj及其他數據進行初始化,其實現代碼為:注:以下代碼寫在文件Ground.cpp中CGroimd: CGiound(char file255):textObj(l?file) (length=450.0f; 縱深width=450.0f; 寬height=5.Of; 高地面的紋理過程通過調用成員函數Init來實現,其實現代碼為:注:以下代碼寫在文件Ground.cpp中 void CGroimd:Init() (textObj Texturehii

8、tO; 地面紋理由此獲得的紋理名稱存放在對象textObj的數據成員texture0中。定義好紋理后,就可以來繪制地面了。地面的繪制通過調用成員函數Render來實現, 其實現代碼為:注:以下代碼寫在文件Groxuid.cpp中 void CGround: Render。 (獲得場景中光照狀態GLboolean Ip;glGetBooleanv(GL_LIGHTING,&lp);glDisable(GL_LIGHTING); 關閉光照/開始繪制glEnable(GL_TEXTURE_2D);/繪制地面glPusliMatiix();glTranslatef(050r10);glBindText

9、uie(GL_TEXTURE_2D, textObj.texture0); glBegin(GL_QUADS);指電紋理坐標和頂點坐標glTexCoord2f(l .0f? O.Of); gl宅rtex3f( width, heiglit, lengtli);glTexCoord2f(1.0f? l .Of); gl宅rtex3f( width, height, -length); glTexCoord2f(0.0f? l .Of); gl宅rtex3f( -width, height, -lengtli); glTexCoord2f(0.Of, O.Of); gl宅rtex3f( width

10、, height, length);glEnd();glPopMatrixO;/繪制結束if(lp)/恢復光照狀態glEnable(GL_LIGHTING); 1.場景類的描述以下我們來定義一個場景類,場景類是一個組合類,其數據成員包括:一個地面對象, 一個消防車對象,一個油罐對象以及火焰對象,此外還包含相應的初始化函數和圖形繪制函 數,場景類的描述如下:/注:以卜代碼寫在文件Scene.h中#include Wotor.1T#include Ground.h” class CScenepublic:float PI;float rad;圓周率角度(弧度)float angle;角度float

11、 Look3;觀察目標點float Eye3;眼睛位置CGrotmd ground; 大地CMotor motor; 消防車CPaiticleSys m_Fire; 火焰C3DSLoader buildl;建筑物(油罐)CSceneO;構造函數CScene(char filel255); 構造函數virtual y Scene。; 析構函數void ImtO;/初始化void DrawSceneQ;繪制;帶參數的構造函數主要對類Cscene對象的屬性進行初始化,其實現形式如下: 注:以下代碼寫在文件Scene.cpp中CScene: :CScene(char file 1 255): gi-o

12、und(file 1)angle=-90.0;PI=3.14159;rad=float(PI*aiigle/l 80.0);Eyel=30.0;Eye2=300.0;觀察目標點的位置Look0=0.0;Lookl=30.0;Look =0.0;motor.Position0=Eye0; /消防車的位置 motor.Position 1 =0;motor.Position2=Eye2;而成員函數Init主要對類Cscene中內嵌對象ground, motor m_Fire和buildl的紋 理映射進行初始化,其實現形式取下:注:以卜代碼寫在文件Scene.cpp中void CScene: :In

13、itOmotor.InitO; gi-ound.Iiiit();buildl.Load3DSModelC3DSModel 臥式油罐.3DS,火焰設置m_Fire.SetPosition(200.0,63.0,0.0);m_Fire.SetMode(20,50,10,0.0,0);m_Fire.Init(PI/2,0);成員函數DrawScene主要完成類Cscene中各個內嵌對象的繪制工作,實現形式為:注:以卜代碼寫在文件Scene.cpp中void CScene:DrawSceneO(消防車隨控制鍵運動,位置更新motor.Position0=Eye0;motor.Position 1 =1

14、0;motor.Position2=Eye2;地面glPusliMatiix();glColor3f(l.0,1.0,1.0);改變顏色ground.Render();glPopMatiix();火焰glPusliMatiix();glColor3f(l .0,1.0,1.0);/改變顏色m_F ire. DrawSysO ;glPopMatiix();建筑物glPusliMatiix();glColor3Rl.0,1.0,1.0);glTranslatef(200.0,30.000);glScalef(1.0,1.0,1.0);buildl.DiawO;繪制建筑物glPopMatiix();

15、消防車(整體)glPusliMatiix();設消防車位置glTranslatef(motor. PositionfO motor.Positionl 1 Lmotor.Position2);glRotatef(angle)0.0,1.0,0.0);glScalef(020.2,0.2);motor. Dra wMotorQ;繪制消防車glPopMatrixO;8.3.3初始化場景在三維場景的初始化中,主要涉及相關庫文件的包含,窗II的大小,場景的大小,場 景對象的定義,以及光照效果設置等,其代碼如下:/注:以下代碼寫在文件maiii.cpp中#include #include #includ

16、e HScene.hHGLint screen Width=800; 窗 口 寬GLint screenHeight=600; 窗I 高GLint scene Width=450;場景橫寬GLint sceneLength=450;場景縱深GLfloat m_width; 記錄窗 口大小GLfloat m_height;場景所浦位圖文件路徑chai g_filepathl255=(ndata/detail.BMPH); 地面紋理圖片場景寸象定義CScene scene(g_filepath);const float PI=3.1415926;場景光照效果設置在函數Light完成,實現形式為:注

17、:以下代碼寫在文件main.cpp中void Light(void)(GLfloat ambientLight=(0.3f,0.3f,0.3f,1.0f);GLfloat diffiiseLight=1 .Of, 1 .Of, 1 .Of, 1 .Of);GLfloat specular=(1.0f51 .Of, 1 .Of, 1 .Of;GLfloat liglitPos=1.0f51 .Of, 1 .Of,O.Of;/創建光源glLightfV(GL_LIGHT 1,GL_AMBIENT,ambientLight); 設置光為環境光。glLightfV(GL_LIGHTl ,GL_DIFF

18、USE0fftiseLight); 設置漫射光 glLightfV(GL_LIGHTl ,GL_POSmON,lightPos); 設置光源位置 選擇光照感 一GLfloat liiiodel_ambient = 0.4, 0.4, 0.4, 1.0 );GLfloat local_view = ( 0.0 );glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);glLightModelfv(GL_LIGHT_MODEL_LOCAL_TEWER,local_view);glEnable(GL_LIGHTING);glEnable(GL_L

19、IGHTl);glEnable(GL_COLOR_MATERIAL);/Z激活光照的情況卜用glColor函數給物 體上色以上光照設置函數和場景對象scene的初始化通過以下函數來調用:void InitQglClearColor(0.2, 0.2,0.2,1.0); 背景顏色 glShadeModel(GL_SMOOTH);glEnable(GL_DEPTH_TEST); 啟動深度測試glD epthFunc(GL_LE SS);啟動裁剪LightO;場景燈光scene.Init();場景初始化8.3.4鍵盤交互實現程序中UP、DOWN、LEFT和RIGHT鍵的回調函數實現形式如下: 注:以

20、下代碼寫在文件main.cpp中 void Contiol(GLiiit specialKeyGLmt xMouse.GLint yMouse) ( switch(specialKey) ( case GLUT_KEY_LEFT:/leftscene.rad=float(scene.PI*scene.angle/180.0); scene.angle1; scene.Look0=float(scene.Eye0-rl000*cos(scene.rad);實現轉向 scene.Look2=float(scene.Eye2-rl000*siii(scene.rad); break; case GL

21、UT_KEY_RIGHT:Z/riglitscene.rad=float(scene.PI*scene.angle/180.0); scene.angle+=l; scene.Look0=float(scene.Eye0-rl000*cos(scene.rad); scene.Look2=float(scene.Eye2-rl000*siii(scene.rad); break; case GLUT_KEY_DOWN:/downscene.rad=float(scene.PI*scene.angle/180.0); scene.Eye 2-=(float)sin(scene.rad)*l .0

22、;實現向后運動scene.EyeO(float)cos(scene.rad)* 1.0; if(scene.EyeOscene Width|scene.EyeOsceneLengtli |i scene.Eye2scene Width|scene.EyeOsceneLength|scene.Eye2鍵scene.motor.theta-=5; /云梯支架向右旋轉 break;case 8:scene.motor.phi+=5; 云梯支架俯仰旋轉 if(scene.motor.phi0) scene.motor.phi=0; break;case 2:scene.motor.phi-=5;if(

23、scene.motor.phi-90) scene.motor.phi=-90; break;case a1:glutFullScreen(); 全屏現實 break;case Y: glutPositionWiiidow( 100,100);glutReshapeWmdow(screenWidth, screenHeiglit);break;case 27:按 ESC 鍵exit(O); /退出系統break;default:break;上面函數中除實現交互功能外,還增加了按鍵a, r和ESC的響應過程,按a和r鍵分 別實現全屏顯示和恢復窗I大小,按ESC鍵來退出系統。8.3.5多視口的實現

24、場景中通過設置兩個攝像機(即設置兩個gluLookAt函數)來實現窗II多視II效果, 其中一個主視口的大小與窗I大小一致,而子視1位于主窗佐下角,大小是主視門的四分 之一,并都采用透視投影方式,其代碼實現如下:注:以下代碼寫在文件main.cpp中void RenderScene(void)(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadldentityO;fbr(int i=0;i2;i+)(lf(i=l)/ 子視口glEnable(GL_SCISSOR_TEST);glScissor(0,O,m_width/4 1 ,m

25、_height/4 1);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glDisable(GL_SCISSOR_TEST);grviewport(0Qm_width,4.1 ,m_height/4 1);glMatnxMode(GL_PROJECTION);glLoadldentityO;gluPerspective(45 .Of,(GLfloat)m_width/(GLfloat)m_heightOf, 1000.Of);glMatnxMode(GL_MODELTEW);glLoadldentityO;gluLookAt(0,scene.Eyel,0,/攝像機固定在場景中央,會跟蹤消防車 scene.EyeO,scene.Eyel ,scene.Eye2,0.0,1.000);scene.DrawScene();else/主視口grviewport(0,0,(GLsizei)m_width,(GLsizei)m_height);glMatnxMode(GL_PROJECTION);glLoadldentityO;ghiPei*spective(45.0?(GLfloat)m_width/(GLfloat)m_height? 1.0,1000.0); gl

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論