用C++实现跨平台游戏引擎开发
游戲開發系列
用C++實現跨平臺游戲引擎開發
你是否夢想寫一部格斗游戲但卻無從著手呢?是否你只因游戲開發好玩而對之感興趣?本文我們將分析一個通用的跨平臺游戲引擎,每個游戲開發新手都可以自由地使用它。
1. 3D游戲引擎的簡短歷史
在游戲開發中,從一開始就確定正確的開發平臺是很重要的。是否你的游戲支持Windows,Linux和OS X?是否你的游戲開發只使用OpenGL就足夠了?OpenGL是十九世紀九十年代初期設計的,起初只運行于價值約$25,000的Unix CAD工作站上,后來移植到Windows和其它一些低端平臺上。與此同時,隨著游戲工業的發展,圖形加速器價格從$2,000劇跌到你今天看到的價值約 $150的大眾市場價格。
確實,許多人都會援引在1996年用OpenGL開發成功的革命性的游戲Quake,作為以上急速發展 現象的直接的原因。然而,成功的Quake級的游戲開發標準要求更多:世界級音頻支持,網絡連接,用戶輸入設備支持,以及實時的管理能力等。既需要實現跨 平臺支持又能使游戲效果激動人心,要實現這樣的解決方案最好建立一個體面的游戲開發站臺。
2. 用于C++,Java和其它開發語言的簡單DirectMedia層
對,歷史就是這樣有趣,但并不是每一部游戲都要做成Quake的克隆品。一直被業界許多人吹捧有著許多優點的選擇是簡單DirectMedia層(SDML)。這是一套跨平臺的多媒體庫, 它提供對于音頻,鍵盤,鼠標,游戲桿,OpenGL和2D視頻幀緩沖的低級存取。SDML支持幾乎我能想像出的每一個平臺,包括Linux, Windows,所有的MacOS變異物,WinCE,Dreamcast還有另外一些操作系統。它被廣泛應用于開發MPEG播放器,硬件仿真器,和許多 流行的游戲,包括獲獎的運行于Linux平臺的Civilization:Call to Power。
SDML用C寫成,但生來就與C++一起工作,已經綁定到了另外許多語言,包括Ada,Eiffel,Java,Lua,ML,Perl,PHP,Pike,Python和Ruby。SDML的應用環境簡直就沒有什么限制,而且它碰巧是我最喜愛的開源飛行模擬器GL-117(見圖1)的開發引擎。事實上,513游戲的當前開發已經基于SDML引擎而且被注冊到了SDML的主頁。
圖1.GL-117中的一個視圖 |
3. 通道視覺效果演示程序
研究游戲引擎的最好方法是看一些示例程序代碼。簡單地看一下圖2中用SDML實現的2D通道類型演示圖,你就能發現你僅用幾行代碼所能完成的工作。你可 以使用該實例作為一個保護屏程序,音樂可視化動畫效果,等等。篇幅所限,我已經整理了實際的繪制代碼。請跟隨我的注釋分析下面對SDML的工作原理的描 述:
| #include "Tunnel.h" // SDL 相關變量定義 SDL_Surface *screen,*bBuffer,*Image; SDL_Rect rScreen,rBuffer; int main (int argc, char **argv) { int flag = SDL_SWSURFACE;// 請求一個軟件表面. //軟件表面處于系統內存中, // 一般不如硬件表面速度快 #ifdef WIN32 int fullscreen = MessageBox(NULL, "Show Full Screen (y/n):","Screen Setting", MB_YESNO); if (fullscreen==IDYES) { flag |= SDL_FULLSCREEN; // 如果用戶需要,接管整個屏幕 } #endif Tunnel_Timer(); // 讀取起始的系統時鐘值 SDL_Init( SDL_INIT_VIDEO ); // 初始化視頻子系統 //把屏幕設置到 320x240,32位顏色 screen = SDL_SetVideoMode( 320, 240, 32, flag); // 如果可用的話,為屏幕表面請求硬件緩沖 bBuffer = SDL_CreateRGBSurface( SDL_HWSURFACE, screen->w,screen->h,screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); // 這是種子圖像,一旦開始它就會盤旋起來 Image = SDL_LoadBMP( "tunnel_map.bmp" ); Image = SDL_ConvertSurface(Image, screen->format, SDL_HWSURFACE); rBuffer.x = 0; rBuffer.y = 0; rBuffer.w = bBuffer->w; rBuffer.h = bBuffer->h; // 忽視大多數事件, 包括 鼠標動作, 并取消光標 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); SDL_ShowCursor( SDL_DISABLE ); Tunnel.Set( 320, 240 ); // 通道將填充整個的緩沖區 Tunnel.Precalc( 16 ); //內部的圓圈直徑 while (SDL_PollEvent(NULL)==0) { float fTime = Tunnel_GetTime(); //在修改前,必須鎖定表面,特別當緩沖區處于圖形硬件內存中時 SDL_LockSurface(bBuffer); SDL_LockSurface(Image); Tunnel.Draw(bBuffer, Image, 180*sin(fTime), fTime*100); SDL_UnlockSurface(bBuffer); // 在更新以后你可以開鎖 SDL_UnlockSurface(Image); // 把緩沖區中的數據輸出到屏幕繪圖區域并強迫進行重畫 SDL_BlitSurface( bBuffer, NULL, screen, &rBuffer ); SDL_UpdateRect( screen, 0, 0, 0, 0 ); } Tunnel.Free(); } |
圖 2. 演示旋轉和扭曲的2D通道 |
4. 對另外一些游戲引擎的探索
讓我們看一下另外一些開源的游戲引擎。
a) ALLEGRO(Allegro低級游戲開發例程)
Allegro是一個開源的可移植的庫,主要針對視頻游戲和多媒體編程。Allegro由Shawn Hargreaves(近來稱為Climax)創建,現在成長為一個能夠跨越許多操作系統如Linux,Windows,MacOS,MS-DOS和許多 另外的流行平臺等的游戲系統。
除了具有一個高級的2D圖形庫,它能容易地存取鼠標,鍵盤,游戲桿和高精度定時器中斷。Allegro 并沒有包裝或替換OpenGL,但是通過參觀他們廣闊的開發站點(http://www.allegro.cc/),你能學習怎樣把OpenGL集成到 Allegro游戲程序中。
大約有700種不同的游戲工程,與Allegro一起發行,其中最為杰出的兩類是街機游戲和謎題游戲。我特別地喜歡經典的街機游戲Zaxxon(見圖3)的重制品。
圖3.酷斃的Zaxxon的重制品 |
b) Irrlicht:點燃快速實時的3D引擎
這個Irrlicht 引擎是一個跨平臺,高性能實時引擎,用C++寫成。你可以選擇Direct3D,OpenGL 或基于軟件的著色技術。高端特點包括動態陰影,粒子系統,人物動畫,進門和出門技術和碰撞檢測(見圖4)。Irrlicht支持Windows和 Linux并提供到語言Java,Perl,Ruby等的綁定。業界先驅Nikolaus Gebhardt在他的朋友的少部分幫助下完成的這個引擎工。
圖4.在Irrlicht中的一個十分逼真的場景 |
c) ClanLib:為多玩家游戲設計的引擎
ClanLib提供了一個平臺獨立的接口來書寫游戲-它們有一個共同的到低級庫如DirectX和OpenGL的接口。借助于ClanLib,你只需編 寫少量代碼即可在Windows,Linux和OSX系統上開發游戲程序。ClanLib包括一個廣泛的聲音庫,2D碰撞檢測,動畫,GUI框架和網絡庫。圖5顯示了游戲XenoHammer中的一個場景。
圖5.XenoHammer屏幕快照 |
發表于 @ 2006年02月22日 12:05 PM | 評論 (2)
用C++實現跨平臺游戲開發之Allegro引擎
要:本文重點討論開源游戲開發庫Allegro(Allegro低級游戲例程),同時涉及到一些深度技術并提供了一個簡單的示例程序,幫你進一步確定它是否是適合你的開發平臺。
border="0" marginwidth="0" marginheight="0" src="http://219.239.88.50/adsunion/get/;pl=pl-20-pip-software;tp=if;sk=0;ck=0;/?" noresize="65535" frameborder="0" height="1" scrolling="no" width="1"> 一、 一個適于多環境的引擎
Allegro最開始被研發于八十年代后期古老的Atari ST平臺上,隨后被快速地移植到流行的DJGPP環境(一個在九十年代早期流行的32位的MS-DOS擴展程序)。此后,Allegro被移植到最為流行的Windows C++開發環境中,包括VS,MinGW,Cygwin和Borland C++。另外的支持它的平臺包括Linux,BeOS,QNX,Mac OSX以及幾乎任何其它帶有X11庫的Unix平臺上。
Allegro能著色到各種類型的位圖和硬件加速的環境中,例如DirectX,XWindows,SVGAlib,FreeBE/AF, CGDirectDisplay,QuickDraw,等等。Allegro并不想提供它自己的3D環境或模擬器,但是OpenGL可以被容易地集成,這 是通過使用AllegroGL庫-它提供了一個類似于GLUT的接口(包括擴展管理)-實現的。
二、 性能概要
在進一步使用API開發前,讓我們看一下Allegro提供的總體功能:
·具體到像素級的繪圖函數,包括平坦陰影,gouraud陰影,紋理貼圖,z緩沖的多邊形和圓繪制,填充,貝塞爾樣條曲線,圖案填充,精靈,blitting(位圖復制),位圖計算縮放和旋轉,半透明/光效果以及比例字體支持的文本輸出
·FLI/FLC(在計算機生成的動畫方面,這種格式比MPEG有更高的壓縮性能)動畫播放器
·播放后臺MIDI音樂,可達64種同時的聲音效果,并能錄制樣本波形和MIDI輸入(聲音平臺支持,包括WaveOut,DirectSound,OSS,ESD,CoreAudio和QuickTime,等等)
·容易地存取鼠標,鍵盤,游戲桿等設備,還支持高分辨率定時器中斷,包括一個DOS版本的垂直折回中斷模擬器
·讀/寫LZSS壓縮文件的例程
·數學函數,包括定點算術,表查找和3D矢量/矩陣/四元數操作
·GUI對話框管理器和文件選擇器
·內建地支持16位和UTF-8格式的Unicode字符
三、 使用引擎
使用Allegro進行開發,就象在許多其它游戲場合下一樣,游戲的總體結構都包括游戲開始前的初始化,游戲循環以及游戲完成后的清理。初始化意味著既 包含Allegro啟動代碼也包含在開始的位置實現基本地裝載或生成你的游戲級別。在創建你的初始化代碼時,啟動Allegro基本上沒有什么代價付出 (見圖1).
如果你需要很多屏幕相關的真實性能,建議你首先禮貌地用get_gfx_mode_list()函數查詢一下最大可用方式:
| #include <allegro.h> //必須放于系統頭文件的引用之后 set_color_depth(32); // 缺省情況下使用8位顏色 if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) { abort_on_error("Couldn’t set a 32 bit color resolution"); } |
set_gfx_mode()的最后兩個參數用于指定虛擬緩沖區的大小-我們的圖形屏幕存儲于其中。這可以使創建一個卷邊游戲-其中地形是連續移動的-變得容易。例如,你可能要使虛擬緩沖區,比方說,寬出20%以留出足夠的空間來平滑卷動新的精靈和地形。
四、 一個完整的Allegro實例
本教程將使用Kee-Yip Chan的SnookerClone演示程序,它是基于James Lohr的另一個具有相同名字的演示程序。圖1顯示了演示程序的基本屏幕快照。
圖1.Kee-Yip Chan的"SnookerClone"演示程序 |
這個工程向你展示了許多不同的Allegro技術,包括動畫,鍵盤輸入和鼠標輸入,碰撞和游戲物理知識(例如重力)。它利用了三個主要的元素:一個有8 個扶手的旋轉的車輪,一個用箭頭鍵來控制的大紅球,還有一些從頂部往下墜落的藍球。車輪以接觸方式推動紅球,而當紅球碰上藍球時,它們之間相互影響。
下列是完整的Allegro演示程序的代碼:
| 1 #include <allegro.h> 2 vector<Point> g_points; //aka球上點的列表 3 vector<Joint> g_joints; //物理對象列表,如車輪和緩沖器 4 kVec g_accControl; 6 int main(void) 7 { 8 allegro_init(); // 初始化allegro. 9 install_keyboard(); // 啟動鍵盤. 10 install_mouse(); // 啟動鼠標. 11 install_timer(); //過程show_mouse()所需要; 13 // 創建一個800x600的非全屏窗口. 14 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); 16 set_window_title("Kee-Yip Chan’s Snooker Clone"); 17 text_mode(-1); // 文本將被畫在透明的背景之上 19 BITMAP* buffer = create_bitmap(SCREEN_W, SCREEN_H); //創建一張位圖用于雙緩沖. 21 // 初始化數據. 22 create_joints(g_joints); //注冊車輪、地板和緩沖器的硬編碼的屏幕位置 25 // 創建頂點以組成aka球: 玩家所用球和三個藍球 26 // 的位置, 速度, 大小和質量. 27 g_points.push_back(Point(kVec(100, 300),kVec(0, 0),16, 10)); // 玩家. 28 g_points.push_back(Point(kVec(50, 40), kVec(0, 0),12, 5)); // 中等的球. 29 g_points.push_back(Point(kVec(80, 40), kVec(0, 0) 12, 5)); //中等的球. 30 g_points.push_back(Point(kVec(110, 40),kVec(0, 0),6, 1)); // 小球. 32 //主循環,在按ESC鍵后退出 33 while(!key[KEY_ESC]) { //檢查輸入. 34 if(key[KEY_UP]) 35 g_accControl.y = -0.07; //Jet pack.向上加速 36 if(key[KEY_LEFT]) 37 g_accControl.x = -0.07; //左走.向左加速 38 if(key[KEY_RIGHT]) 39 g_accControl.x = 0.07; //右走.向右加速 41 static bool leftMousePressed = false, rightMousePressed = false; 42 if(mouse_b & 1) { //鼠標左鍵按下 43 if(!leftMousePressed){ 44 leftMousePressed = true; // 創建一個新球. 45 g_points.push_back(Point(kVec(mouse_x, mouse_y),kVec(0, 0), 12, 5)); 46 } 47 } 48 if(!(mouse_b & 1)) 49 //保證不重復鼠標按鍵 50 //否則,就會出現許多的新球 51 leftMousePressed = false; 52 if(mouse_b & 2) { //鼠標右鍵按下 53 if(!rightMousePressed){ 54 rightMousePressed = true; // 創建一個新球 55 g_points.push_back(Point(kVec(mouse_x, mouse_y),kVec(0, 0), 6, 1)); 56 } 57 } 58 if(!(mouse_b & 2)) 59 //保證不重復鼠標按鍵 60 //否則,就會出現許多的新球. 61 rightMousePressed = false; 63 doPhysics(); 65 // 著色:如果我們能再次使用緩沖區,則清除它; //否則,舊圖像將滯留顯示 66 //用白色進行清除. 67 clear_to_color(buffer, makecol(255, 255, 255)); 68 for(unsigned i = 0; i < g_points.size(); i++) { //畫點. 69 //畫一個實心球 70 circlefill(buffer, //畫向緩沖區 71 g_points[i].position.x,g_points[i].position.y,// aka 球的中心點的位置 72 g_points[i].size, // 半徑. 73 (i == 0) ? makecol(255, 0, 0) : makecol(0, 0, 255)); //紅色如果是玩家;否則為藍色 75 // 畫一個輪廓球. 76 circle(buffer, //畫向緩沖區 77 g_points[i].position.x,g_points[i].position.y, // aka 球的中心點的位置. 78 g_points[i].size, // 半徑. 79 makecol(0, 0, 0)); //紅色如果是玩家;否則為藍色. 81 } 83 // 畫接合點 84 for (unsigned i = 0; i < g_joints.size(); i++) 85 line(buffer, //畫向緩沖區 86 g_joints[i].p1.x, g_joints[i].p1.y, // 點 1. 87 g_joints[i].p2.x, g_joints[i].p2.y, // 點 2. 88 makecol(0, 0, 0)); // 黑顏色. 89 ); 91 // 打印指令. 92 textout(buffer, font, "Left Mouse Button - new big ball Right Mouse Button - new small ball", 93 125, 1, makecol(0, 0, 0)); 95 textout(buffer, font, "Arrow Keys - move red ball", 96 300, 592, makecol(0, 0, 0)); 98 show_mouse(buffer); // 畫鼠標光標. 100 draw_sprite(screen, buffer, 0, 0);// 把緩沖區中的數據畫向屏幕. 101 } // while循環結束 103 return 0; 105 }END_OF_MAIN(); |
33-101行包括了典型的游戲編程循環模式。游戲繼續進行直到玩家按下ESC鍵退出為止。34-39行支持同時進行的鍵盤輸入,因為你可以按下向上和向左箭頭鍵來獲取粗略的斜向運動。
在41-61行,鼠標動作被捕獲到全局變量mouse_b(用于按鈕),mouse_x和mouse_y。如果你一直在使用一滾輪鼠標,你還可以使用變量mouse_z。我們對反向彈跳邏輯進行了一點硬編碼以確保每次鼠標按下事件只有一個球下落。
第63行調用doPhysics(),其目的是旋轉車輪的線段,更新球位置,檢測球碰撞和適當地改變它們的方向矢量。這個模塊(350行的數學代碼)有點深入了些,但它確實是一個一流的實現,值得你深入研究。
余下的代碼,65-101行,開始著色,在典型的示例程序中這屬于常規實現部分。這里的著色用典型的雙緩沖區技術,下一次屏幕變化被計算出來并進行脫屏 繪制并在最的一毫秒進行緩沖交換(第100行)。這確保了視覺的連續性又減少了煩人的閃爍-對象看上去是隨機地繪制的。在著色代碼部分,對line()和 circlefill()的調用是相當直接的:circlefill()以x,y,半徑和填充顏色作為參數。
textout_ex ()函數的功能稍強于textout()(示于92-96行),允許你指定前景和背景顏色。Allegro提供例程以直接從GRX格式.fnt文件, 8x8或8x16 BIOS格式.fnt文件,位圖圖象以及數據文件格式中裝入字體。作為選擇,你能導入一種大范圍的Unicode字體,這可以通過寫一個.txt腳本-它 為每一范圍的字符指定相應的不同的源文件-來實現。如果你想要支持TrueType,那么你需要AllegroTTF或相同功能的插件。
最后,在第100行的draw_sprite()實現一個覆蓋性復制新生成的位圖到第14行創建的屏幕對象上。覆蓋性復制意指只有非透明的顏色像素被復制。在本例中,我確信它已被退化成一個"blit"(塊復制)轉儲。
五、 Allegro的音頻
這個snooker演示程序只涉及到了一些最基本的圖形和I/O函數,但是并沒有用到Allegro的音頻開發包。該包中的MIDI混頻,音響效果和錄 音API,其效果達到或超過幾乎每一個我所見過的專業的聲音庫。Allegro音頻應用軟件大量存在,包括WinCab-一個MP3和OGG Vorbis音樂唱片機,還有LouTronic Rhythm Box-一個鼓聲生成合成器,它具有可全面融合到一起的snare鼓,低音鼓和hi hat的效果。下面我們簡單地回顧Allegro音頻API的一小部分。
每一個使用音頻的程序都應該調用reserve_voices()來指定數字和MIDI聲音驅動程序分別使用的聲音的數目。接下去,你能控制這些音頻軌道的混合.
你可以非常容易地象下面這樣插入一個音軌:
| MIDI *midFile = load_midi("myfile.mid’); play_midi(midFile, TRUE);//連續循環 |
對于更復雜的需要,你可以安裝三個鉤子函數之一,它們可以使你攔截MIDI玩家事件。如果被設置為非NULL,這些例程將在每次MIDI消息,元事件和系統獨占的數據塊中被分別調用。
Allegro的數字音頻系統被設計為從最基本的配置到可高度擴展的。你能容易安裝讀取器和寫入器來處理新的或者不同的音頻文件類型, 例如:
| register_sample_file_type("mp3",load_mp3,NULL);//安裝MP3讀取器 |
當正播放數字音頻時,你可以隨時編輯它。下列代碼改變將在播放一個樣本參數時改變該樣本(用于操作循環播放的聲音):
| void adjust_sample(const SAMPLE *spl, int vol, int pan, int freq, int loop); |
你能改變音量,平移音頻數據并清除循環標志,在下次執行到循環末尾時,這將停止該樣本。如果在播放相同樣本的好幾個副本,這會調整它遇到的第一個副本。如果該樣本沒有播放,對它沒有任何影響。
發表于 @ 2006年02月22日 12:03 PM | 評論 (0)
用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甚至更多種語言的綁 定。而最為重要的是,它是完全自由的。
二、 Irrlicht特性
在深入分析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),這里顯示的是一個靜態游戲幀中的令人吃驚的著色效果 |
三、 在Irrlicht中的特殊效果
在本文的例子中,我將向你展示怎樣使用模板緩沖區影子技術,還有粒子系統,告示板,動態光以及水表面場景結點等技術。參見圖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 <irrlicht.h> #include <iostream> 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->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); |
我對從這個導入文件產生的發射光線顏色的效果并不滿意。下列代碼顯示怎樣實現這些步驟:
| scene::IAnimatedMesh* mesh = smgr->getMesh("room.3ds"); smgr->getMeshManipulator()->makePlanarTextureMapping( mesh->getMesh(0), 0.008f); scene::ISceneNode* node = 0; node = smgr->addAnimatedMeshSceneNode(mesh); node->setMaterialTexture(0, driver->getTexture("wall.jpg")); node->getMaterial(0).EmissiveColor.set(0,0,0,0); |
四、 水動畫
你將添加的第一個特殊的效果是水動畫。為此,WaterSurfaceSceneNode導入一個造型文件并使之象水表面一樣地波動。如果你讓這個場景結點使用一種相當好的材質如MT_REFLECTION_2_LAYER,那么它看起來相當酷:
| mesh = smgr->addHillPlaneMesh("myHill", core::dimension2d(20,20), core::dimension2d(40,40), 0, 0, core::dimension2d(0,0), core::dimension2d(10,10)); node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0),3,300,30); node->setPosition(core::vector3df(0,7,0)); node->setMaterialTexture(0,driver->getTexture("water.jpg")); node->setMaterialTexture(1,driver->getTexture("stones.jpg")); node->setMaterialType(video::EMT_REFLECTION_2_LAYER); |
作為輸入造型,你可以創建一個陡峭的平面造型,但是你也可以為此使用任何其它的造型。你甚至能重用room.3ds輸入文件(它看上去確實很奇怪)。該實例還用一個普通的石頭紋理模型來繪制所有另外的表面。
五、透明的告示板和燈光
第二個特殊的效果是很基本的但是非常有用:一個透明的告示板,伴之有一個動態的燈光。為產生這種效果,你只需要產生一個燈光場景結點,并讓它四處飛行;而且,為了讓它看起來更酷一些,可以把一個告示板場景結點依附到它上面:
| //創建燈光 node = smgr->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->createFlyCircleAnimator(core::vector3df(0,150,0),250.0f); node->addAnimator(anim); anim->drop(); // 把告示板依附到燈光 node = smgr->addBillboardSceneNode(node, core::dimension2d(50, 50)); node->setMaterialFlag(video::EMF_LIGHTING, false); node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); node->setMaterialTexture(0,driver->getTexture("particlewhite.bmp")); |
六、 粒子系統
下面介紹的這個特別效果更有趣:一個粒子系統。在Irrlicht引擎中,粒子系統既是組件化的,也是可擴展的,但是仍然易于使用。你只需要簡單地把粒 子發射器放到一個粒子系統場景結點,這樣以來粒子看上去沒有產生源。這些發射器可以據需要進行靈活配置,并經常帶有許多參數,如粒子方向,粒子數量,以及 粒子顏色等。
當然,發射器類型有區別(例如,一個點發射器能夠使粒子從一個固定的點上發出粒子)。如果該引擎提供的粒子發射器還 不能滿足你的要求,你可以容易地創建你自己的發射器。這只需簡單地從IParticleEmitter接口派生一個新類并使用setEmitter()方 法把它依附到粒子系統上去即可。
下一個實例將創建一個盒子粒子發射器。你可能已經猜出,它從一個跳躍的盒中隨機生成粒子。由參數來定義盒子,粒子的方向,每秒產生粒子的最小和最大數目,顏色以及粒子的最小和最大生命周期。
一個完全由發射器組成的粒子系統將是令人生厭的,因為缺乏真實感。因此,Irrlicht支持粒子影響器-它負責在粒子到處飛揚時予以修整。一旦添加到 粒子系統上,它們就能模仿另外的更真實的效果,象重力或風。在本例中的粒子影響器只是簡單地修改粒子的顏色來產生一種淡出效果。
可能 你已經猜出,粒子影響器是通過派生IParticleAffector接口實現的,然后通過使用addAffector()方法把它添加到粒子系統上去。 在你為該粒子系統設置了一種好看的材質后,你就有了一個看上去相當酷的野外宿營火的效果。通過調整材質,紋理,粒子發射器,還有影響器參數,你能容易地創 建煙霧,下雨,爆炸,下雪等效果:
| scene::IParticleSystemSceneNode* ps = 0; ps = smgr->addParticleSystemSceneNode(false); ps->setPosition(core::vector3df(-70,60,40)); ps->setScale(core::vector3df(2,2,2)); ps->setParticleSize(core::dimension2d(20.0f, 10.0f)); scene::IParticleEmitter* em = ps->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->setEmitter(em); em->drop(); scene::IParticleAffector* paf =ps->createFadeOutParticleAffector(); ps->addAffector(paf); paf->drop(); ps->setMaterialFlag(video::EMF_LIGHTING, false); ps->setMaterialTexture(0, driver->getTexture,"particle.bmp")); ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); |
七、 影子投射
最后但也不容忽視一個問題是,你需要為一個動畫角色產生一個動態的影子。為此,你裝載一個Quake2.md2模型文件并把它放到你的world上去。 為了創建影子,你只需要調用方法addShadowVolumeSceneNode()。你可能通過調用ISceneManager:: setShadowColor()來控制影子的顏色;注意,這僅是全局可調整的,并影響所有的影子。好,下面就是你的產生動態影子效果的代碼:
| mesh = smgr->getMesh("../../media/faerie.md2"); scene::IAnimatedMeshSceneNode* anode = 0; anode = smgr->addAnimatedMeshSceneNode(mesh); anode->setPosition(core::vector3df(-50,45,-60)); anode->setMD2Animation(scene::EMAT_STAND); anode->setMaterialTexture(0, driver->getTexture("../../media/Faerie5.BMP")); anode->addShadowVolumeSceneNode(); smgr->setShadowColor(video::SColor(220,0,0,0)); |
八、 游戲循環
最后,你能進入由device->run()方法控制的游戲循環。該循環將不斷運行,直到通過獲取一個關閉窗口事件(例如在Windows操作系 統下的ALT-F4擊鍵)來退出設備。你必須在一個beginScene()和endScene()命令對之間繪制每樣東西。beginScene()用 指定的一種顏色清屏,如果需要的話,可以同時清除深度緩沖區。然后你就可以讓場景管理器和GUI環境來繪制它們的內容。隨著調用endScene(),每 一樣東西都被繪制到屏幕上去。在本例中,你還可以動態地在標題欄上顯示幀每秒(FPS)數,這對于嚴肅的游戲開發者是十分重要的事情:
| scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(); camera->setPosition(core::vector3df(-50,50,-150)); int lastFPS = -1; while(device->run()) { driver->beginScene(true, true, 0); smgr->drawAll(); driver->endScene(); int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"Campfire FX example ["; str += driver->getName(); str += "] FPS:"; str += fps; device->setWindowCaption(str.c_str()); lastFPS = fps; } } device->drop(); |
結束循環后,你必須刪除先前用createDevice()方法創建的Irrlicht設備。通過使用Irrlicht引擎,你應該刪除所有你用以 ’create’開頭的方法或函數創建的所有對象。你可以通過簡單地調用device->drop()來刪除該設備對象。
九、你可能喜歡的Irrlicht插件
正如在前面所介紹的,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的非正式的外部地形生成器,此處也提供很多相關的教程。
發表于 @ 2006年02月22日 12:02 PM | 評論 (0)
基于Nokia手機的移動游戲開發步步通wxh zt
????摘要:
一、游戲開發策略
1?游戲動作(Action)的使用
MIDP的Canvas類讓程序員處理某些按鍵事件,要么作為特定的低級鍵控代碼事件要么作為抽象的游戲動作。FullCanvas是Nokia的全屏畫布(FullCanvas)類,它是從Canvas類繼承而來的。
在回合制游戲或者不需要超過四個方向鍵(上、下、左、右)的游戲中,最好使用直接的鍵盤代碼來控制游戲動作。可以使用抽象游戲動作的游戲例子包括國際象棋和知識測驗以及解謎游戲,這些都是使用方向鍵來滾動屏幕或者移動。
游戲動作應該只在不需要快速反應的游戲中使用。這是因為所選擇的設備的游戲動作映射可能對于要求快速動作的游戲并不適用。并且,如果一個游戲要求斜的方 向鍵或者這個游戲是一個快節奏的動作游戲,那時游戲者一只手需要移動游戲角色,另一只手需要執行其他操作,比如射擊、開門等等,那么就需要使用直接鍵盤代 碼。原因是在MIDP中沒有斜向的游戲動作,并且游戲動作映射是為一只手使用設計的。
當使用直接鍵盤代碼事件的時候,必須特別注意應用程序的可移植性。????(全文共27691字)——點擊此處閱讀全文
發表于 @ 2005年08月25日 4:25 PM | 評論 (5)
3D游戲開發流程
????摘要:隊伍組成
開發團隊
n ? ? ? ? ? ? ?制作人
n ? ? ? ? ? ? ?執行制作人
n ? ? ? ? ? ? ?策劃團隊
n ? ? ? ? ? ? ?程式團隊
n ? ? ? ? ? ? ?美術團隊
銷售團隊
測試團隊
游戲評論隊伍
游戲制作人
n ? ? ? ? ? ? ?開發組長(always)
n ? ? ?????(全文共16443字)——點擊此處閱讀全文
發表于 @ 2005年08月20日 12:40 PM | 評論 (0)
half-life2的圖形系統研究心得
????摘要:作者:佚名
小T一邊作自己的3D引擎,一邊研究half-life2的圖形引擎,留下點心得。
整體上half-life2給小T的感覺一是龐大,二就是難讀,com方式組織引擎,小T也不敢妄加評價,只是小T覺得整個引擎非常的難讀。小T只有借助 調試器才勉強對half-life2的圖形引擎有個大致的了解,至于怎么編譯half-life2,怎么運行,以及怎樣調試,小T就不詳細的描述了,到網 上隨便一搜索就能找到一大堆,這里只是簡單的看看他的圖形系統。
當前的3D環境,想要提高渲染速度,一個最基本的方法就是要減少硬件 的渲染狀態的切換,今天小T就是講hl2的渲染狀態管理部分的。在hl2里面,渲染狀態主要被放在了一個叫ShadowState_t的結構里面,這個結 構對應了大多數的硬件渲染狀態,渲染系統維護多個ShadowState_t結構,在必要的時候把ShadowState_t的內容真正的設置到硬件上 面,從而減少硬件的狀態切換。當然實際上卻沒有這么簡單,上面只????(全文共9751字)——點擊此處閱讀全文
發表于 @ 2005年08月18日 4:37 PM | 評論 (0)
讀程序員網游專題云風的文章有感
????摘要:讀程序員網游專題云風的文章有感 ????(全文共3782字)——點擊此處閱讀全文
發表于 @ 2005年08月01日 11:31 PM | 評論 (0)
基于圖論的幾何約束解算簡介
????摘要:基于圖論的幾何約束解算簡介????(全文共5690字)——點擊此處閱讀全文
發表于 @ 2005年08月01日 11:31 PM | 評論 (0)
spg系列c語言開發---改變 sprite 的楨的函數
????摘要:spg系列c語言開發---改變 sprite 的楨的函數 ????(全文共1938字)——點擊此處閱讀全文
發表于 @ 2005年08月01日 11:30 PM | 評論 (0)
進入Ogre的世界
????摘要:進入Ogre的世界 ????(全文共2435字)——點擊此處閱讀全文
發表于 @ 2005年08月01日 11:29 PM | 評論 (0)
總結
以上是生活随笔為你收集整理的用C++实现跨平台游戏引擎开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通知|百度1+X区块链系统应用与设计职业
- 下一篇: 安卓虚拟机_VMOS虚拟大师独立的安卓虚