Building and using OpenSceneGraph in Android
Requirements to compile OpenSceneGraph for Android
- Android-sdk (http://developer.android.com/sdk/index.html)
- Android-ndk (http://developer.android.com/sdk/ndk/index.html)
While Android-sdk version doesn't really matter, ndk version must be 4(Crystax Version) 5 ,5b,5c . Newer versions are expected to work. Recomended
version is Ndk 5b. Also, Cmake 2.8 is required to generate makefiles of OSG.
Platform minimum requirements
The Android device target needs to have Android 2.2 / Api Level 8. While it can be used under Android 2.1, it's not advisable because OSG don't works well on some Android 2.1 phones. In Samsung Galaxy S I9000 with Android 2.1 OSG won't run if it's not compiled with Ndk r4 Crystax (A non official build of Android Ndk) , but the same phone with 2.2 version will run perfectly with any compilation. r5c's Chagefile states that this has been fixed also for Ndk r5c.
Particularities of OSG in Android
There are some particularities that you need to know before compiling and using OSG in Android:
- OSG in Android only supports Static linking.
- OSG needs to be compiled with OpenGL ES 1.x OR 2.0
- Environmental mapping doesn't work.
- Automatic Shaders don't work.
- Multithreading Handler doesn't work.
- osgSim and osgShadow won't work if you don't link also freetype.
When working in Android you have to set OSG to work in GLES1 OR GLES2. It's not advisable to compile with support for both libraries at the same time. Runtime linking errors may happen. If you don't know how to set GLES1/2 please read OpenGL-ES in OSG wiki.
CMake building script will search the Ndk (With the original name as it is in google releases) in $HOME or $HOME/android_development.Otherwise you can set manually it's location with the environment variable: ANDROID_NDK.
When you call CMake you need to set the variable: OSG_BUILD_PLATFORM_ANDROID to on and DYNAMIC_OPENTHREADS / DYNAMIC_OPENSCENEGRAPH to off. The first variable enables the compilation for android because we are doing something similar to cross-compiling. The other two make OpenSceneGraph to compile statically. At the moment the build config generated for android only contemplates a static build not a dynamic one. The main reason is that you cannot "install" as it is the dynamic libraries onto your phone so all of them have to be in your apk. At the same time Google in their last ndk only supports RTTI and exceptions if you use gnu_static_stl. That would increase dramatically every dynamic library size.
So if you want to build a OSG with OpenGL ES 1.x you need to use the next line (supposing out-of-source build).
cmake .. -DOSG_BUILD_PLATFORM_ANDROID=ON -DDYNAMIC_OPENTHREADS=OFF -DDYNAMIC_OPENSCENEGRAPH=OFF -DOSG_GL_DISPLAYLISTS_AVAILABLE=OFF -DOSG_GL_MATRICES_AVAILABLE=ON -DOSG_GL_VERTEX_FUNCS_AVAILABLE=ON -DOSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE=ON -DOSG_GL_FIXED_FUNCTION_AVAILABLE=ON -DOSG_CPP_EXCEPTIONS_AVAILABLE=OFF -DOSG_GL1_AVAILABLE=OFF -DOSG_GL2_AVAILABLE=OFF -DOSG_GL3_AVAILABLE=OFF -DOSG_GLES1_AVAILABLE=ON -DOSG_GLES2_AVAILABLE=OFF
That will generate every Android Makefile needed to compile OSG for Android. Once that process is finished a Make will start compilation.
If you want to use -j option to speed build note that you can't use it from make command because our make will call ndk-build. To set the j level You have to set it in the cmake config line with the variable J (-DJ=2). We decided to use Android Makefiles to ensure the most possible compatibility between ndk changes instead of a straightforward crosscompiling. Because of that there are some standard options that don't work quite well, don't work at all or simply need more time and debugging.
After compilling you can do a make install to create a clean install directory with a header directory and a library directory. Inside the library you will have both armeabi and armeabi v-7 version of the libraries.
If you don't want to use the normal make and instead use directly ndk-build you can do so also. This makes accessible more info of the building process, compiler calls and other things.
$ $ANDROID_NDK/ndk_build NDK_APPLICATION_MK=Application.mk [OPTIONS]
NDK-Build useful options
|NDK_DEBUG=1||generate debuggable native code|
|V=1||launch build, displaying build commands|
|-B||force a complete rebuild|
|NDK_LOG=1||display internal NDK log messages|
For more info please read the documentation inside your ndk file folder.
Building your Application
In the last compilation chain we've included every serializer and deprecated to support .osg models. As stated before, please, be aware that this doesn't mean that everything works. If you encounter some errors or things that don't work, please contribute by providing information about the tests you've done.
By default we build OSG against Android/platform-5 this can be overridden in Application.mk before compiling. Do not try to compile in Platforms less than 5 it's not advisable even if you can. Remember Platform-5 are Android Devices with 2.0. Even so there are some incompatibilities in some devices as Samsung and the Galaxy i9000. In this model it will work, but only if you use Ndk r4, that's why we recommend to use 2.2 as minimum version.
In the last trunk version, OSG can be compiled for both armeabi and armeabi-v7. By default it will build the two library versions. If you don't need both, or you want to speed the building, it can be disabled by editing Application.mk. Please remember that when you create a Android package with both versions, the .apk size will double, but after installing the package your phone will only have the best version for the device.
Also there are two examples of OSG viewer for Android in examples' directory. It shows how to make a Gles context call with Java/Dalvik and how to call the jni bridge to OSG library calls. The examples have the next features:
- Resolution locked to landscape.
- Menu button shows a menu with options to load or delete models.
- Loading models using keyboard.
- Keyboard option in menu.
- Basic state and manipulator changes by keyboard.
- Android UI with buttons to center view and change mode of navigation.
- Touchscreen controls with pinch and drag.
The projects can be imported directly to Eclipse. Eclipse has also some plugins to compile at the same time the C++ code if you are not confident in building in command line as stated in: http://developer.android.com/sdk/ndk/overview.html#samples You can start from the provided examples (osgAndroidExampleGLES1/2) in ./examples that we've provided as a start.
The project can be imported in Eclipse creating a new Android project with existing sources and selecting the folder. After that you need to set up properly your include and binaries directories. If you are using Sequoya to integrate NDK in Eclipse now you can add Native support using the right button in the project and select Android Tools -> Add Native support.
The example program has the same egl start context as google's ndk examples and some code to get out virtual keyboards, masking of standard keys (the program will only close with home) and the code need to pass screen/keyboard events to OpenSceneGraph like mouse/keyboard. Multitouch is masked as mouse events instead of using the multitouch approach. We support using double tap to move, simple move to drag and pinch to zoom. We support as well a double tap (in different locations) to make a reset of the view.
Finally remember that OSG in android is a STATIC build so if you don't use the macros he won't know what plugins and serializers are or not enabled. The macro are: USE_OSGPLUGIN(name_plugin) USE_DOTOSGWRAPPER_LIBRARY(name_deprecated) USE_SERIALIZER_WRAPPER_LIBRARY(name_serializer)
3rd Party Dependencies
To ease the development of aplications, there is a 3rd party dependency pack with libjpeg,libpng, libtiff,libcurl and freetype to use with OpenSceneGraph in Android. It will work only with armeabi v5 and v7(With Neon extensions).
The package can be found at the next address: http://www2.ai2.upv.es/difusion/osgAndroid/3rdpartyAndroid.zip
To use the package, put the 3rd party directory inside the OpenSceneGraph root directory, it will be detected when you use CMake.
Current building system assumes Neon extension for every device with armeabi V7. This asumption is not correct in Tegra2 processors creating a runtime error. Use a armeabi v5 compilation or disable NEON extensions in the NDK scripts. This issue will be targeted on future submissions to the library by adding options to use (or not) optimizations.