This post was saved / ported from a previous site migration. You may encounter missing images, dead links, and strange formatting. Sorry about that!

Project TreeWars: When is an OpenGL not an OpenGL?

Programming OpenGL C++ TreeWars

So, I was playing around with the ‘sparks’ feature on Google+. Since I’ve been working with OpenGL lately, I made a spark for it. On that spark, I came across this thread, which gave me this advice:

A general rule of thumb is that if a tutorial contains calls to glBegin, glEnd and/or any of the glTexEnv functions then it’s old and you should avoid it.

Now, I wouldn’t generally trust a single person on the Internet with nothing to recommend them, but I’m seeing this advice repeated in several places now that I know to look.

So, all the tutorials I’ve been working with are for very, very old versions of the OpenGL spec, and the functions I’m calling are pretty deprecated; I’ve been learning obsolete tools. To that end, I recommend anyone following this series not use my last post as a jumping-off point for working with OpenGL, or at least know what you’re getting into. Those functions and methods still work, but they’ve been deprecated and eventually graphics cards will probably stop shipping with support for them.

Instead, I found some more modern tutorials and documentation. Luckily, I’m not terribly invested in the way I’m doing things yet; I have maybe 100 lines of OpenGL-related code in my project, and the vast majority of it (that is, all the stuff that isn’t needed for initialization and gamestate changes) is factored into a single file. It should be pretty straightforward to replace it with something better, once I’ve got a handle on the “new way” of doing things.

This exposes a deeper issue, too. There are several different versions of OpenGL: best denoted by their major version numbers (1-4). The most current iterations of each are OpenGL 1.5, 2.1, 3.3, and 4.0. There seem to be tutorials available for all of them. Now, there’s a tradeoff to using one version of OpenGL over the other; newer versions will have less support from other libraries (Linux doesn’t even seem to have OpenGL 3 headers yet). On the other hand, older versions will eventually be deprecated and phased out. Newer versions can also do things older versions couldn’t, although right now I’d be happy just learning the basics.

So, after looking around on the web for a while, I settled on learning OpenGL 2.1 (and the corresponding GLSL 1.2, which we’ll talk about in a moment), while avoiding all of the functions in OpenGL 2 that are deprecated in OpenGL 3. This is the approach that Joe takes in this tutorial series, so what I’m learning will line up well with at least one tutorial on the web. It is also nice because this version is well supported in Linux, while OpenGL 3 support (especially in SDL) is still under development.

Now, there is a huge change between OpenGL 1 and 2. A change so massive that the difference between 1 and 2 dwarfs the differences between 2 and later versions. This change is the move from having a “fixed-function graphics pipeline” to using GLSL, the OpenGL Shader Language. So, what does this mean? Well, in OpenGL 1.5, you tell the graphics card what you want to draw, and some parameters about how you want to draw it, but the details of that process - the functions on the graphics card that handles doing the actual drawing - are hard-coded and unchangeable. With shaders, you get to program those functions yourself, and then your application can send them to the graphics card, compile them, and use them. GLSL is the language the shaders are written in - it looks a lot like C, but it has neat built-in functions for matrix and vector math, and a ton of built-in variables that I haven’t quite worked out yet.

So, I rewrote my rendering engine to use shaders. I followed the tutorial closely, modifying it to fit into my object-oriented C++ code and to fit all the other code I had already painstakingly written. I refactored large sections of my program. This took several hours, during which I couldn’t even compile the program all at once, because so many changes were being made. When I finally got it to compile and run without immediately crashing, this is what I had produced:



I appear to be doing it wrong, as they say around these parts. I have simplified my program so that all it should be doing is displaying a single texture on a simple rectangle. I have no idea what’s wrong here. Is my coordinate system somehow incompatible with my shaders? I don’t think so - I reworked the coordinates to match the tutorial I’ve been using. Are my shaders for drawing a texture simply wrong? Maybe, but there’s not a great way that I can find to get debugging info out of the shaders. Is SDL 1.2 not compatible with GLSL? That’s a decent possibility; testing it will take some time, though.

This is the biggest setback I’ve encountered so far, though, so that’s a pretty good sign. Hopefully, by my next post, we’ll have something better than a black screen to work with.