I’m a bit dedicated to getting libGDX fully usable on Android that I created the template libgdx-termux it can use libGDX and build .apk files, all using only Termux.

I’m still continuing to bring more functionalities to make game development complete on Android.

And for today I bring you fbx-conv which is a converter utility by the libGDX team to convert 3D models into a more runtime-friendly format optimized for libGDX.

The reason why fbx-conv needs special treatment is because it uses a library that is only available on Intel x86-64 and most Android devices are as you know: ARM

I got this working via the QEMU emulator, follow the steps below to do the same.

Installing required packages

First let’s get some termux dependencies out of the way, install the following packages:

$ pkg install unzip qemu-user-x86-64

Downloading fbx-conv

Within the Github Repository scroll down and find the link for Linux 64-bit and download the zip file.

Now inside Termux, let us extract it within some folder, say, create this in your home directory.

$ mkdir ~/fbx-conv
$ cd ~/fbx-conv

Now we are inside the directory, extract the zip file we just downloaded, let’s say it’s located in our /sdcard/Download folder. (The typical downloads folder on Android, replace path as needed)

$ unzip /sdcard/Download/fbx-conv-linux.zip

Now running ls we see we have two files: fbx-conv and libfbxsdk.so

Running ./fbx-conv obviously won’t work since we are not on an x86-64 device so let’s setup the next part, our emulator.

Setting up Ubuntu RootFS and QEMU

We first need some ground work before we can call qemu, remember that the binary is not all we need (unless it’s a static binary which in our case it’s not) we also need some system libraries like the linker.

If we simply run qemu-x86-64 ./fbx-conv we get the following error:

qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory

As you can see it tries to lookup the x86-64 linker which is nowhere on our ARM device.

To solve this we download an Ubuntu RootFS, a RootFS is just the base file system of the distro, e.g all the /usr/bin, /usr/lib, etc. folders are there. It includes the system linker which is exactly what we need.

Here’s a direct link to download the Ubuntu 20.04 LTS rootfs: ubuntu-base-20.04.1-base-amd64.tar.gz (about 30 MB)

Got it? Cool, now let’s move on, back to your home directory we create another folder to store the rootfs

$ mkdir ~/ubuntu
$ cd ~/ubuntu

Now we extract the tarball we just downloaded:

$ tar -xzvf /sdcard/Download/ubuntu-base-20.04.1-base-amd64.tar.gz

All the files will be extracted, some will error due to hardlinks and tar may report a failure status but don’t worry we don’t care about that, the files we need are extracted, confirm by running ls you should see various stuff in the directory now.

Great now we are ready to use qemu, quickly go back to the fbx-conv folder (cd ~/fbx-conv)

Now we need to move the libfbxsdk.so into our Ubuntu RootFS so the linker can find it.

$ mv libfbxsdk.so ~/ubuntu/lib/x86_64-linux-gnu

Info

I tried a lot to get QEMU or the linker to recognize the current directory as part of the library search but it just didn’t work, so I just resorted to moving the fbx sdk to the Ubuntu RootFS.

Okay now ready for the actual QEMU command?

$ env LD_PRELOAD= qemu-x86_64 ~/ubuntu/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 --library-path ~/ubuntu/lib/x86_64-linux-gnu/ ./fbx-conv

Oh my! If it worked correctly you should see an output like:

INFO:     FBX to G3Dx converter, version 0.01.0000 x64 , FBXSDK 2019.00
ERROR:    Missing input file

Usage: fbx-conv.exe [options] <input> [<output>]

Options:
-?       : Display this help information.
-o <type>: Set the type of the output file to <type>
-f       : Flip the V texture coordinates.
-p       : Pack vertex colors to one float.
-m <size>: The maximum amount of vertices or indices a mesh may contain (default: 32k)
-b <size>: The maximum amount of bones a nodepart can contain (default: 12)
-w <size>: The maximum amount of bone weights per vertex (default: 4)
-v       : Verbose: print additional progress information

<input>  : The filename of the file to convert.
<output> : The filename of the converted file.

<type>   : FBX, G3DJ (json) or G3DB (binary).

Exciting! fbx-conv is running! An x86-64 binary running on our ARM device!

Note

Notice that we unset the LD_PRELOAD environment variable, this is related to Termux’s termux-exec plugin that allows shebangs pointing to traditional Unix paths e.g /usr/bin and translates it into the Termux prefix, e.g /data/data/com.termux/files/usr/bin. In our case this just creates issues since we are running a binary of a different architecture, to silence the error from termux-exec we unset the LD_PRELOAD library and therefore the plugin won’t be loaded.

Wrapping Up

Let’s create a script so we don’t have to run that long command everytime.

#!/data/data/com.termux/files/usr/bin/bash

unset LD_PRELOAD

qemu-x86_64 ~/ubuntu/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 --library-path ~/ubuntu/lib/x86_64-linux-gnu ~/fbx-conv/fbx-conv "$@"

Pretty simple, we just unset the LD_PRELOAD variable like before and in the end we pass $@ as the argument which in bash translates to all the command line arguments.

Now place that into a new file located at /data/data/com.termux/files/usr/bin/fbx-conv, then make it executable:

$ chmod +x $PREFIX/bin/fbx-conv

And done! We can now freely run fbx-conv anywhwere in Termux and do our work.

$ fbx-conv -f -v ship.obj
INFO:     FBX to G3Dx converter, version 0.01.0000 x64 , FBXSDK 2019.00
STATUS:   Loading source file
STATUS:   FBX file version 0 0 0
ERROR:    Unknown FBX file version, supported version up to 7500 (may be too recent)
PROGRESS: Import FBX 100.00%                                          
WARNING:  [ship_root] Node uses RrSs mode, transformation might be incorrect
WARNING:  [cube1_cube1_auv] Node uses RrSs mode, transformation might be incorrect
VERBOSE:  [shape(cube1_cube1_auv)] polygons: 92 (276 indices), control points: 48
STATUS:   Converting source file
STATUS:   Closing source file
VERBOSE:  Listing model information:
VERBOSE:  ID        :
VERBOSE:  Version   : Hi=0, Lo=1
VERBOSE:  Meshes    : 1 (227 vertices, 1 parts, 276 indices)
VERBOSE:  Nodes     : 1 root, 2 total, 1 parts
VERBOSE:  Materials : 1 (0 textures)
STATUS:   Exporting to G3DB file: ship.g3db
STATUS:   Closing exported file