Here you have it in all its glory, and as a bonus you get to see some unsafe C# in action! I gotta say, SDL makes this stuff easy and hard at the same time: Easy because the documentation is amazing and everything has examples. Hard, because there were a couple nasty surprises to figure out, especially figuring out when asking OpenGL for "RGBA" pixels you have to tell SDL to save in ABGR, plus the mandatory OpenGL vertical flip, of course
At first glance, it seemed the culprit was that glGetTexImage. Everyone will tell you that transferring pixel data from the GPU to the CPU is super slow and will block everything, stall rendering, and probably will make you late for dinner too. Because suddenly we're all hardware people and everyone knows "pci express is super slow", or something.
Anyway, after a quick detour into Pixel Buffer Objects, which apparently can speed this up, but not as much as one would hope, I had an epiphany: What if I actually profile this?
Well, turns out 100% of the time is taken by that SavePNG function in SDL_Image and the actual data transfer from the GPU to CPU is negligible... Why does SavePNG take so long (about 250ms)? Don't know don't care, but now we have a solution. We run it in a separate thread and let the magic of parallelism do the rest. Since we have the pixel data in an array that nobody else knows about (something something *ownership*), we can do all the SDL stuff on the side while the game continues running. I'll also take the opportunity to appreciate how easy it was to do all this "low level" manipulation mostly-safely (no formal proof for you
Remember kids: Always profile first
*EDIT*: Oops! And there was a tiny memory leak in there. I forgor to destroy the SDL surface. Guess I'm not used to cleaning up after myself ^^' Serves me right for boasting about how (un)safe this stuff was.