Graphics programming through Allegro was something I last looked at in 2012. The article I wrote about it, Cross Platform C++ Programming with Allegro goes into some detail about the possibility of Allegro as a basis for cross platform software. The rationale expressed in that article has not changed but I decided to explore other options. One of those options are classified as application level software frameworks such as Qt, GTK and wxWidgets. I speak about them in my July 2014 article, Insight into Cross Platform Software GUI Development. At the same time, I decided to review graphics frameworks such as SDL and SFML. I was aided by the availability of books on the subject. SDL Game Development by Shaun Mitchell and SFML Game Development by Artur Moreira/Jan Haller/Henrick Hansson are both published by PACKT and provide a good background on two good graphics technologies. With the requisite introduction to the technologies, I decided to explore the idea of using SFML as a foundation for an GUI application framework.
Choosing SFML and C++
Over the last few months, I had been reviewing a number of works in areas of technology. One of those dealt with software security from Robert Seacord whose work I discuss in a series of articles (Raw Numerical Security, Raw Code Security, and Raw Data Security). Prior to reading his work, I was quite certain that the most productive way to write classically compiled, native computer programs was to use the C programming language. After reading Robert Seacord’s books in detail and considering the information he presents, I still believe that C is the most productive, quickest way to build native programs but that C++ has a design edge in drafting better structured code that could be better secured.
As a result of these considerations, I decided to keep with C++. As SDL is more C centric, that made SFML the default choice. During my prior exploration of the Allegro library as described in the C++ Cross Platform Programming article, I had taken the C centric Allegro library and shrouded it in C++. I did not want to do that again with SDL and thus having a clean, vetted, and ready library that is more compliant with C++ would save tremendous time and effort.
Code Blocks IDE
The operating system I am using for this exploration is Xubuntu 14.04 LTS running as a virtual machine under Ubuntu 14.04 LTS. Initially, I decided to just write the C++ code in a text editor and compile on the command line (as I did in an article for Allegro/C++) and that worked for a while, but to ramp up productivity, I decided to use an IDE. While I used Eclipse CDT in the past, I decided to go with Code::Blocks. I was skeptical at first, but after setting up an empty project and importing the text files that I had written, things looked up.
I setup an empty project in Code::Blocks and set the appropriate options to have the IDE reference the right SFML include files and libraries. After 3 weeks of working through the new code I had written, I found that Code::Blocks works pretty well in Xubuntu. I have to say that while I did not use Code::Blocks for wxWidgets programming in C or C++, it does work well for straight C or C++ in general. The only thing I do not like about Code::Blocks is the debugging facilities do not appear as productive as with Eclipse CDT but I can accept that as I would rather have a native code IDE for C and C++ code.
Initial Project and Build
See below my latest compile of the project I setup to explore SFML. In the Build log tab below, you see the command line that Code::Blocks is forwarding to gcc.
Run the SFML based Program
We invoke program execution through the IDE. The code I have written has produced a screen using SFML facilities to minimize the window, resize the window while redrawing the blue square centered while maintaining a 10 pixel break from the edge of the square and the window.
At first, the square would not remain centered whenever I resized the window. I thought my mathematics was off. That could not be since running the calculations on paper produced the correct result. The behavior of the resize made me consider that it was something else. I kept researching the matter, and came up empty until I started thinking about viewports. After a week, I went back to the sfml-dev website until I found a good article on 2D cameras and views. Within that article was a section titled, Showing more when the window is resized. The information in that section was what I needed to make the overall adjustment of the window contents maintain the proper aspect ratio.
Capture the Keyboard
The next objective was to handle keyboard input and repeat what was typed onto a facsimile of a data entry field. I had never done this before. Throughout my full career in technology, I used software programming technologies in which the code for data entry fields was pre-written by Microsoft, Adobe, or whomever, and all I needed to do was refer to the text typed into the field. I imagined what they might have done to make the field a usable object for corporate application programming, but I never had a need to peer into this concept at a deeper level. Just take it for granted. Well, I decided to try my hand at creating a data entry field from scratch.
The first thing was to define the concept of a mouse click. That is when the left mouse goes down and the goes up over the same spot, then you have a mouse click. The basic idea is to track the x and y coordinates of the mouse as it is moving and evaluate mouse button states in correlation to those x and y coordinates.
If the mouse is clicked within the rectangular region defined by the data entry field, then when a keyboard key is pressed, text would be drawn, a letter at a time, to the data entry field. Again, Java, .NET, HTML and etc provides code that does all this for you so this was going to be interesting coordinating the mouse/keyboard detection and output. At this point, I thought I would use SFML to determine the intersection of the x and y coordinates of the mouse with the rectangular bounds of the data entry field which is actual a graphical shape object indirectly mapped to OpenGL calls. After about an hour or two a day (I had other obligations to attend) for 2 or 3 days, I had success.
The Basic Ideas are Now Encoded
The entire point of this exercise was to see if SFML, usually applied to video games and simulations, could be used as a means for an application framework as well. Success with SFML means you have a general means to produce any kind of visual output, even multiple visual concepts, within one application in an efficient and cross-platform way. Investment in a software application would exist once as it does with Java but with the ready ability to tap directly into the computer system at a more efficient level and depth of access. I do not know if I am going to continue with this, but so far, I am satisfied that SFML has broad potential in highly structured, disciplined C++ programs.
See the following representations of the code. I switched to SciTE in order to show more of the text. I normally use gedit for text documents, but SciTE has more acceptable handling and presentation of formatted software source code. Each code section shown below will have a brief explanation and some will have a link to a PDF document that provides the full listing of the code.
The program starts at main() and the short sequence for program start is shown below.
Download PDF: Lists Main.cpp
Placed a few common values in a primitive configuration class. It is small enough that both header and implementation are shown together.
This was an early process setup to calculate basic geometry for shapes.
Download PDF: Lists interactionexplore.cpp
I eventually consolidated most of the event handling and logic for the window, keyboard, and mouse into one class called interactionhold. This potentially allows us to reuse the logic for multiple entities defined in the future. The interactionhold type spans more than a handful of lines of source text and so there are several representations below that emphasize various key parts.
Download PDF: Lists interactionexplore.cpp
Keyboard and Text
Keyboard handling is shown below.
Mouse handling is show as follows.
Mouse click detection.
Primitive form field text accumulation.
Top Level Program Implementation
A single area called central contains the primary coordination for graphics and interactivity. This central class refers to and accesses the other classes shown above.
Download PDF: Lists central.cpp
The rest of central.
We will embark on a journey to take what we have learned so far and do it better. Now that I know that Code Blocks actually has an official, prebuilt process for SFML, I can get started a second time without having to manually configure Code Blocks. First, we will start a new project in Code Blocks.
We get to choose the SFML project type. And look, it supports SDL as well.
We have a list of SFML versions. Of course, if you have a different version than these, you may have to revert to the manual configuration approach or modify the project after the initial setup.
We name the project SFMLApp to establish this as an application framework.
I am going to go with Clang instead of GCC this time around. It is my understanding the Clang supports C++11 better than GCC at this time. I have not researched that, I am going by vague references on some websites but moreover, warning messages from GCC that make it explicit that the C++11 support is experimental. I do not want experimental, I want production ready. C++98 is the previous standard and it is still widely in practice as of August 2014.
Code Blocks automatically generates code that looks similar to the tutorial on sfml-dev.org/tutorials/2.0/start-linux.php. I am going to delete all of that since I am going to approach it a different way. Before I delete this generated code, I am going to take the opportunity to see if the SFML configuration works by building and running the code.
Build is successful.
Running it in Debug Mode gives us two windows since it is set as a console application. Code Blocks launches xterm with instruction to have xterm launch the program from where it resides in the output directory containing the newly compiled program.
Now, in Release Mode, we have a single window as expected.
Clean everything out. I am satisfied that this SFML project template in Code Blocks is a quick way to reference the SFML dependencies such as the include files and the various libraries. If you inspect the command line output on Linux, you will see references to sfml-graphics, sfml-window, and sfml-system libraries which are in the system path if you have installed SFML from the repository.
After I have deleted the program text, I build and run the program again in Debug Mode and we get an empty execution environment.
We will quickly peer at what the settings are for building to the SFML library in Code Blocks. In my original attempt at doing this manually, I included more than what is shown here and now I see a more streamlined way to refer to sfml dependencies.
Compile, link, and run commands up close.
I am going to add a new class to validate some things.
Use the class builder to speed up the definition of the header and implementation files.
Code Blocks does fairly well in code file generation.
We are going to query the level of C++11 support in the Clang compiler. Not exhaustively but enough to show how LLVM/Clang recognizes C++98 versus C++11 syntax. As you can see, under default settings in August 2014, we have some interesting error messages for the nums2 variable using C++11 universal initializer syntax.
We are going to look at some compiler options.
We are going to toggle on the C++11 option for both Debug and Release modes.
We try the compile again and we have success for nums2 but I do not like the warning message. It is unnecessary noise in this case.
We will switch the warnings from everything to the standard all. I know it sounds like the same thing.
The final warnings configuration.
Let’s try the compile/link cycle again. We have a good result with clean compile/link output.
The program listing for exploring SFML was practical for understanding it hands on and putting the theoretical concepts from research into practice. Proceeding through the exploration of SFML in the way that I did has built up a greater level of awareness of issues and possibilities with SFML. Now, let’s look at how we might evolve the design to have better structure, internal reuse, minimize redundancy, and improve the process of introducing new functionality and concepts into the program.
Below is my first draft design (4 hours of contemplation) for a program structure based on SFML that provides an application level framework that takes advantage of the SFML technology. I created the diagram below in Dia on Ubuntu. The program, Dia, works much like Microsoft Visio that I’ve used in the past, particularly for UML based diagrams. I have a very basic static structure based UML diagram using only class diagram entities. I am not a fan of over using UML and once upon a time I used it extensively to architect new systems but I find it occasionally useful to map out a system in a clearer way.
As you can see below, we are striving towards a MVC based design with elements of the builder design pattern. At this point we have eschewed the observer pattern common in event architectures though not totally as we have strong coupling among publishers and subscribers of event data. What we have emphasized here is strong interface consistency that we can leverage to build familiarity that breeds high productivity. We have inheritance through composition as a preference to avoid fragile base class issues from developing while keeping our implementations more compact by way of structure.
We have not gone too far towards efficiency at the expense of readability and maintenance. Instead we have a good balance in terms of the design below to later be proven out in implementation. This is concludes this first exploration of SFML in August 2014.