More new stuff for libgdx!

Mr. Thotep asked for mouse capturing and cursor invisibility. I added that today (besides a few other additions and fixes). Here’s how the new methods in Input look like:

The first method will make the cursor invisible on the desktop and make sure the mouse can’t leave the window. It works perfectly fine with the Lwjgl backend. For the Jogl backend i had to emulate this behaviour with Robot. Sadly, it will not work 100% if the mouse speeds are to fast: the mouse can escape the window in that case.

The second method’s function should be obvious. The third method allows you to position the mouse cursor within the window. That can come in handy for first person shooters where you usually center the mouse cursor in your window and only operate on deltas. But how to get the deltas? Looky:

Simple, eh? With all those nice additions we are nearing the 1.0 release with big steps. The last bits missing are the UI stuff i talked about earlier which i’ll try to integrate over the weekend, as well as finishing off the 3D API, which is also in a pretty good shape already.

Note: the cursor related methods in Input will of course only work on the desktop. The delta methods work on all backends! Finally, Gdx Remote needs an overhaul i don’t have time for at the moment to also implement the above methods. I’ll do that eventually, just not now. And the Angle backend also needs some love. Both things are recorded as issues on the tracker so i don’t forget them.

UI stuff tomorrow or on sunday if all goes well. Release of 0.9.2 with all the new stuff plus fixes on sunday 🙂 Use the nightlies for now.

Also, a shout-out to MatthiasM over at the #lwjgl channel for fixing a bug in Lwjgl we discovered today. I could have submitted a patch as well, but i was to lazy 😀 He’s also the guy that provides us with the awesome TWL UI library, go check it out (supported in libgdx!).

Fix for accelerometer reading in libgdx

I just got around fixing the longstanding issue of those funky new tablet devices with HC (and one Motorola Phone) that have a landscape native orientation. Here’s an image illustrating this super awesome situation (taken from NVIDIA’s accelerometer whitepaper):

As you can see, on phones, the native orientation is portrait. That means

  • The accelerometer x-axis coincides with the smaller side of the screen
  • The accelerometer y-axis coincides with the bigger side of the screen
  • The accelerometer z-axis comes out of the screen

On shiny new tablets like the Transformer the native orientation is landscape. That means:

  • The accelerometer x-axis coincides with the bigger side of the screen
  • The accelerometer y-axis coincides with the smaller side of the screen
  • The accelerometer z-axis comes out of the screen

Which is totally fucking awesome. Thankfully the Android API does not provide a direct method to detect the native orientation. With a bit of creativity (Display metrics + Display.getOrientation()/getRotation()) one can however reliably determine the native orientation.

I did just that, and we are now “correcting” the accelerometer readings for your convenience. No matter the device, the y-axis will always coincide with the bigger side of the screen, the x-axis will always coincide with the smaller side of the screen. Just as it was on phones for the last 3 years.

In addition to that i added two new methods to the Input interface:

The getRotation() method returns an angle in degrees (0, 90, 180, 270), indicating the rotation relative to the default orientation of the device. The getNativeOrientation() method returns, well, the native orientation.

If you “fixed” the above “issue” yourself so far, make sure you revert that when updating to the latest nightlies! All other methods to calculate the orientation on the three axes in angles and so on work as expected, with the same reference system on all devices.

edit: on the desktop these methods return 0 and Orientation.Landscape. Always. GdxRemote has to be adapted to report the correct values. I put that on my todo list.

Tons of new Stuff in Libgdx!

For the next 4 days (including today), i put together a nasty todo list for libgdx 1.0. Today i finished off all the things i planned for today. So hurray me 🙂 What’s new?

Displaymode Enumeration and Fullscreen Support
A feature that’s been on my todo list for a gazillion years already. The Graphics interface has a couple of new methods that allow you to query for available fullscreen display modes and set them with a single call. Here are the new methods:

Before you can change the display mode you have to make sure you can actually do that. Nothing will fail per se if you try to change a display mode when that feature is not supported, but it is good practice 🙂

These two methods return the available fullscreen display modes. The first one returns all of them, the second one returns the desktop display mode currently set. Usually you want to go fullscreen with the width/height of the desktop display mode. However, if you want to be fancy you can enumerate all display modes with the first method, present them to the user and let them chose what fullscreen resolution they want to run with.

Sets a DisplayMode retrieved via getDisplayModes() or getDesktopDisplayMode(). This will return whether that action succeeded. In case it did your ApplicationListener will also receive a call to its resize() method later on.

For the brave among you, you can directly try this method. Specify the width and height of the resolution in pixels and away you go. Note the last parameter. If it is false you will switch back to windowed mode. This method also allows you to resize your window in windowed mode 🙂

You can call all these methods at any time, except for the dispose() method. Usually you’ll call them in create() and render() when appropriate.

Also note that these methods have no effect on Android of course. The getDesktopDisplayMode() and getDisplayModes() methods will return a display mode specifying the native screen resolution. Setting a mode on Android does not work for obvious reasons. If you don’t need fullscreen on Android remember that there’s the AndroidApplication.initializeForView() method!

Here’s the DisplayMode class in all it’s glory:

You can’t instantiate that one, use the getDisplayModes() and getDesktopDisplayMode() methods.

VSync
Another new method:

Straight forward. On Android that method has no effect. In Lwjgl it will either synch to the display refresh rate (which might fail) or use a cpu synch that tries to cap the framerate. The later was the default until now. Both suck. Jogl manages to vsynch with the display just fine it seems. More on the Lwjgl vsync stuff in a bit.

Querying the Buffer Format
The buffer format is a term i totally made up. What i mean by it is the number of bits for the color buffer, the depth buffer, the stencil buffer as well as the number of samples used for MSAA (anti-aliasing on the desktop).

Here’s the BufferFormat class:

To query the buffer format used by the OpenGL surface call the following Graphics method:

The BufferFormat instance will then tell you with that color, depth and stencil depth you are operating as well as how many samples are used for MSAA.

JoglApplicationConfiguration, LwjglApplicationConfiguration, AndroidApplicationConfiguration
Now, how can you set the buffer format? With the new configuration classes for all three backends! We already had the AndroidApplicationConfiguration, see this blog post. That one got extended a bit. Let’s go over them one by one.

Fancy, right? You can specify whether you want to use GLES 2.0, how many bits per color channel to use, how many bits to use for the depth and stencil buffer and so on. You can also specify if you want to immediately start off as a fullscreen application instead of toggling that in ApplicationListener.create(). To facilitate this there are two static methods called getDesktopDisplayMode() and getDisplayModes(). Guess what they return 🙂 Use the setFromDisplayMode() method to set the configuration from a specific fullscreen mode. You use this class like this:

Easy, right? The LwjglApplicationConfiguration looks exactly the same:

As you can see it is nearly 100% identical. You can use it in the exact same way as you use the JoglApplicationConfiguration, just pass it to the constructor of your LwjglApplication after you defined it. Note the additional flag called useCPUSynch. If that is set to true the vsynch is simulated via frame rate capping to 60fps. If it is set to false and vsynch is enabled (Graphics.setVSync(true)) then Lwjgl will try to use the real display vsync.

Finally we have new additions to the AndroidApplicationConfiguration:

As expected, you can now also specify the buffer format on android. The default values will work on all Android devices.

A Word on Stencil Buffer Support
By default all the backends do not create a stencil buffer. If you want a stencil buffer you have to set teh config.stencil flag to a value. On Android you should set this value to 1, EGL will then chose the nearest supported stencil format. On the desktop (Lwjgl and Jogl) you should set it to 8.

That is all, enjoy.