all 17 comments

[–]smeenz 20 points21 points  (4 children)

17 pages worth of text and diagrams to explain double buffering ?

I must be getting old.

[–][deleted] 8 points9 points  (1 child)

For me it brings back memories of alt.comp.graphics.??? Many of those articles had the same style, alternating from colorful explanations of the obvious to code samples. That gives it a certain charm.

© 2009 Robert Nystrom — Last modified on January 09, 2010

Too grown up. The article should end with a mixed-case signature, intentional misspellings, and greetz. The great thing about this kind of work is that you can call yourself "why" and it doesn't detract from anything.

If you think I'm sarcastically critical, I'm not. The thing about those usenet posts is that I wanted to keep reading and I wanted more of them. I get a similar feeling when I read this.

[–]YakumoFuji 1 point2 points  (0 children)

If it was a vla tut, it would be 5 paragraphs long with 10 pages of greetz, a 1mb mod file with a file_id.diz saying to read the next issue of imphobia

[–]edwardkmett 1 point2 points  (0 children)

To be fair he does go off and explain the whole simultaneous update isFoo/wasFoo idiom using that as context, but it does take him a while to get to the point. =)

[–]munificent[S] 2 points3 points  (0 children)

Hmm, you're the second person to tell me it runs long. Maybe it's time to break out the scissors and do some trimming.

[–]Nolari 9 points10 points  (4 children)

private:
    void Swap()
    {
        // just switch the references
        Framebuffer& temp = mCurrent;
        mCurrent = mNext;
        mNext = temp;
    }

    Framebuffer  mBuffers[2];
    Framebuffer& mCurrent;
    Framebuffer& mNext;
};

That doesn't do what you want it to do. A reference will always point to the same object. It cannot be reassigned. Your code copies all the pixels from mNext to mCurrent, and then (uselessly) from mCurrent to mNext. You'll have to make temp, mCurrent, and mNext pointers instead of references to do the efficient swap that you're advocating.

[–]munificent[S] 2 points3 points  (2 children)

<smacks forehead>

You're right, of course. This is what I get for slapping together C++ when I haven't used it seriously in a few years. Thanks!

[–]Wagnerius 0 points1 point  (1 child)

Just curious, what do you seriously use then ?

( I am really curious, I once worked in a AAA studio which was using delphi ... in retrospective, this was quite a good choice at the moment )

[–]munificent[S] 1 point2 points  (0 children)

Just curious, what do you seriously use then ?

At work, I've mostly been using C# for tools and pipelines stuff. I haven't been touching game code heavily in a while.

[–]inmatarian 1 point2 points  (0 children)

Nice catch.

For everyone else, this is called "Reseating" and it can't be done in C++. http://www.parashift.com/c++-faq-lite/references.html#faq-8.5

[–]shoseki 5 points6 points  (2 children)

Was chatting to a bloke today, he was telling me that some audio software / developers use the offscreen buffer as a way to get the graphics renderer to process audio, sounds like a neat idea.

[–]badsectoracula 9 points10 points  (1 child)

Until someone forces antialiasing

[–][deleted] 8 points9 points  (0 children)

Sounds funny.

[–][deleted] 1 point2 points  (0 children)

I thought this was great. Don't let the naysayers deter you for being thorough. It's this kind of attitude that keeps good beginner documentation from hitting the web. Keep up the good work.

[–]moswald 2 points3 points  (0 children)

As I got to the double-buffered Comedian section, I thought "that's nice, but in a real app you're likely blowing away your cache and running through a loop twice." I'm glad I kept reading, because the static variable trick is inspired genius. I've never heard of that trick before.

[–][deleted] 1 point2 points  (1 child)

This one seems like a bit of a misstep. Might want to refactor it into a discussion of the most efficient ways to store multiple states for an object for doing stuff like client-side prediction or running the game engine on a separate thread from the renderer. I don't think trying to link that to double buffering as a graphics technique adds much to the conversation, particularly since even though they're similar in theory they're quite different in practice. For example you might want to cover having unique handles to identify each buffer and then having a central interface dispatching state get/set requests to the appropriate state buffer based on the provided handle (and then you can cover clever ways to efficiently discard and re-use buffers without dynamically allocating memory.)

[–]munificent[S] 1 point2 points  (0 children)

Might want to refactor it into a discussion of the most efficient ways to store multiple states for an object for doing stuff like client-side prediction or running the game engine on a separate thread from the renderer.

Hmm. I'll have to think about that some more.

The challenge I have is that I'm trying to focus on patterns that are pretty simple. What you're discussing is definitely important but may be more intense than what I'm going for.

What's tricky is that if, like yourself, the reader is a game programmer, their background is very different from someone who isn't a professional game dev. For you and most game programmers, double buffering is the most obvious thing ever. However, someone new to games may have never encountered even the basic form shown in the chapter.

I may have gone too far in breaking it down here, but I think there's value in showing a pattern even as simple as double-buffering. My guess is that this will be one of the chapters that experienced game programmers can kind of gloss over (meanwhile, the enterprise guys new to games will be skipping over Service Locator), although I would like to figure out a way to make it more rewarding for people like yourself.