I currently use this to take a screenshot:
Code:
int w=gState->GetWindowWidth();
int h=gState->GetWindowHeight();
#define kNumColorComponents 3 //RGB=3, RGBA=4
SDL_Surface temp = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8kNumColorComponents, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 );
char * pixels = new char [kNumColorComponents * w * h];
if(kNumColorComponents==3)
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
else if(kNumColorComponents==4)
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
SDL_LockSurface( temp );
for (int i = 0 ; i < h ; i++)
std::memcpy( ((char ) temp->pixels) + temp->pitch * i, pixels + kNumColorComponents * w * (h-i - 1), wkNumColorComponents );
SDL_UnlockSurface( temp );
delete [] pixels;
SDL_SaveBMP(temp, (char*)Path.c_str());
SDL_FreeSurface(temp);
It is missing some functionality. I would like to be able to resize the screenshot to specific input dimensions, but I’m not sure the best way to do that. Also, a huge improvement would be to be able to save as a JPG or other compressed format. A BMP will save to a large file. My application window is set to 1084x813 and the output file as a BMP is about 2.6 MB, because 1084x813x3=2,643,930. I couldn’t think of any good reason to save the Alpha values for a screenshot. With basic JPG compression, the same image is about 16% of that. When I get some time, I will make sure saving to a JPEG is possible. People expect to be able to save to that image format, and rightly so in my opinion.
With regard to your specific request, it seems like you want more of a mirror than a proper screenshot. You could just re-render the screen in its own viewport, or you could make a SDL_Surface of the window and use that. Both have disadvantages and advantages. With a full re-render, you could remove specific things you wanted to remove, like parts of the interface. With just ripping an SDL_Surface from the window, you wouldn’t have to re-render everything.