OpenGL + SDL engine (I)

Disclaimer: this is my very first post ever so feel free to give me feedback about text formatting, english mistakes, my writing or technical questions, thanks.

This particular post is about struggles I went through starting up an engine with OpenGL and SDL lib from the very beginning, but while I was writing the title I realize I could expand a bit more the scope and make a sort of serie (the (I) thing in the title is because of that) posting interesting stuff about the development of the engine.

So, as I said above I’m going to enumerate some issues I find relevant to reveal here for the good of people starting projects with the combo OpenGL-SDL. I would like this helps people facing the same problems I faced and that they don’t stuck in “little things” then have more time for the big things happen.

I will try to order the issues chronologically (that is from early in the development and forward):

dynamic or static linking for the engine

Go static, end.

No, seriously, going static is easier and less painful than dynamic linking. Let’s see why:

Picking dynamic you have to mark every bit that you want to make available in your binary for client usage as exportable, that is each class, type and global variable in your project. Maybe you still don’t realize this means, apart from obvious, that you have to make exportable instances of template classes and, even more, think on STL objects that you might use, clients have to match compiler version that you used, even some STL containers aren’t exportables at all cause use of templates in Its implementation.
Also we have the “dll hell” problem in Windows, this means that every time you install a program, the dll’s that uses go to registry, if new program that uses same dll’s is installed, the current dll’s in registry get overwritten, so maybe the first program would stop running properly cause is not using libraries It meant to use.
Of course you can solve this issues, but maybe It’s not worth the effort given the benefits of dynamic linkage.

In the other hand, going static, you avoid this struggles. Sure your final binary will be bigger and you will have to build project every time you change engine code (unlike how dynamic works) but I think dynamic advantages (shared library among multiple programs and runtime load) don’t serve the purposes of a game engine project.

At the end, you have to decide what It fits better to you though.

Linking sdl is failing

It’s frustrating sometimes linking errors, but If you know how linking works and make a stop to think about it It becomes not that hard to solve them.

Anyway in my case a linking error that made me lose some valuable time trying to fix it is one related to function calls of SDL lib. I couldn’t figure out why I was getting that errors, after a while I set again SDL libs in link settings just in case and It works, so for some reason I messed up configurations initially and I was linking x86 build with x64 libs.

So worth to remember double-check that your build configuration links against correct libraries version.

UNRESPONSIVE WINDOW

If you are getting an unresponsive window like you can’t move it around, neither resize nor affect with the mouse on it in any way then you need to add this lines in some place inside your frame loop:

// Poll input events
SDL_Event e; 
while (SDL_PollEvent(&e)) 
{ 
    if (e.type == SDL_QUIT) 
    {
        // Exit app
    }
}

After this you will recover your window from dead. This loops through each input triggered during the frame so you can handle them.

GLEW functions calls are failing

First, I use GLEW as my wrapper for OpenGL functions calls.

Once I had compilation working again another problem arose: calls to OpenGL functions failed, they wouldn’t do any effect. This is my working order of initialization:

  1. SDL_Init.
  2. Set GL attributes.
  3. SDL_CreateWindow > SDL_CreateContext > SDL_GL_MakeCurrent.
  4. SDL_SetSwapInterval(int).
  5. glewInit().

GLEW needs a GL context created before initializes. Also, if glewInit() fails, next OpenGL calls won’t have any effect or will raise an exception.

Hunting DOWN errors

It’s important to use debbuging tools or specs for solving (or finding lol!) malfunctions on our software.
Sometime maybe you don’t realize all what you have available out there, well, in this case for tracing OpenGL errors in my code I use “glGetError” after error prone calls or in general just for security. This works like a stack so when you call it It will return last error stored.
In SDL side we have “SDL_GetError” which works similar but only store one error (the last one).

I also use RenderDoc which is very handy in order to see easily your drawing pipeline frame-to-frame in a shot: graphic buffers, render context changes, drawcalls, vertex attributes values, primitives output…even you can live-editing shaders (fragment shaders at least). A cool feature that doesn’t work for me is “pixel history” which is a historial drawcalls affecting certain pixel, also debug shader doesn’t work for me neither, I don’t know If It’s something related to the fact that RenderDoc support for OpenGL is relatively new or maybe I’m doing something bad. Anyway I would use “Visual Studio Graphic Debbuger” If It would got support for OpenGL, It works nicely with Direct3D though.

Several objects render visually equal despite they have different draw settings

It happened to me that at render sprites they all had the same shape when each one should have had different size. What was happening is that all shared same VBO for some reason. I found out that the VBO from the last updated sprite was beign binded to all VAO’s in frame because of I didn’t unbind VBO’s once I was done with them. Also is fault of the arquitecture of my drawing pipeline which is: bind VAO > bind and update VBO only If vertex attributes values changed > call glVertexAttribPointer every frame. You can realize that always there is a dangling VBO binded and calling glVertexAttribPointer binds to active VAO :(.

Obviously, I have to rework that flow, for now I fixed the issue by unbind VBO after glVertexAttribPointer, also I check If there is buffer binded before call, would trigger undefined behaviour otherwise.

So the important thing to remember is unbind resources once you are done with them. Always is a bad practise leaving dangling stuff over there, is very likely to be source of malfunctions and hard to figure out the error.

jpg images with ODD WIDTH render ugly

When I tried to draw a sprite with a JPG image It rendered just bad, in grayscale and a diagonal line splited the image in two halves. Doesn’t look like It should and It supposed that engine had proper support for 24bpp RGB format.
I found, digging in OpenGL texture docs, that you can indicate the memory alignment that will use GPU to read pixel data from client memory, by default is 4 byte alignment. This means that the total size in bytes of a row of pixels of your texture must be multiple of 4, It looks bad otherwise.

So for formats with even number of bytes per pixel you have to set 4 bytes alignment.

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

And for textures with odd width and format with odd number of bytes per pixel you have to set 1 byte alignment.

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);