>>分享Android开发相关的技术 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 19356 个阅读者 刷新本主题
 * 贴子主题:  编译Irrlicht On Android 回复文章 点赞(0)  收藏  
作者:javathinker    发表时间:2020-05-15 06:19:37     消息  查看  搜索  好友  复制  引用

    0.为了与本文情况一致,建议各位看官的工具均升至最新版

  Eclipse Kepler+ADT 22.3.0+CDT-master-8.2.1+android-ndk-r9c-windows-x86_64

  1.下载Android版Irrlicht的源码。 https://gitorious.org/irrlichtandroid/irrlichtandroid/source/f12c3b9743d64dc5cd61931f40e42e8ca64b40ef:

2.将源码导入到Eclipse。怎么导入?蹲墙角反省半小时~~

  3.导入完毕,代码结构如下图

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  为了程序能支持OpenGL ES,Android的版本号要在8以上,这里我选择的是android-16。并且将AndroidManifest.xml中的minSdkVersion改成8

  4.右击项目,选择Android Tools→Add Native Support,在弹出的输入框中,输入irrlicht

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  如果所有插件均是最新版,则会出现Include文件夹。

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  5.接下来,就是最激动人心的时刻,右击项目,Run As | Android Application。完成!!

  6.好吧~ ,还没结束……,在经过几分钟的编译以后,如果你的NDK是r9版本,就会碰到第一个坑。

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  这是因为,r9版本以后,方法的接口名变了。只需将

  __android_log_print(ANDROID_LOG_INFO, "log", message);改为

  __android_log_print(ANDROID_LOG_INFO, "log",  “%s”, message);

7.重新编译,在即将完成编译时,半路又杀出来一个程咬金
点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

            multiple definition of 'GL_BGRA'。这是因为,同时编译了OpenGL ES1和OpenGL ES2,造成了重复定义。我们首先使用ES1.x渲染。在include\irrCompileConfig.h,注释掉#define _IRR_COMPILE_WITH_OGLES2_,再次重新编译。

   8.由于所有的文件都间接包含了irrCompileConfig.h,因此等于是又重新编译了一遍。
点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  恭喜,编译成功。

9.oh on!闪退~~看看logcat吧

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

请注意这句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吧

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  又发现线索,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.如果一切顺利,劳拉将会在红色的背景中原地踏步~~

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  帅不帅~~

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: throw new IOException( "Irrlicht exists and is not a directory on SD Card");
     7:     }  else if (!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: throw new 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目录下

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

  运行程序~~劳拉依旧飞奔~~

  PS:在USB连接手机时,请将USB模式设置成仅充电,即不用通过windows的资源管理器访问到手机的SD卡,否则Environment.getExternalStorageState()将会返回shard。剩下的,你懂得~~



----------------------------
原文链接:https://blog.51cto.com/youngcold/1349168

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-06-05 08:21:24 重新编辑]
  Java面向对象编程-->Swing组件(上)
  JavaWeb开发-->Web运作原理(Ⅱ)
  JSP与Hibernate开发-->JPA API的高级用法
  Java网络编程-->RMI框架
  精通Spring-->Vue Router路由管理器
  Vue3开发-->通过Vuex进行状态管理
  Android在SDcard建文件夹(在Android中移动文件必用)
  Android开发实践:编译VLC
  android cts 相关
  编译Irrlicht On Android
  Android UI学习 - Menu
  Android JSON网络数据交换
  Android Spinner范例
  ]android:gravity / android:layout_Gravity 的区别
  Android开发随想:iPhone和Android之间的对话
  浅析Android的通知系统
  Android SDCard Mount 流程分析
  Android 加载大图/多图,有效避免OOM
  Android中使用Activity管理类
  Appbarlayout+Recycleview滑动效果颜色渐变
  在腾讯面试Android技术的经历
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。