SFML versus Libgdx

A couple of days ago i stumbled over a very nice alternative to SDL called SFML. It’s similar in goals to SDL but exclusively uses OpenGL for rendering things like sprites or text. Much like libgdx it allows to get mix rendering with direct calls to OpenGL. It’s a nice OO C++ API and heavily modularized. The APIs for rendering a very similar between SFML and libgdx. So i figured i give SFML a try and cehck it’s performance against libgdx. Being that it’s a plain C++ library i expected libgdx to be blown away. After all, SFML is considered to be the state of the art OSS API when it comes to 2D rendering.

I put together a simple test and implemented it in C++ with SFML and in Java with libgdx. Here’s what the test does:

  • Load two 32×32 pixel images, one in RGB888 and the other in RGBA8888 format.
  • Create 25.000 sprites using the first image without blending and 25.000 sprites using the second image with blending enabled
  • In each frame rotate and scale each sprite a little and draw it to the screen

So that’s a total of 50k sprites rendered to screen, a total of 50.000 * 32 * 32 = 51200000 ~= 51 million pixels per frame. Here’s the C++ code of the test, using SFML.

And here’s the equivalent Java version written with libgdx. Note that i implemented it as a GdxTest, which is just an ApplicationListener, no strings attached.

Note to self: please fix the ugly texture loading API. Something like new Texture(FileHandle handle, boolean createMipmap) would be super awesome…

Both programs output the number of frames per second, each second. The testmachine this is running on is my trusty Asus 1215n netbook which sports an Nvidia ION 2 chip. The C++ test as well as the latest snapshot of SFML 2.0 were compiled with Visual Studio 2008, with all possible optimizations turned on (emphasis on speed). The Java version runs on the latest Sun client JVM, no special VM arguments. Here are the results for SFML:


fps: 6
fps: 5
fps: 6
fps: 5
fps: 6
fps: 6

And here are the results for libgdx


SpritePerformanceTest2: fps: 25
SpritePerformanceTest2: fps: 25
SpritePerformanceTest2: fps: 25
SpritePerformanceTest2: fps: 26
SpritePerformanceTest2: fps: 25

OMG, JAVA IS FASTER THAN C++!!!!11!!one!. Actually the difference is due to two things: we transform the vertices of the sprites on the CPU. Sound crazy, but you don’t want to use the matrix stack like this, as Rockon or Andengine do it for example (which i can understand, cause it’s convenient). SFML transforms each sprite in a shader (in SFML 2.0 that is). The second reason is that SFML does not implement batching but draws each sprite separately.

Note: this is just a very very simple microbenchmark. Also, Laurent is currently in the process of spicing up the renderer backend, so expect you can expect better performance in future releases. I contacted him on the forums and told him about our approach, he’ll look into it :)

In any case, if you are a C++ person i highly recommend SFML. It’s API is really awesome and well thought out, it’s cross-platform (Win/Lin/OSX, so not as cross-platform as SDL, by why care) and the code is very well written and clean so you can easily modify or extend it. Give it a try, two thumbs up from my side.

  • http://www.darkrockstudios.com Wavesonics

    Wow very interesting, I know SFML has been working on batching for 2.0 for a long time now.

    He is trying to do implicit batching however which has a lot of obvious difficulties, what are your thoughts on implicit batching?

  • http://badlogicgames.com Mario

    It’s OK as long as you stay within the API itself. If you start mixing it with straight OpenGL ES you end up in hell. And i guess that’s the problem he tries to overcome. I don’t think it’s worth it.

  • dpk

    What version of libgdx introduced newTexture? It doesn’t seem to be available in the nightly from a few days back, at least not under Gdx.graphics.

  • dpk

    Er, nevermind, I see that they’re gone. Cool.

  • Dan

    There’s also a VertexArray class in SFML (rc 2.0) – This puts a bit more responsibility on the developer, but should provide much better performance. It would still require vertices to be transformed on the CPU though (which it currently is anyway).