0.爲了與本文狀況一致,建議各位看官的工具均升至最新版java
Eclipse Kepler+ADT 22.3.0+CDT-master-8.2.1+android-ndk-r9c-windows-x86_64android
1.下載Android版Irrlicht的源碼。https://gitorious.org/irrlichtandroid/irrlichtandroid/source/f12c3b9743d64dc5cd61931f40e42e8ca64b40ef:git
2.將源碼導入到Eclipse。怎麼導入?蹲牆角檢討半小時~~程序員
3.導入完畢,代碼結構以下圖windows
爲了程序能支持OpenGL ES,Android的版本號要在8以上,這裏我選擇的是android-16。而且將AndroidManifest.xml中的minSdkVersion改爲8app
4.右擊項目,選擇Android Tools→Add Native Support,在彈出的輸入框中,輸入irrlichtide
若是全部插件均是最新版,則會出現Include文件夾。函數
5.接下來,就是最激動人心的時刻,右擊項目,Run As | Android Application。完成!!工具
6.好吧~,還沒結束……,在通過幾分鐘的編譯之後,若是你的NDK是r9版本,就會碰到第一個坑。ui
這是由於,r9版本之後,方法的接口名變了。只需將
__android_log_print(ANDROID_LOG_INFO, "log", message);改成
__android_log_print(ANDROID_LOG_INFO, "log", 「%s」, message);
multiple definition of 'GL_BGRA'。這是由於,同時編譯了OpenGL ES1和OpenGL ES2,形成了重複定義。咱們首先使用ES1.x渲染。在include\irrCompileConfig.h,註釋掉#define _IRR_COMPILE_WITH_OGLES2_,再次從新編譯。
8.因爲全部的文件都間接包含了irrCompileConfig.h,所以等因而又從新編譯了一遍。
恭喜,編譯成功。
9.oh on!閃退~~看看logcat吧
請注意這句No OpenGL-ES2 support compiled in.其實,在/jni/android-activity.cpp的nativeInitGL()方法中,咱們能夠找到答案。
1: device = createDevice( video::EDT_OGLES2, dimension2d<u32>(gWindowWidth, gWindowHeight), 16, false, false, false, 0);
在建立device,用的是OGLES2,若是咱們一路跟進去createDevice()→new CIrrDeviceAndroid()→createDriver(),就會發現,因爲咱們註釋了_IRR_COMPILE_WITH_OGLES2_,致使程序irrlicht沒有底層圖形庫去渲染圖形,形成程序閃退。如今將createDevice的參數改成video::EDT_OGLES1
1: device = createDevice( video::EDT_OGLES1, dimension2d<u32>(gWindowWidth, gWindowHeight), 16, false, false, false, 0);
10.再次運行,是否是點的想吐了?吐也不行,哥依然閃現給你看~~……。繼續logcat吧
又發現線索,Could not load mesh, because file could not be opened: 和cannot getMesh。咱們能夠在項目中搜索cannot getMesh試試看。在/jni/app-android.cpp的initSydney()方法中,咱們發現
1: smgr = device->getSceneManager();
2: guienv = device->getGUIEnvironment();
3:
4: stringc myDir = gSdCardPath;
5: myDir += "/Irrlicht";
6: device->getFileSystem()->changeWorkingDirectoryTo(myDir.c_str());
7:
8: stringc sydneyFilename = "/Irrlicht/sydney.md2";
9: mesh = smgr->getMesh( (gSdCardPath+sydneyFilename).c_str() );
10:if (!mesh){
11: device->drop();
12: __android_log_print(ANDROID_LOG_INFO, "Irrlicht", "cannot getMesh");
13:return;
14: }
若是你能看懂上面的代碼,那差很少,也就知道錯出在哪了。程序要從/sdcard/Irrlicht/獲去sydney.md2,但手機的SD卡上並無這個路徑。因此,咱們能夠在SD卡上建立一個Irrlicht目錄,並把/IrrlichtSDCard下的文件拷貝到/sdcard/Irrlicht/。
11.若是一切順利,勞拉將會在紅色的背景中原地踏步~~
帥不帥~~
12.總有些人怕麻煩,還得在SD卡建立文件夾,還要複製文件……,DDMS還只能一個一個複製~~麻煩啊~~,還有方法嗎?
不怕麻煩的程序員不是好碼農!祕密就在Utils.java中,直接看unpackOnSdCard()
1:if (Environment.getExternalStorageState().compareTo(Environment.MEDIA_MOUNTED)==0) {
2: File sdcard = Environment.getExternalStorageDirectory();
3: String irrlichtPath = sdcard.getAbsoluteFile() + "/Irrlicht/";
4: File irrlichtDir = new File(irrlichtPath);
5:if (irrlichtDir.exists() && !irrlichtDir.isDirectory()) {
6:thrownew IOException("Irrlicht exists and is not a directory on SD Card");
7: } elseif (!irrlichtDir.exists()) {
8: irrlichtDir.mkdirs();
9: }
10:// Note: /sdcard/irrlicht dir exists
11: String[] filenames = assetManager.list("data");
12:for(String filename:filenames) {
13: InputStream inputStream = assetManager.open("data/" + filename);
14: OutputStream outputStream = new FileOutputStream(irrlichtPath + "/" + filename);
15:// copy
16: byte[] buffer = new byte[4096];
17:int length;
18:while ( (length = inputStream.read(buffer)) > 0 ) {
19: outputStream.write(buffer, 0, length);
20: }
21: outputStream.flush();
22: outputStream.close();
23: inputStream.close();
24: }
25: } else {
26:thrownew IOException("SD Card not available");
27: }
#1—#9 正是在SD卡上建立Irrlicht目錄
重點看11行
String[] filenames = assetManager.list("data");
該行代碼是獲取,/asset/data/下的全部文件名
由此,該函數的功能正是取代咱們以前的手動操做,將文件複製到/sdcard/Irrlicht/目錄下。
刪除以前的SD卡上的Irrlicht目錄,在assets目錄下新建data目錄,將IrrlichtSdcard下的文件複製到data目錄下
運行程序~~勞拉依舊飛奔~~
PS:在USB鏈接手機時,請將USB模式設置成僅充電,即不用經過windows的資源管理器訪問到手機的SD卡,不然Environment.getExternalStorageState()將會返回shard。剩下的,你懂得~~