with Tags: c++ X
Introduction to a series of simple tutorials
Over recent weeks, I have spent many hours updating previous OpenGL projects to work without using the deprecated fixed function pipeline. The reason for this is to future proof some of my 3D tools in case the required functionality is ever dropped from the OpenGL driver provided by FreeBSD.
Admittedly I was at first quite skeptical of the new(ish) way of doing things and hated the idea of breaking the backwards compatibility of older OpenGL (especially closed source) software. However, NVIDIA for one has stated that they will not be removing fixed function pipeline emulation for some time in their drivers but also the fact that the new OpenGL API is much much cleaner and nicer to work with without having to worry about such intricate state changes.
Using shaders is not a new concept but previously my software also used a fair chunk of fixed functionality (such as the inbuilt matrix system) and this needed to be changed out and the work delegated to a shader and implemented myself.
The road to completion has generally been very troubled since there is a lack of definitive documentation. Instead many tutorials mix and match parts of the fixed function pipeline with a few of the new OpenGL APIs.
This hasn't been helped by the fact that the OpenGL driver provided by Mesa on FreeBSD reports version 1.4 and thus some of the newer features (such as those found in the 4.x core profile) are not available to me or do not work by default. Luckily for me there are many extensions to the OpenGL implementation for my Intel GMA 950 graphics card so I can still do pretty much anything.
I have decided to attempt to document the steps required to build a sizable OpenGL project which can perform all tasks using shaders, whilst at the same time working on older cards as well as more recent hardware. So whilst I will be using OpenGL 2.x, I will not be using functionality such as glTranslatef, or GL_LIGHTING so the same code should work perfectly with OpenGL 4.3 and OpenGLES 2.0.
The first tutorial in the series is to simply get a Glut window open and displaying ready for the later steps. I am using C++ but will not be creating classes since I feel this complicates things greatly in tutorials. I will also only be using standard libraries provided by the OpenGL SDK since I also dislike learning from other developers "wrapper" classes. (I have not yet decided whether to use OpenIL (DevIL) or libpng for the textures...)
OpenGL Book (http://openglbook.com)
OpenGL Programmers Guide (6th edition) (Red Book)
Swiftless (Deprecated) (http://www.swiftless.com/opengltuts.html)
LazyFoo (Deprecated) (http://lazyfoo.net/tutorials/OpenGL)
When working with 3D animation, it is vital that the framerate of the software remains consistent. This ensures that each frame of animation is displayed on screen for the same amount of time as one another. This make for a much smoother result, but also enforces correct speeds such as walking or jumping.
So with this in my applications main loop, the framerate stays at a constant 30fps. Admittedly 30fps is a littleslow for most 3D applications, but my Thinkpad X61 hasn't got much power for graphics processing. This could be expanded upon to skip frames if the target is lower than the difference.
This example uses glutGet to obtain the time, this could easily be changed for individual GUI toolkits. It would even be possible to create a bespoke timer by introducing a thread that just counts continuously.
An interesting feature of my dissertation is how the C++ GUI library handles callbacks such as onButtonClicked() and onListIndexChanged(). In the past I have always found ways around relying on function pointers for user specified code to run on certain events. Instead I would usually opt for using an adapter class where the user can override abstract methods such as onMessageReceived(). The limitations of this can easily be seen once multiple adapter classes need to be inherited from and additional difficulties arise when multiple instances of the same component (I.e a Button) exist in a class and end up sharing the same callback. So for this reason I decided to bite the bullet and create my own system for handling this.
After my initial research I found that std::function could handle most of this for me and is also part of the C++ standard (thus the std namespace). Unfortunately it must have been a new addition to the standard since it didn't seem to exist on my older version of g++ (not even in the tr1 namespace). Since I tend to only use features that are in the lowest common denominator of platforms (and because I like to hack on code ;), I decided to write my own simple alternative.
Function pointers in C++ are seemingly
more complex than their C counterparts because the class instance
needs to be known in order for the callback to work. I decided to get
around this issue by introducing templates so the type of the
“callback class” could easily be specified. When working with
templates, it quickly began getting messy since the template type had
to keep being specified every time the function pointer class was
being passed around in the application logic. So to get around this I
inherited from a more generic Function class. This can be seen in the
So now a GUI component such as a button can contain a fully encapsulated function pointer for it's onClickEvent(). This can also be put inside an auto_ptr container to prevent any memory leaks. The only real work now is making sure that the class containing the method that the function points to is not deleted when being called but if the software has correct logic, this will be very unlikely anyway.
In short, I no longer need be jealous of the callback systems found in javax.swing or Windows.Forms since although done quite differently, my GUI library should hopefully be as straightforward to use in this respect.
From the code above it is also trivial to add a template class similar to GenericFunction which can take a void* parameter so the caller (i.e Button) can also be passed when calling the function pointer's function, so it is possible for the programmer to determine in code, which button triggered the callback.
Before I start any OpenGL project, past experience has always taught me to make sure that I can get the basics to compile on my current system before trying to do anything clever. I have once spent countless hours trying to debug an OpenGL project only to find that I was using an old buggy version of FreeGLUT (Which has since improved greatly!). Below is a short code listing of a very basic OpenGL application.
In order to get this to compile we need to link it with 3 libraries: libGL, libGLU and libglut
This code can be compiled by issuing the following command:-
Now when ./simple is run a window should appear with a rotating teapot.
If this has worked, then congratulations on creating your simple OpenGL application, now you can progress onto the fun stuff!