Investigating ARCore with LibGDX
Like many Android developers, I was excited when the ARCore preview was released. I think there is a lot of potential for augmented reality to really change how users interact with applications, so I wanted to try it out. There is a Unity plugin for ARCore, it works with 2017.2 version of Unity. My day job was to write a codelab for the ARCore Unity plugin. It’s pretty easy to use, if you are interested in Unity, you might want to check it out.
What really piqued my interest was the Java library for ARCore. Being able to add a splash of AR to my Java Android applications would be awesome. So I downloaded the SDK and built the Hello ARCore sample. Nice stuff. When I started to read the code to figure out how it worked, I realized there is a lot of OpenGL needed to draw these 3d objects.
I am no stranger to OpenGL, but it is not a common sight in Android apps. With this in mind, I started looking around for an easy to use, full featured, graphics framework that I could call from Java, that would peacefully co-exist with ARCore.
I was a aware of the LibGDX project for some time, but never did any work with it, so this was a great opportunity to try to implement the sample “Hello AR” using LibGDX and avoiding openGL calls as much as possible.
LibGDX Touch points
LibGDX has a nice layered architecture, so it was straightforward extending 3 classes to integrate ARCore into the framework.
The class AndroidApplication extends Activity and is responsible for creating the GLSurfaceView. I extended AndroidApplication, to make BaseARCoreActivity. This class holds the ARCore lifecycle management, the configuration, and the ARCore session.
The graphics for an Android application are implemented in AndroidGraphics. This class also implements the GLSurfaceview.Renderer interface. ARCore needs to be aware of the renderer, so I extended AndroidGraphics to create ARCoreGraphics. This subclass handles:
- The management of the OpenGL texture for rendering the background image from the camera.
- Updating the current ARCore frame so it is accessible for rendering.
- Detecting and handling screen size changes and rotation.
Unfortunately, the graphics member of AndroidApplication is initialized in a private method. I worked around this by copying the code into BaseARCoreActivity.
The last touch point for LibGDX is the ApplicationListener. This interface is implemented by the application to handle input and render the objects on the screen. Since I want to have access to the ARCore Frame when updating my application and it is important to draw the background first, I implemented ApplicationListener in a class named ARCoreScene. This class exposes the Frame and Session from ARCore and handles the batching of objects to draw after drawing the background.
How to use “ARCoreGDX”
Once the LibGDX framework has been extended to integrate ARCore, how can this be used to create an AR experience?
Make an activity that extends BaseARCoreActivity
I created a subclass of BaseARCoreActivity. This simply configures the rest of the application, via initialize(). The parameters are my subclass of ARCoreScene and the default AndroidApplicationConfiguration from LibGDX.
Create an ARCore scene
The work of the app actually takes place in the scene. The key methods are:
create() — This is called when the application is created. In this method I start to load my 3D models asynchronously.
render() — This is called every frame and is where all the work is done. Everything that needs to be drawn on the screen needs to be rendered. This is also where you have access to the ARCore Frame and Session so you can interact with planes and anchors.
Thanks for reading! If you want to know more about ARCore’s API, I suggest you start at the ARCore developer site.
The official ARCore documentation is at: https://developers.google.com/ar
More information including tutorials for LibGDX is at : http://libgdx.badlogicgames.com
The full project is published on GitHub: https://github.com/google/helloargdx.
The code is based on 1.0 of ARCore. Feel free to try it out & let me know what you think!
Disclaimer: I work in Developer Relations at Google. This article is a quick introduction to a personal project using ARCore with LibGDX for Android. This is not an actual supported project by Google, just me trying out some cool stuff. All opinions are my own and don’t necessarily reflect Google’s.