PDA

View Full Version : Saving screen to bitmap



David
09-28-2000, 02:11 AM
Hi, I need to save the screen to a bitmap,
Ive found the bitmap format out, but my program just doesnt work, does anyone know of any source code (in OpenGL) which does this?


Thanks

danoon
09-28-2000, 05:33 AM
Use glReadPixels to grab the bits from the screen.

::glReadPixels(0,0,nWindowWidth,nWindowHeight,GL_R GB,GL_UNSIGNED_BYTE,pRGB);

David
09-28-2000, 05:37 AM
I use glreadpixels

I am using a 24 bit format, and I think it is to do with the way I am formatting my data (currently I am simply packing 3bytes (RGB) one after the other, is this right?

(I use the two MS structures beforehand)

danoon
09-28-2000, 05:46 AM
I'm very familiar with the frustations of getting bitmaps to write to disk correctly.

I'm sorry that this code is not going to work for you right out of the box because I use a custom file class that is similar to CArchive, but hopefully it will help. Pay special attention to how each line in the bitmap has to be dword aligned at the fact that you can't just right a memory structure (BITMAPFILEHEADER) directly to disk because it is dword aligned in memory.

void SaveBitmap(int width, int height, unsigned char* pRGB)
{
int dwWidth=(width*24+31)/32*4; // get dword aligned width
BITMAPFILEHEADER bmfHeader={0};
BITMAPINFO bmi={0};
int i,j;

// open file

bmfHeader.bfType=((unsigned short) ('M' << 8) | 'B');
bmfHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(B ITMAPINFO)+height*dwWidth;
bmfHeader.bfOffBits=54;

//Need to write out each field separately because of memory alignment issues
//
//file.Write((char *)&bmfHeader, 14);
file << bmfHeader.bfType;
file << bmfHeader.bfSize;
file << bmfHeader.bfReserved1;
file << bmfHeader.bfReserved2;
file << bmfHeader.bfOffBits;

bmi.bmiHeader.biSize=40;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=24
bmi.bmiHeader.biHeight=height;
bmi.bmiHeader.biWidth=width;

file.Write(&bmi,40);

for (i=0;i<height;i++)
{
for (j=0;j<width;j++)
{
file << pRGB[i*width*3+j*3+2];
file << pRGB[i*width*3+j*3+1];
file << pRGB[i*width*3+j*3];
}
for (j=width*3;j<dwWidth;j++)
file << (unsigned char)0;
}
}

El Jefe
09-28-2000, 06:25 AM
Dunno, does it have to be a .bmp format? I wrote a simple tga routine and it works fine...if nothing else, you could probably model a .bmp screenshot function after it though....good luck.

+------------------------+
int t = 18 + win.sx * win.sy * 3;
unsigned char *buffer=(unsigned char *)malloc(t);
unsigned char temp;

// create the header
memset(buffer,0,18);

buffer[2] = 2;// uncompressed
buffer[12] = win.sx & 255;
buffer[13] = win.sx >> 8;
buffer[14] = win.sy & 255;
buffer[15] = win.sy >> 8;
buffer[16] = 24; // bit depth

glReadPixels( 0, 0, win.sx, win.sy, GL_RGB, GL_UNSIGNED_BYTE, buffer + 18 );

// swap rgb to bgr
for ( i = 18; i < t; i += 3 )
{
temp = buffer[i];
buffer[i] = buffer[i + 2];
buffer[i + 2] = temp;
}

// write buffer out here....

[This message has been edited by El Jefe (edited 09-28-2000).]

David
09-28-2000, 06:32 AM
Ive done it at last! Thanks for the replies they certainly helped me find out my problem. I had some dodgy code when I was reading in the pixels, but looking at yours, I realised that I could read them all in at once (much faster as well)

Thanks!!
David

rts
09-28-2000, 09:13 AM
Originally posted by David:
Hi, I need to save the screen to a bitmap,


Look here:

http://www.opengl.org/discussion_boards/ubb/Forum4/HTML/000065.html

and see my post... three functions that
write the framebuffer in PPM, TGA or
BMP format

Hope this helps