天天看點

用C++實作跨平台遊戲開發之Irrlicht引擎

Irrlicht引擎是一個用C++書寫的高性能實時的3D引擎,可以應用于C++程式或

者.NET語言中。通過使用Direct3D(Windows平台),OpenGL

1.2或它自己的軟體着色程式,可以實作該引擎的完全跨平台。盡管是開源的,該Irrlicht庫提供了可以在商業級的3D引擎上具有的藝術特性,例如動

态的陰影,粒子系統,角色動畫,室内和室外技術以及碰撞檢測等(見圖1)。

圖1.Irrlicht 3D引擎

  Irrlicht是一個德國神話故事中的一種動物的名字,它能夠發光和飛翔,可以在大部分的沼澤地附近發現它。單詞"Irrlicht"是兩個德國單詞("irr"意思是瘋狂的;而"Licht"意思是光)的組合。在英語中,它被譯為"鬼火"。

 

 Irrlicht十分幸運地為一個巨大的活躍的開發團隊以大量的工程所支援。然而,因為Irrlicht主要由遊戲名家Nikolaus

Gebhardt所設計,是以該遊戲在設計上十分連貫。你可以在網上到處發現有Irrlicht的增強程式,如可選用的地形生成器,入口生成器,輸出器,

world層生成器,相關教程和編輯器等。而且,它獨立地建立了到Java,Perl,Ruby,BASIC,Python,LUA甚至更多種語言的綁定。而最為重要的是,它是完全自由的。

  <b>二、 Irrlicht特性</b>

  在深入分析API之前,請讓我更具體地介紹一下Irrlicht提供給了3D遊戲開發者哪些功能:

  ·一個可以運作于Linux以及Windows 98,ME,NT,2000和XP(MacOS在計劃之中)等作業系統之上的引擎

  ·針對Direct3D 8生成器或Direct3D 9生成器(可選)提供了Anti-aliasing支援

  ·可換膚的GUI環境(包括一個很酷的具有金屬質地的帶陰影的皮膚),給一些老式的對話框加上漂亮的外觀

  ·場景管理系統,它允許無縫的室内/室外過渡

  ·角色動畫系統,帶有骨骼和變形目标動畫功能

  ·一個特殊的效果系統,包括粒子效果(雨,煙,火,雪,等等),告示闆,燈光貼圖,環境,地圖,模闆緩沖區陰影,霧,紋理動畫,視差貼圖,凹凸貼圖,還有更多

  ·内建的材質支援,包括支援Pixel and Vertex Shaders版本1.1到3.0,ARB Fragment and Vertex程式以及HLSL(GLSL正在計劃中)

  ·.NET語言綁定,這使得引擎可用于所有的.NET語言例如C#,Visual Basic.NET以及Delphi.NET

  ·一内建的平台獨立的軟體生成器,特性有:z-緩沖,Gouraud陰影,alpha混合和透明性,還有快速的2D繪圖(見圖2)

  ·你久已期待的2D繪圖功能,例如alpha混合,基于關鍵色的位圖複制,字型繪制,以及混合3D與2D圖形

 ·能直接導入常見的模組化檔案格式:Maya,3DStudio Max,COLLADA,DeleD,Milkshape,Quake 3

levels,Quake2 models,DirectX,Pulsar,My3DTools,FSRad以及Cartography Shop

  ·能直接從BMP,PNG,Photoshop,JPEG,Targa和PCX導入紋理

  ·快速而易用的碰撞檢測與響應

  ·為快速的3D運算和容器模闆庫進行了優化處理

  ·直接讀取檔案(可能是壓縮的,如.zip檔案)

  ·內建了快速的XML分析器

  ·為實作容易的本地化開發提供Unicode支援

圖2:基于Irrlicht的遊戲Yet Another Space Shooter(YASS),這裡顯示的是一個靜态遊戲幀中的令人吃驚的着色效果

  <b>三、 在Irrlicht中的特殊效果</b>

  在本文的例子中,我将向你展示怎樣使用模闆緩沖區影子技術,還有粒子系統,告示闆,動态光以及水表面場景結點等技術。參見圖3。

圖3.結合動态的光和水進行的場景着色

 Irrlicht引擎自動地檢查是否你的硬體支援模闆緩沖;而如果不支援,則不啟動陰影。在這個示範程式中,在方法createDevice()中的

’shadows’标志被置位,以産生從一個動畫角色投下的動态影子。如果這個執行個體程式在你的PC上運作太慢,可以把這個标志設定為false或者幹脆再

買一塊更好些的圖形加速卡。

  為能夠使用Irrlicht.DLL檔案,你需要連結到Irrlicht.lib庫檔案。你可以在工程設

置對話框中設定這個選項;但是為了容易實作,你可以使用一個pragma預編譯注釋指令。方法createDevice()負責執行個體化根對象-它使用引擎

完成一切事情。參數如下:

  ·deviceType:裝置類型。目前你可選取Null裝置以及軟裝置,如DirectX8,DirectX9或OpenGL。

  ·windowSize:要建立的視窗的大小或全螢幕模式。這個例子中使用512x384。

  ·bits:每像素位數(當在全螢幕情況時)。僅允許值為16或者32。

  ·fullscreen:指定是否你想使裝置運作于全螢幕方式。

  ·stencilbuffer:指定是否你想使用模闆緩沖區以用于繪制陰影。

  ·vsync:指定是否你想啟動vsync(僅在全螢幕情況),可選。

  ·eventReceiver:一個接收事件的對象,可選。

  為适合于本執行個體環境,你将裝載一個3D Studio Max檔案(一幢房子)。該房子看起來并沒有什麼特别的,但是Irrlicht引擎能為你建立一個相當酷的紋理貼圖。隻需使用造型操縱器并為之建立一個planar紋理貼圖即可:

#include &lt;irrlicht.h&gt;

#include &lt;iostream&gt;

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int main()

{

 //讓我們假定使用者在本例中使用OpenGL

 //當然,也可以指定DirectX 8, 9, 等等.

 video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;

 //建立裝置,如果建立失敗立即退出。

 IrrlichtDevice *device = createDevice(driverType,

 core::dimension2d(640, 480), 16, false, true);

 if (device == 0)

  return 1;

 video::IVideoDriver* driver = device-&gt;getVideoDriver();

 scene::ISceneManager* smgr = device-&gt;getSceneManager();

  我對從這個導入檔案産生的發射光線顔色的效果并不滿意。下列代碼顯示怎樣實作這些步驟:

scene::IAnimatedMesh* mesh = smgr-&gt;getMesh("room.3ds");

smgr-&gt;getMeshManipulator()-&gt;makePlanarTextureMapping(

mesh-&gt;getMesh(0), 0.008f);

scene::ISceneNode* node = 0;

node = smgr-&gt;addAnimatedMeshSceneNode(mesh);

node-&gt;setMaterialTexture(0, driver-&gt;getTexture("wall.jpg"));

node-&gt;getMaterial(0).EmissiveColor.set(0,0,0,0);

 <b> 四、 水動畫</b>

  你将添加的第一個特殊的效果是水動畫。為此,WaterSurfaceSceneNode導入一個造型檔案并使之象水表面一樣地波動。如果你讓這個場景結點使用一種相當好的材質如MT_REFLECTION_2_LAYER,那麼它看起來相當酷:

mesh = smgr-&gt;addHillPlaneMesh("myHill",

core::dimension2d(20,20),

core::dimension2d(40,40), 0, 0,

core::dimension2d(0,0),

core::dimension2d(10,10));

node = smgr-&gt;addWaterSurfaceSceneNode(mesh-&gt;getMesh(0),3,300,30);

node-&gt;setPosition(core::vector3df(0,7,0));

node-&gt;setMaterialTexture(0,driver-&gt;getTexture("water.jpg"));

node-&gt;setMaterialTexture(1,driver-&gt;getTexture("stones.jpg"));

node-&gt;setMaterialType(video::EMT_REFLECTION_2_LAYER);

  作為輸入造型,你可以建立一個陡峭的平面造型,但是你也可以為此使用任何其它的造型。你甚至能重用room.3ds輸入檔案(它看上去确實很奇怪)。該執行個體還用一個普通的石頭紋理模型來繪制所有另外的表面。

  <b>五、透明的告示闆和燈光</b>

  第二個特殊的效果是很基本的但是非常有用:一個透明的告示闆,伴之有一個動态的燈光。為産生這種效果,你隻需要産生一個燈光場景結點,并讓它四處飛行;而且,為了讓它看起來更酷一些,可以把一個告示闆場景結點依附到它上面:

//建立燈光

node = smgr-&gt;addLightSceneNode(0, core::vector3df(0,0,0),

video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 600.0f);

scene::ISceneNodeAnimator* anim = 0;

anim = smgr-&gt;createFlyCircleAnimator(core::vector3df(0,150,0),250.0f);

node-&gt;addAnimator(anim);

anim-&gt;drop();

// 把告示闆依附到燈光

node = smgr-&gt;addBillboardSceneNode(node, core::dimension2d(50, 50));

node-&gt;setMaterialFlag(video::EMF_LIGHTING, false);

node-&gt;setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);

node-&gt;setMaterialTexture(0,driver-&gt;getTexture("particlewhite.bmp"));

  <b>六、 粒子系統</b>

  下面介紹的這個特别效果更有趣:一個粒子系統。在Irrlicht引擎中,粒子系統既是元件化的,

也是可擴充的,但是仍然易于使用。你隻需要簡單地把粒子發射器放到一個粒子系統場景結點,這樣以來粒子看上去沒有産生源。這些發射器可以據需要進行靈活配

置,并經常帶有許多參數,如粒子方向,粒子數量,以及粒子顔色等。

  當然,發射器類型有差別(例如,一個點發射器能夠使粒子從一個

固定的點上發出粒子)。如果該引擎提供的粒子發射器還不能滿足你的要求,你可以容易地建立你自己的發射器。這隻需簡單地從

IParticleEmitter接口派生一個新類并使用setEmitter()方法把它依附到粒子系統上去即可。

  下一個執行個體将建立一個盒子粒子發射器。你可能已經猜出,它從一個跳躍的盒中随機生成粒子。由參數來定義盒子,粒子的方向,每秒産生粒子的最小和最大數目,顔色以及粒子的最小和最大生命周期。

 一個完全由發射器組成的粒子系統将是令人生厭的,因為缺乏真實感。是以,Irrlicht支援粒子影響器-它負責在粒子到處飛揚時予以修整。一旦添加到

粒子系統上,它們就能模仿另外的更真實的效果,象重力或風。在本例中的粒子影響器隻是簡單地修改粒子的顔色來産生一種淡出效果。

  可能

你已經猜出,粒子影響器是通過派生IParticleAffector接口實作的,然後通過使用addAffector()方法把它添加到粒子系統上去。

在你為該粒子系統設定了一種好看的材質後,你就有了一個看上去相當酷的野外宿營火的效果。通過調整材質,紋理,粒子發射器,還有影響器參數,你能容易地創

建煙霧,下雨,爆炸,下雪等效果:

scene::IParticleSystemSceneNode* ps = 0;

ps = smgr-&gt;addParticleSystemSceneNode(false);

ps-&gt;setPosition(core::vector3df(-70,60,40));

ps-&gt;setScale(core::vector3df(2,2,2));

ps-&gt;setParticleSize(core::dimension2d(20.0f, 10.0f));

scene::IParticleEmitter* em = ps-&gt;createBoxEmitter(

core::aabbox3d(-7,0,-7,7,1,7),

core::vector3df(0.0f,0.03f,0.0f),

80,100,

video::SColor(0,255,255,255), video::SColor(0,255,255,255),

800,2000);

ps-&gt;setEmitter(em);

em-&gt;drop();

scene::IParticleAffector* paf =ps-&gt;createFadeOutParticleAffector();

ps-&gt;addAffector(paf);

paf-&gt;drop();

ps-&gt;setMaterialFlag(video::EMF_LIGHTING, false);

ps-&gt;setMaterialTexture(0, driver-&gt;getTexture,"particle.bmp"));

ps-&gt;setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);

  <b>七、 影子投射</b>

 最後但也不容忽視一個問題是,你需要為一個動畫角色産生一個動态的影子。為此,你裝載一個Quake2.md2模型檔案并把它放到你的world上去。

為了建立影子,你隻需要調用方法addShadowVolumeSceneNode()。你可能通過調用ISceneManager::

setShadowColor()來控制影子的顔色;注意,這僅是全局可調整的,并影響所有的影子。好,下面就是你的産生動态影子效果的代碼:

mesh = smgr-&gt;getMesh("../../media/faerie.md2");

scene::IAnimatedMeshSceneNode* anode = 0;

anode = smgr-&gt;addAnimatedMeshSceneNode(mesh);

anode-&gt;setPosition(core::vector3df(-50,45,-60));

anode-&gt;setMD2Animation(scene::EMAT_STAND);

anode-&gt;setMaterialTexture(0, driver-&gt;getTexture("../../media/Faerie5.BMP"));

anode-&gt;addShadowVolumeSceneNode();

smgr-&gt;setShadowColor(video::SColor(220,0,0,0));

  <b>八、 遊戲循環</b>

 最後,你能進入由device-&gt;run()方法控制的遊戲循環。該循環将不斷運作,直到通過擷取一個關閉視窗事件(例如在Windows操作系

統下的ALT-F4擊鍵)來退出裝置。你必須在一個beginScene()和endScene()指令對之間繪制每樣東西。beginScene()用

指定的一種顔色清屏,如果需要的話,可以同時清除深度緩沖區。然後你就可以讓場景管理器和GUI環境來繪制它們的内容。随着調用endScene(),每

一樣東西都被繪制到螢幕上去。在本例中,你還可以動态地在标題欄上顯示幀每秒(FPS)數,這對于嚴肅的遊戲開發者是十分重要的事情:

scene::ICameraSceneNode* camera = smgr-&gt;addCameraSceneNodeFPS();

camera-&gt;setPosition(core::vector3df(-50,50,-150));

int lastFPS = -1;

while(device-&gt;run())

 driver-&gt;beginScene(true, true, 0);

 smgr-&gt;drawAll();

 driver-&gt;endScene();

 int fps = driver-&gt;getFPS();

 if (lastFPS != fps)

 {

  core::stringw str = L"Campfire FX example [";

  str += driver-&gt;getName();

  str += "] FPS:";

  str += fps;

  device-&gt;setWindowCaption(str.c_str());

  lastFPS = fps;

 }

}

device-&gt;drop();

 結束循環後,你必須删除先前用createDevice()方法建立的Irrlicht裝置。通過使用Irrlicht引擎,你應該删除所有你用以

’create’開頭的方法或函數建立的所有對象。你可以通過簡單地調用device-&gt;drop()來删除該裝置對象。

  <b>九、你可能喜歡的Irrlicht插件</b>

  正如在前面所介紹的,Irrlicht有一群勤奮的獨立開發人員并為之産生了大量的插件,也用之開發了相當多的遊戲。這些開發者中提出的許多的改進被再次內建到Irrlicht的随後的發行版本中。下面我列舉其中的幾個例子,我想這會吸引許多頗有前程的開發者感興趣:

  ·OCTTools,是一套用于Irrlicht的工具,由Murphy McCauley所建立,用于操作OCT檔案相關的:輸出器,加載器,甚至更多。

  ·ICE(Irrlicht通用引擎)是一個開發架構,它提供了一個工程的輪廓實作,進而加快了新工程的開發。

  ·MIM,由Murphy McCauley所建立,是一個非常有用的基于XML的檔案格式,可用于Irrlicht的加載器,轉換器及其各種工具。

  ·My3D是一個開發工具包,它能夠使你把來自于各種3D包(3DStudio MAX,Giles,等等)中的燈光貼圖場景直接輸出到Irrlicht中。

  ·Dusty引擎允許程式員建立"任務"-這些"任務"可以完成程式員想做的任何事情。之後,這些任務被添加到一棵普通的任務樹上去,而每個任務可以有它們希望數目的孩子任務。任務"組"允許遊戲設計者在一棵完整的樹上執行普通的操作,例如暫停,繼續或破壞等。

  ·Irrlicht RPG(Erring Light)是一個3D 繞行走遊戲引擎,最初是針對RPG類遊戲開發的。

  ·2D 圖像和精靈類組成了一個很有用的庫,它擴充了Irrlicht的2D能力。

  ·Zenprogramming站點,提供第一個針對Irrlicht的非正式的外部地形生成器,此處也提供很多相關的教程。

繼續閱讀