Screenshot of opengl window

Need to take simple screenshot of the opengl window and save it to file.
Please, post example code in c++.

just use glReadPixels to retrieve raw data.
http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml

Ok, i get the data. Now how to save it to file? I’m sorry, i’m absolutely zero in c++.

I use this method to write a PPM file, maybe it can help you


void Image::writePPM( std::ostream& out ) {
	// Escreve o cabeçalho do arquivo
	out << "P6" << endl;
	out << width << ' ' << height << endl;
	out << "255" << endl;

	// Escreve os valores ajustados para o intervalo [0,255]
	// O valor do canal aplha é ignorado
	for ( unsigned int idx = 0; idx < this->getNumberOfPixels(); idx++ ) {

		unsigned int iRed = (unsigned int) ( 256 * raster[idx].r );
		unsigned int iGreen = (unsigned int) ( 256 * raster[idx].g );
		unsigned int iBlue = (unsigned int) ( 256 * raster[idx].b );

		if ( iRed > 255 )
			iRed = 255;
		if ( iGreen > 255 )
			iGreen = 255;
		if ( iBlue > 255 )
			iBlue = 255;

		unsigned char red = (unsigned char) iRed;
		unsigned char green = (unsigned char) iGreen;
		unsigned char blue = (unsigned char) iBlue;

		out.put( red );
		out.put( green );
		out.put( blue );
	}
}

Comments are in portuguese, but you can take the idea

I succeeded make a screenshot with SDL library:

SDL_Surface * image = SDL_CreateRGBSurface(SDL_SWSURFACE, current_w, current_h, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);

glReadBuffer(GL_FRONT);
glReadPixels(0, 0, current_w, current_h, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);

SDL_SaveBMP(image, "pic.bmp");
SDL_FreeSurface(image);

But it was all black))) My size but all black. Why and how to fix it?

UPD: I found - need to remove glReadBuffer(GL_FRONT). But now screenshot is upside down… How to fix IT?)

The system’s origin of an OpenGL window is in the bottom left corner, while a bitmap has its origin in the upper left corner.

All you need to do is to invert the y coords of your pixels.
How this can be done with SDL? I have no idea.

I found:

int index;
void* temp_row;
int height_div_2;

temp_row = (void *)malloc(image->pitch);
if(NULL == temp_row)
{
	SDL_SetError("Not enough memory for image inversion");
}
height_div_2 = (int) (image->h * .5);
for(index = 0; index < height_div_2; index++)    
{
	memcpy((Uint8 *)temp_row,(Uint8 *)(image->pixels) + image->pitch * index, image->pitch);
	memcpy((Uint8 *)(image->pixels) + image->pitch * index, (Uint8 *)(image->pixels) + image->pitch * (image->h - index-1), image->pitch);
	memcpy((Uint8 *)(image->pixels) + image->pitch * (image->h - index-1), temp_row, image->pitch);
}
free(temp_row); 

Now all works fine. Thanks for help, McLeary.

No problem