PDA

View Full Version : creating a bitmap from the framebuffer



lost hope
08-24-2002, 10:07 PM
I'm currently trying to create a bitmap based on what's in the framebuffer (what would be drawn to screen). I have:



long buffer;
glReadPixels (0, 0, g_width, g_height, GL_COLOR_INDEX, GL_FLOAT, &buffer);

HDC memHandle = CreateCompatibleDC (g_hDC);
HBITMAP dynamicBitmap = CreateBitmap ( g_width, // width of bitmap
g_height, // height of bitmap
1, // number of color planes - this value must be 1
32, // the number of bits required to specify the color of 1 pixel
&buffer); // long void pointer to an array of color data used to set the colors in a rectangle of pixels

if (dynamicBitmap == NULL)
MessageBox(g_hWnd, "Error: bitmap could NOT be created", "ERROR", MB_OK);

Every time this is called, the messagebox alerts me that the bitmap could not be created. I can't seem to figure out why this is? Do I have the parameters set up correctly to read the image from the framebuffer? Any ideas would be greatly appreciated!

08-25-2002, 05:19 AM
Looks like you're not allocating memory for the bitmap to be stored in.

Consult an introductory C/C++ reference and look up memory allocation.

lost hope
08-25-2002, 06:58 AM
I don't think that's my problem. I believe:

HBITMAP hbm = CreateBitmap(width, height, 1, bitsPerPixel, &pixelData);

is the correct code for creating a bitmap -- it does the memory allocation for you. I am more concerned that possibly my glReadPixels code is somehow incorrect. Any other ideas??? Thanks.

Bob
08-25-2002, 07:17 AM
That glReadPixels call is somewhat messed up.

1: I assume you want to grab the whole frame buffer, or at least a part of it (i.e. more than one singe pixel). But the last parameter you pass to glReadPixels, &buffer, is the address of a singe long only. If you want to read say 100 pixels, at least allocate a buffer large enough to hold 100 values. If you want to read 100 pixels and only pass the address of a buffer lagrge enough to hold one value, you will have quite a buffer overflow.

2: You tell OpenGL to save the values as floating point values, yet you pass it the address of a long integer. This can cause sever problems because floating point values and integer values are quite different in how they work on bit level.

lost hope
08-25-2002, 08:19 AM
Thanks for your help, Bob - that clears things up a lot! Also makes me look foolish - hah - but I'm ok with that =) Unfortunately, I'm still having a little difficulity. Since I need to declare an array of floats that's the size of the data I want to grab, I now have:

For a screen resolution of 800x600 at 4 floats per pixel (RGBA), that would be:

800x600x4 = 1920000

But when I declare:
float buffer[1920000];
and then try to use it for the glReadPixels, I get a stack overflow before ever reaching the glReadPixels line (I assume it doesn't like allocating that much memory).

"Unhandled exception at 0x0049f535 in GF_Version_1.02.exe: 0xC00000FD: Stack overflow."

Any thoughts?

lost hope
08-25-2002, 09:23 AM
Ah, I fixed the above problem. So now i have:




glDrawBuffer (GL_BACK);
glReadBuffer (GL_BACK);

static float *buffer = new float [1920000]; // 800x600x4

glReadPixels (0, 0, 800, 600, GL_COLOR_INDEX, GL_FLOAT, buffer);

HBITMAP screenImage = CreateBitmap(800, 600, 1, 32, buffer);


But when I check, screenImage is still NULL, so the bitmap is not being created. Is there anything else that I might be doing wrong?

[This message has been edited by lost hope (edited 08-25-2002).]

[This message has been edited by lost hope (edited 08-25-2002).]

Humus
08-25-2002, 09:28 AM
Originally posted by lost hope:
For a screen resolution of 800x600 at 4 floats per pixel (RGBA), that would be:

800x600x4 = 1920000

But when I declare:
float buffer[1920000];
and then try to use it for the glReadPixels, I get a stack overflow before ever reaching the glReadPixels line (I assume it doesn't like allocating that much memory).

"Unhandled exception at 0x0049f535 in GF_Version_1.02.exe: 0xC00000FD: Stack overflow."

Any thoughts?

Malloc?

lost hope
08-25-2002, 10:30 AM
Yeah, I fixed that using "new" -- that should work as well. It's the post after that which is giving me trouble now.

fringe
08-29-2002, 05:47 AM
Hi,

Shouldn't that be

static float *buffer;
buffer = new etc..
otherwise aren't you setting the thing pointed to by buffer to the memory sopace and so buffer is still NULL.

If this is not the case and it is a problem wth allocation you can catch the error with:
try {
buffer = new long etc
}
catch (bad_alloc xa){
cout << "memory failed";
}

Note: this is copied I have never tried it.

fringe