Gamedev Tip #1 : Fix the Leaks

3212859_f4028dca

This is the first of a series of short articles I plan to post here. The posts will come in the form of tips (or reminders) intended for game developers. These tips will hopefully help the reader avoid common frustrating situations when developing a game.

Let’s start with one that haunts me for years!

Graphics context state leaking will make a project very hard to maintain. So find a way to eliminate the leaks at the beginning, when you initially design your engine.

At first this might seem like overengineering, since your first few lines of rendering code will go smoothly without leak management. But during the project’s lifetime there will be lots of things to add and remove here and there. Every time you try to add a new feature in graphics, you are going to break something else. And then the nightmare starts … or the detective story if you will 🙂 Try to solve the mystery of a lost state in a couple of thousands lines of code

Possible solutions:

  • Create a function SetDefaultGraphicsState() and call it whenever you enter a new function that draws something and/or
  • Create a couple of Save/LoadGraphicsState() functions

These should be enough to guarantee a consistent state in your rendering context. You could also design these functions to be smart and check if it’s needed or not to do an API call. For example if they need to disable blending, they could first check if blending was already disabled and if it was, avoid the function call.

But I suspect a good driver might also do this check before communicating with the graphics hardware anyway.

Advertisements

3 thoughts on “Gamedev Tip #1 : Fix the Leaks

  1. SetDefaultGraphicsState will work if you only intend to go through your 3D engine to draw anything, but will not help in integrating it with other code that might use OpenGL directly.

    I’m leaning towards the lightweight framework approach for my latest 3D engine designs, which means that rendering doesn’t neceserily always go through my library, so my functions must take care to leave OpenGL state the way they found it.

    The second idea of save/load states is much better, but it’s not general enough. For instance it won’t work with nested calls to your drawing functions.

    I think that the best way to handle the issue of state creep is to have a state stack, which fortunately is already provided by OpenGL.

    Before changing any state just call glPushAttrib which can be instructed to push only the relevant state attributes through a set of bitflags so it won’t have to spend time to push everything if you’re not going to change it, then at the end just call glPopAttrib.

    Random example from my recent 3d engine… texture::set_filter changes texture filtering for the OpenGL texture corresponding to that instance of my optional texture class. To do that, it needs to bind the OpenGL texture to make changes to it, however it’s not intended that this should affect the current texture. so it does:

    glPushAttrib(GL_TEXTURE_BIT);
    glBindTexture(textype, tid);
    glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, min);
    glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, mag);
    glPopAttrib();

    Similarly my post-effect overlay function changes a lot of stuff like the current projection and modelview matrices in order to show a fullscreen quad, disables lighting, makes sure we’re not drawing polygons in wireframe mode, enables blending and so on… so it first does:

    glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_CURRENT_BIT | GL_POLYGON_BIT);

    and when it’s finished it just calls glPopAttrib() and everything is back to normal.

  2. Good to know 🙂 OpenGL rocks (I have to study the API better sometime).

    Also I think there is some state management functionality in DirectX too, but not a state stack though. I think directx provides state buffers that reside in video memory and can be enabled with a single call.

    Edit: Was that the mythical Overlay function from 3dengfx? I still use a mutation of this function in conspiracies 2 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s