DISCLAIMER: This article was migrated from the old blog thus may contain formatting and content differences compared to the original post. Additionally, it likely contains technical inaccuracies, opinions that I may no longer align with, and most certainly poor use of English (I was young and foolish :)). This article remains public for those who may find it useful despite its flaws.
There was always big need for libraries that provide an abstract interface towards the basic platform specific facilities that are necessary for setting up an execution environment for a particular application. In the OpenGL world one of the first such libraries was GLUT. After a while more and more functionalities were put into these libraries that reflect more or less the requirements of application developers. One such framework is SDL. It seems that SDL is still the most respected one of these and it is preferred by the developer community. However, in this topic I will present an alternative that proved its superiority to me in the last few months…
Why would I need such a library?
There are loads of reasons why it is good to have such a framework in your toolkit. I would like to present only a few that I consider important. First of all, having some easy to use API to setup the basic environment for your application, like a window with an OpenGL rendering context, simply removes the burden from dealing with such platform specific details and concentrate on the actual product. Next, they usually give a quite good degree of platform portability so you don’t have to study specific operating system APIs and you can still deploy your application on multiple platforms. I can recite many other reasons but the most important one is that they are reusable components so you don’t reinvent the wheel.
For a while I was quite satisfied with my own implementation of such a toolkit until I moved from Delphi to C++ development. This forced me to look around on the market to find a replacement for my proprietary solution as C++ has a very large developer community so it shouldn’t be that hard to find a suitable framework. Well, actually this wasn’t the case as it was the time when the OpenGL 3 specification came out with its new context creation and deprecation model. It was very embarrassing to observe that even the most popular multimedia frameworks are hardly adopting these new features.
At that time I realized that my library choice will heavily affect my productivity in the future so I have to think well which one I will use afterwards. To ease the selection I created something like a wish-list about what I expect from such a library. The most important issues were the following:
- Feature-rich – The library must provide the most basic functionalities needed for an average OpenGL application. This includes window and rendering context handling, keyboard and mouse user input capture, timing facilities and, of course, supports OpenGL 3 contexts. Optionally it would be nice if the API also provides multi-threading, image and audio handling, basic network operations, joystick support, etc.
- Modular – The library must be modular, that means I can select which components of the framework I would like to use in a particular application. Sometimes less is more so, as an example, in a very simple cube rotating OpenGL demo I don’t want to link against a library which contains network handling. Such monolithic libraries makes life much harder as they usually rely on exotic dependencies and prevent easy deployment of the application.
- Portable – It should be portable, at least it should work on the three most popular PC platforms: Windows, Linux and MacOSX. It has to work also with a variety of build systems, preferably with Visual C++, GCC and Xcode. Optionally it would be nice if it can be interfaced by applications written in other programming languages than C/C++.
- Easy to use – In an ideal world such a framework should have a very clean interface and its usage must be very natural for the developer. This issue is however rather subjective so what it easy to use for one developer maybe it’s not the best for another. Regarding to this issue I will present the alternatives, obviously, from my perspective.
Maybe choosing such a multimedia library for an OpenGL hobby project is just a matter of taste, but when it comes to support for OpenGL 3 context support, developers have very limited choices and one most probably faces decisions when they have to make some trade-offs when selecting any of these libraries. Anyway, as one of my key requirements is that the library must support OpenGL 3 contexts, it is not that difficult to present all the most popular alternatives.
Simple DirectMedia Layer
SDL has a long history in this domain and it proved that it is an excellent choice for most hobbyists and even for professionals. It has been used in tons of different free and commercial applications and it is probably still the most preferred library in this category. Lets examine it regarding to the issues presented previously.
SDL provides almost all the facilities that are needed for an average graphics application. Together with some additional libraries developed as an extension to SDL like SDL_image and SDL_net it conforms to almost all of my requirements regarding to feature content. The most important is that its latest development branch also has support for OpenGL 3.
From point of view of modularity, especially taking into account that the less common used facilities are provided by different add-ons, SDL seems to be a good choice. However, the SDL core itself has already a bit too much dependencies on other operating system specific libraries, especially the reliance on DirectX on the Windows platform. Even if probably most of you can live with this, it is simply unacceptable for me. Anyway, this is still not the biggest problem what I’ve faced with when I checked out whether SDL suites my needs.
Platform portability is one of the key advantages of SDL as it even supports many other platforms than what was on my wish-list. Also regarding to language portability, the C interface of SDL makes it very easy to drop into a Delphi project as an example. Actually there are also plenty of bindings for other languages for interfacing SDL including but not limited to Java, C#, Delphi, Ada, Perl and python. However, when it comes to build system portability I have to mention my bad experiences.
First of all I am that kind of animal who uses GCC also for compilations under Windows. As SDL comes with an automake based build system which proved to be unusable using MSYS and I would rather not use Cygwin as it also introduces quite many unwanted external dependencies. After giving up compilation using MinGW, I tried to build the library using the good old Visual C++ IDE. This is when I faced the problem that I would have to install the DirectX SDK in order to compile SDL. The final hit was that even after downloading and installing the huge DirectX SDK, SDL still refused to compile with weird compiler errors.
By the way, all these compilation related issues wouldn’t be a problem for me if SDL would come with a binary release. Even if it has such releases for earlier versions, it does not have it for the latest development branch which contains the OpenGL 3 related stuff. So actually I cannot even prove that the OpenGL 3 specific implementation in SDL works in practice or not.
The API interface provided by SDL got skewed up meanwhile, arising from the fact that SDL has a long history, but still I cannot say that the interface is not clean enough to be easily used in any project. So in this regard SDL is still a major player.
The OpenGL Framework
My second was GLFW as it was the only library that supported OpenGL 3 as far as I knew at that time. For those who are not familiar with this library, GLFW is a simple yet powerful toolkit with a similar interface like GLUT but with added capabilities like multi-threading and joystick support (see GLFW home page).
It is a very feature-rich framework compared to its size and even not being very modular, it still does not involve that much external dependencies as SDL. As it also provides OpenGL 3 support only in it’s latest development branch I had to compile the code here as well, however, it was straightforward to do it even using MinGW so I don’t have any complains regarding to this subject. Also it supports multiple platforms, at least those that I am mainly interested in.
Unfortunately, as many other early OpenGL 3 context handling implementations, it wasn’t working on all platforms. More precisely, under Windows the OpenGL 3 code in the development at that time (about half year ago) worked only with NVIDIA cards as, non-compatible with the Microsoft WGL specification, NVIDIA’s ICD exposed the wglCreateContextAttribARB function even if there was no valid OpenGL context bound and, as usual, the developers used only NVIDIA cards for testing which resulted in a partially working OpenGL 3 context handling implementation.
As the code of GLFW is also very straightforward and handy to read, I easily corrected the bug in the OpenGL 3 context handling and I used GLFW for a few months for my hobby projects. After a while, however, the lack of some facilities in GLFW made me to think through this library selection again as I didn’t want to end up using several different libraries for different purposes which would result in a barely well designed code structure.
Simple and Fast Multimedia Library
We’ve arrived to the main topic of this article. Finally I’ve found SFML which at first sight seemed to be “just another multimedia library” but I soon realized that it’s far more than that.
First of all, it has all the features I needed. Beside the basic ones, it has very nice support for networking but not just basic socket programming using TCP or UDP packets, but a more comprehensive toolkit for even HTTP and FTP transactions. It also has built-in sound support via OpenAL which was another thing that caught my attention as I also preferred OpenAL over other audio libraries like fmod. Beside this, it has many other interesting features but you’d better check out the SFML project site.
As I already got used to, SFML had also support for OpenGL 3 context handling but only in the latest development branch. Anyway, this seemed to be no problem as I had no building issues like that what I met in case of SDL. What is more important that the OpenGL 3 implementation actually worked flawlessly, there was no need for any modification. Just to demonstrate, setting up an OpenGL 3 window with SFML can be as easy as writing the following line of code:
sf::Window App(sf::VideoMode(800, 600, 32), "OpenGL 3 window", sf::Style::Close, sf::ContextSettings(24, 8, 0, 3, 2));
When it comes to modularity, SFML also wins at me. First, it does not need any exotic libraries or headers for rebuilding the framework. Beside this, it has minimal number of external dependencies but only to the operating system libraries used. It is also modular as different sub-systems of the framework are compiled into different library modules so in your project you can simply select which ones do you intend to use to further minimize deployment issues.
From portability point of view, SFML supports all the platforms that are important for me. Also SFML works with no fuss indifferent with all the compiler tool-chains I’ve tried. At first sight I had concerns regarding to the language portability of SFML as is was written in C++ and this C++ interface is exposed to the client. However, this issue was solved by the library by providing a C wrapper called CSFML together with the framework itself which makes it rather straightforward to write binding for virtually any programming language.
If I haven’t convinced you so far that SFML can be the perfect choice as a multimedia library for almost any hobby or commercial product then you should check out the full feature list and see for yourself. I will probably write more about SFML in the future and you will also meet some usage examples in my upcoming demos.
If you are not interested in the additional features provided by SFML, instead you are just searching for a very basic framework that provides you a window and some user input handling then GLFW can be your choice. However, based on my bad experiences I would not advise anymore the usage of SDL to anybody but maybe I’m a bit too inclement.