本人3D编程方面超级菜鸟,因为项目需要,接触了一些Open Scene Graph(OSG)引擎的相关编程工作。首先我得承认,OSG这个引擎超级牛,无论是渲染效果和效率,都没的说,很棒。但是,OSG提供的Android example真是不敢恭维,里面的代码逻辑有很多冗余+bug(至少在我的三款测试机上都表现如此)。
闲话少说,为了不让别人再入坑&做个记录日后方便查阅,说一下osgAndroidExampleGLES1这个工程的坑。Java层代码没什么好说的,直接说Jni下面的C++代码。
Problem 1
一个example涉及的操作过多,而且都交织在一起,没什么注释。对于初学者,真心各种看不明白。在此做一下简单的介绍,OsgAndroidNotifyHandler这个类和android的log类一个功能,就是在logcat里打印一些信息。其实OsgAndroidNotifyHandler.cpp这个文件的内容就是利用OsgAndroidNotifyHandler对 __android_log_write函数做了简单封装。osgNativeLib.cpp这个文件包含了所有的接口函数,搞过ndk开发的人应该很容易看懂。整个jni文件夹下面的精华都在OsgMainApp这个类中,其中_viewer是用来设置投影矩阵之类的,相当于摄像头,将模型通过一系列矩阵变换最终投影到设备屏幕上(手机上就是手机的GLSurfaceView)。_root是所有模型的根节点,需要显示的模型都将添加进_root或_root的子节点中。_state用来设置一些OpenGL ES选项,比如是否打开灯光什么的。_manipulator是用来控制camera,就是控制摄像头的轨迹,用于展示包含模型的场景用的。
Problem 2
example里面添加的是鼠标响应事件,和android的触屏事件对应的很不好,我这边的效果是,轻轻一碰屏幕,模型就不知道飞哪里去了,响应太敏感了。如果是初学OSG+Android,建议把OsgMainApp.cpp中101到104行及相关代码注释掉。这样就不怕一摸屏幕就看不到模型了。如果需要模型能响应触屏,我觉得还是自己写触屏事件,然后根据相应参数添加变换矩阵来控制模型姿态比较好。
Problem 3
代码中的载入模型、清除模型等函数的逻辑有问题,会导致example的不正常显示。至少在我这边的测试中,如果载入了一个模型,但是不在退出程序之前clean,下次再打开应用,载入模型之后就会什么都不显示。这是因为应用退出之后,有些情况下Android系统没有完全kill掉它,再打开进入的时候,由于example中奇葩的、眼花缭乱的各种暂存model的vector设计,导致逻辑有误,无法正确显示。更奇怪的是,这个example在调用_viewer->frame()函数去显示每一帧的之前,都要重新载入一遍所有模型,这个操作显然是没有必要的。针对以上问题,改起来幅度比较大,建议直接把loadObject函数中的代码都删除,改为直接加载模型并添加到_root节点。
总之,OSG这个android example真是很难搞,想自己开发的话,最好大部分都不要参考这个工程里的代码并且要大概学学OSG的基础知识。