Taking screenshots: How to?

Is there any good way to take screenshots under OpenGL? As for the collateral, I’m using Borland Builder 5.5 without IDE on a Win 95 system and programming without any additional library (except of course OpenGL and windows, but no GLUT)

Thanks!

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

Can’t you just type alt-[Print Screen key] (or something like that) and the screen image will be copied to the clipboard?

If you want to take screenshots without help from outside (system, screenshot utility), read back the frame buffer with glReadPixels() and export the read back data in some image file format (TGA is easy to export).

Here’s a screenshot function I’ve done. It’ll save it as a 24bit bmp file.

bool screenshot(char *fileName){
static unsigned char header[54] = {
0x42, 0x4D, 0x36, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

unsigned char *pixels = (unsigned char *) malloc(Xres * Yres * 3);
((unsigned __int16 *) header)[ 9] = Xres;
((unsigned __int16 *) header)[11] = Yres;

glReadPixels(0,0,Xres,Yres,GL_RGB,GL_UNSIGNED_BYTE,pixels);

unsigned char temp;
for (unsigned int i = 0; i < Xres * Yres * 3; i += 3){
temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}

HANDLE FileHandle;
unsigned long Size;

if (fileName == NULL){
char file[256];
i = 0;
do {
sprintf(file,“Screenshot%d.bmp”,i);
FileHandle = CreateFile(file,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
i++;
} while (FileHandle == INVALID_HANDLE_VALUE);
} else {
FileHandle = CreateFile(fileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (FileHandle == INVALID_HANDLE_VALUE) return false;
}

WriteFile(FileHandle,header,sizeof(header),&Size,NULL);
WriteFile(FileHandle,pixels,Xres * Yres * 3,&Size,NULL);

CloseHandle(FileHandle);

free(pixels);
return true;
}

The code below exports in TGA format

void
TakeScreenshot(void)
{
unsigned char *buffer;
char filename[50];
int w = gState->windowWidth;
int h = gState->windowHeight;
int buf_size = HEADER_SIZE + (w * h * 3);
int i;
unsigned char temp;
FILE *out_file;

// open file for output
if (!(out_file = fopen(“my_screenshot”, “wb”)))
{
return;
}

// allocate mem to read from frame buf
if (!(buffer = (unsigned char *) calloc(1, buf_size)))
{
return;
}

// set header info
buffer[2] = 2; // uncompressed
buffer[12] = w & 255;
buffer[13] = w >> 8;
buffer[14] = h & 255;
buffer[15] = h >> 8;
buffer[16] = 24; // 24 bits per pix

// read frame buf
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer + HEADER_SIZE);

// RGB to BGR
for (i = HEADER_SIZE; i < buf_size; i += 3)
{
temp = buffer[i];
buffer[i] = buffer[i + 2];
buffer[i + 2] = temp;
}

// write header + color buf to file
fwrite(buffer, sizeof(unsigned char), buf_size, out_file);

// cleanup
fclose(out_file);
free(buffer);
}

how I can know the right HEADER_SIZE?

Originally posted by 0m4r:
how I can know the right HEADER_SIZE?

HEADER_SIZE for TGA is 18 as far as I know. And it seems to work apart from the little glitch I have placed up on my web site at http://programming.swangen.co.uk/opengl/glReadPixels.asp. Hopefully someone can shed a light on why it is working like that :wink:

Tina

Tina, why dont you post your code… If you did, I did not see it…

Originally posted by mancha:
Tina, why dont you post your code… If you did, I did not see it…

Thanks for the reply mancha. I just managed to figure out the cause. Well confirm my suspicions anyway. Took me long enough :wink:

I was using MFC Classes with OpenGL and I must have been missing something MFC specific. Still alot to learn in that area so dropped the program there and introduced the screengrab and file save into a normal Win32 OpenGL program with no problems. Well, apart from the code only works for fixed fonts only. Oh well. It’ll do for now.

The code is relatively big to post here so I will place both the MFC and Win32 versions onto my site for all and sundry to figure out soon…

Tina

I saw your post on what the error was too… The clientrect function returns the drawing portion only; it does not include title bar or anything… So use that for the picture size…

[This message has been edited by mancha (edited 08-27-2002).]