Android OpenGLES – Load Customized Mesh File
This program originally come from an Android OpenGLES sample. It display a cube with texture. What I did is I pull the hard code cube mesh data out of the code, and save as an external file “cube.mesh”, then let the android try to load this mesh file.
Build the customized Mesh
To create the external mesh file that we could use it in the android program, a new project named “MeshCreator” was created. What this project just save the cube mesh as a binary file. And the mesh file format we design here is very simple.
Add the Mesh data as Android Resource
After you create the binary mesh file, you should add it to the android program resource. To do this, you should create a new folder under the android ‘res‘ folder, and move this mesh file into that new folder. And then, you switch to the Eclipse, select your project, right click, choose ‘Refresh‘. This will add the external file into your android resource list. You could check you ‘gen‘ folder R.java file, you could notice that a new item will created for your new added files.
Load the mesh data in Java
To read my customize mesh file from android program, some code wrote like this:
Resources resources = OpenGLES_ReadMeshActivity.GetInstance().getResources(); InputStream iStream = resources.openRawResource( R.raw.cube ); DataInputStream dis = new DataInputStream(iStream);int v_num = dis.readInt(); byte[] bytes = new byte[v_num * 4]; dis.read(bytes, 0, v_num *4);
A InputStream could be got from Resources.openRawSource(). I did some research on the web, it seems there are only some directories under the ‘res’ folder could be used. So maybe you need to do some test to check whether android support more folder under the ‘res’ and how depth about those folders.
Java use BigEdian Vs OpenGL-ES use LittleEdian
Java program use BigEdian, but the OpenGLES need some data in LittleEdian. If you did not do the conversion, you will get some running time exception: must use a native order direct buffer. There are already some solutions on the web to address this issue. To get the short cut way, I will cut their code to here:
public static IntBuffer GetNativeBuffer(int[] array) { // !!! Be careful, we use ‘allocateDirect’ here instead of ‘allocate’ ByteBuffer buffer = ByteBuffer.allocateDirect(array.length * 4); buffer.order(ByteOrder.nativeOrder()); IntBuffer intBuffer = buffer.asIntBuffer(); intBuffer.put(array); intBuffer.position(0); return intBuffer; } public static FloatBuffer GetNativeBuffer(float[] array) { // !!! Be careful, we use ‘allocateDirect’ here instead of ‘allocate’ ByteBuffer buffer = ByteBuffer.allocateDirect(array.length * 4); buffer.order(ByteOrder.nativeOrder()); FloatBuffer floatBuffer = buffer.asFloatBuffer(); floatBuffer.put(array); floatBuffer.position(0); return floatBuffer; }
Something More
One trick thing to write android program under the Eclipse is that you need to toggle on “Build Automatically” (under the “Project” menu item). This will make the R.java file generated automatically and avoid some projects compiling errors. In one word, you MUST to toggle on it.
To Confirm
I tried to launch this sample on Android Device. But the result was the texture mapping missing. And Some one told me that, I should compress the texture into PVRTC format because of Android CPU architecture.
The full source code could be downloaded from here. A document about how to set up the Android develop environment also included. The process to download the Android SDK will be a bit long, please be patient wait for it (Or only download the specified Android version). And the process of launch the Android emulator also a bit long.