I draw a screen with OpenGL commands. And I must save this screen to .bmp or .png format. But I can't do it. I am using glReadpixels but I can't do continue. How can I save this drawing in c++ with OpenGL?
-
1It isn't really opengl's job to save files. You need some other library for that, such as libjpeg. – Vaughn Cato Mar 11 '12 at 17:36
4 Answers
Here it comes! you must include WinGDI.h (which i think the GL will do it!)
void SaveAsBMP(const char *fileName)
{
FILE *file;
unsigned long imageSize;
GLbyte *data=NULL;
GLint viewPort[4];
GLenum lastBuffer;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
bmfh.bfType='MB';
bmfh.bfReserved1=0;
bmfh.bfReserved2=0;
bmfh.bfOffBits=54;
glGetIntegerv(GL_VIEWPORT,viewPort);
imageSize=((viewPort[2]+((4-(viewPort[2]%4))%4))*viewPort[3]*3)+2;
bmfh.bfSize=imageSize+sizeof(bmfh)+sizeof(bmih);
data=(GLbyte*)malloc(imageSize);
glPixelStorei(GL_PACK_ALIGNMENT,4);
glPixelStorei(GL_PACK_ROW_LENGTH,0);
glPixelStorei(GL_PACK_SKIP_ROWS,0);
glPixelStorei(GL_PACK_SKIP_PIXELS,0);
glPixelStorei(GL_PACK_SWAP_BYTES,1);
glGetIntegerv(GL_READ_BUFFER,(GLint*)&lastBuffer);
glReadBuffer(GL_FRONT);
glReadPixels(0,0,viewPort[2],viewPort[3],GL_BGR,GL_UNSIGNED_BYTE,data);
data[imageSize-1]=0;
data[imageSize-2]=0;
glReadBuffer(lastBuffer);
file=fopen(fileName,"wb");
bmih.biSize=40;
bmih.biWidth=viewPort[2];
bmih.biHeight=viewPort[3];
bmih.biPlanes=1;
bmih.biBitCount=24;
bmih.biCompression=0;
bmih.biSizeImage=imageSize;
bmih.biXPelsPerMeter=45089;
bmih.biYPelsPerMeter=45089;
bmih.biClrUsed=0;
bmih.biClrImportant=0;
fwrite(&bmfh,sizeof(bmfh),1,file);
fwrite(&bmih,sizeof(bmih),1,file);
fwrite(data,imageSize,1,file);
free(data);
fclose(file);
}

- 246
- 8
- 27
One thing need to be fixed at:
bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
Otherwise, some picture edit can not open correctly.

- 51
- 3
Unless you're feeling particularly ambitious (or perhaps masochistic) you probably want to use a library like DevIL that already supports this. The current version can load and/or save in both PNG and BMP formats, along with a few dozen others.
Compared to something like IJG, this is oriented much more heavily toward working with OpenGL or DirectX (e.g., it can load a file fairly directly into an texture or vice versa).

- 476,176
- 80
- 629
- 1,111
-
-
You'd use DevIL along with OpenGL. It's possible to read pixels back with glReadPixels, then put a header on the front, insert padding as needed, and save as a BMP file, but OpenGL doesn't provide anything to support it directly. – Jerry Coffin Mar 11 '12 at 18:23
-
-
I've linked to the site where you can download it. It includes pretty good documentation. If you run into specific problems, it would probably be better to ask about them in separate questions. – Jerry Coffin Mar 11 '12 at 18:34
-
I know you're asking for raster formats, but an indirect way would be to first output vector graphics through gl2ps (http://www.geuz.org/gl2ps/). Examples of usage are provided with the package and on the site (http://www.geuz.org/gl2ps/#tth_sEc3).
Then, the vector output can be converted to the format of your choice using another tool (Inkscape, Image/GraphicsMagick, etc.) or library. An added benefit is you can convert to bitmaps of any resolution in the future.

- 131
- 1