libgdx part 7 – OpenGL

NOTE: This tutorial was written in march 2010. It is extremely outdated. Please go to the new fangled wiki at http://code.google.com/p/libgdx/wiki/TableOfContents?tm=6

A warning before we start: this tutorial will not teach you OpenGL ES. There’s a lot of sources out there that do a much better job than i’d be capable of. So let me give you a couple of links before we start.

  • OpenGL from the ground up: an extremely well written tutorial series on OpenGL ES 1.x. Covers all the basics you need to get started with OpenGL. Note that the tutorial is written for the IPhone and uses Objective C/C++. This shouldn’t be a big problem though as the API is the same.
  • OpenGL ES at Khronos: Khronos is the consortium responsible for all the OpenGL APIs out there as well as other things like OpenCL or the Collada format. The page linked includes the specifications for OpenGL ES 1.x as well as 2.0 as well as online manuals. It is a must to read this stuff if you really want a full understanding of what you do.
  • OpenGL ES 2.0 Programming Guide: the definite guide to OpenGL ES 2.0. It is more than worth the money and should be on any OpenGL ES programmer’s book shelf

Do not ever NEVER check out the Nehe tutorial series. It is outdated, does many things completely wrong and boils down to code dumps that don’t really explain anything. If you think you can do graphics programming with just copy & pasting codes, then go ahead and try them. I strongly advice against it. You were warned.

So now that you’ve read and understood all things OpenGL ES let’s look at how you can harness its power with libgdx. The first thing you will do is to create an instance of Application, either a JoglApplication or an AndroidApplication. In either case you must specify if you want to work with OpenGL ES 1.x or 2.0. The problem is that the two versions are incompatible so you have to decide what you want to use. This does not mean that you can’t write a game that has a rendering path for OpenGL ES 1.x and a second path for OpenGL ES 2.0. If you have an OpenGL ES 2.0 rendering path that you want to use you have to tell the Jogl and Android application to initialize a compatible surface and context. Here’s how you do that with the JoglApplication:

The last parameter of the constructor tells the JoglApplication to setup an OpenGL ES 2.0 context if available. On Android you do something similar:

Here we have the method AndroidApplication.initialize() which has a single parameter specifying whether to use OpenGL ES 2.0 if available.

To check whether OpenGL ES 2.0 could be initialized you do the same in both scenarios. You ask the Graphics instance whether OpenGL ES 2.0 is available or not:

If this returns false you have to fallback to OpenGL ES 1.1 or even 1.0. To determine which 1.x version is available you use similar methods:

OpenGL ES 1.1 is backward compatible with OpenGL 1.0, so if 1.1 is available so will 1.0. NOTE: if OpenGL ES 2.0 is available neither OpenGL ES 1.1 nor 1.0 will be available and vice versa as 1.x and 2.0 are not compatible!

So we now know how to initialize an application with OpenGL ES 2.0 support and how to check whether that was successful. The next thing to get going is to get a hold of the actual OpenGL API. On the desktop you’d normally use things like Jogl or LWJGL in Java, on Android you get an instance of GL10 or GL11 passed to your Renderer.onDrawFrame() method. Note that there’s no Java OpenGL ES 2.0 support on Android yet! Another thing to note is that desktop OpenGL is quiet a bit different to OpenGL ES. OpenGL ES is a streamlined version of desktop OpenGL with a lot of unnecessary features removed. It also adds functionality, the possibility to use fixed point math instead of floats being the most prominent one.

Now, with libgdx i want to offer a cross-plattform way to develop and prototype your games on the desktop and deploy them on Android without changing any code. This means that with respect to OpenGL we have to go for the least common denominator which is OpenGL ES. This is of course a problem as a couple of the OpenGL ES features are not available on the desktop. I therefor wrote a wrapper around Jogl implementing the OpenGL ES API (yes i’m that crazy…). It even supports fixed point, except for vertex buffer objects. The feature is working but i’d advice against using it. In my benchmarks i couldn’t find significant benefits from using fixed point on my Android devices (HTC Hero, Motorola Droid). On newer devices fixed point will make even less sense as they will most probably sport proper FPUs. The Droid already has an FPU.

Ok, we still have no idea how to get our hands on the OpenGL ES API. Here’s how that works:

Note again: when OpenGL ES 2.0 is available then Graphics.getGL10() and Graphics.getGL11() will return null and vice versa. If OpenGL ES 1.1 is available then you can either get a GL10 or a GL11 interface. If only OpenGL ES 1.0 is available you can only get a GL10 interface.

The interface GL10, GL11 and GL20 implement the full OpenGL ES specifications. The Java bindings for OpenGL ES 2.0 where done by my and can be downloaded seperately if you want from http://code.google.com/p/gl2-android/. It’s a tiny JNI bridge to the native OpenGL ES API.

Once you get a hold of a GL interface instance you can store it somewhere instead of always querying the Graphics instance. It will stay valid over the complete life cycle of the application.

All that is left is to use the GL instance in your rendering method, maybe like this:

That should be more than enough to get you started. As stated in the introduction, read all the material about OpenGL ES you can get a hold off and experiment with it. Next time we will have a look at the rest of the graphics related classes that will hopefully make you forget about OpenGL :)