PDA

View Full Version : glReadPixels and bitmap



Pat
09-04-2002, 10:08 AM
I'm using glReadPixels to get the image data from my OpenGL window. I'm then creating a Windows bitmap file with this data. It works fine other than the image is upside down. I've been reordering the array of bytes returned from the glReadPixels before saving the bitmap.

Is there an easy way to force OpenGL return the array in the order that I would like (top down) instead of (bottom to top)?

Thanks

Korval
09-04-2002, 10:27 AM
I could have sworn that Windows .bmp files were upside-down.

In any case, to answer your question, the most you could do is render your image upside down. Invert it with a y-axis flip and reverse your backface culling.

Asgard
09-04-2002, 10:32 AM
The only way I can think of, is to render the scene upsidedown...but that's probably not what you want. glReadPixels is defined to start reading from the lower-left corner, as that is the standard behaviour in OpenGL.
So the only way to get the image the right side up, is to flip it after glReadPixels.

Asgard
09-04-2002, 10:35 AM
Actually, coming to think of it, Korval is right. BMP files are upsidedown in Windows. So glReadPixels actually gives you the image the way you want it for saving it into a BMP file.
Cheers.

Pat
09-04-2002, 10:42 AM
Thanks. I must be doing something else incorrectly.

DjAttitude
09-04-2002, 10:46 AM
I must note that openGL gives the format in RGB, unless you are using extensions. You'll need to swap the format to BGR, which is what BMP format is.

Altho the code can do with some optimizing (asm) this will do the work for you...



void swap(char &a, char &b){
a^=b^=a^=b;
}

void RGBtoBGR(void *pixels, uint32 size)
{
char *p=(char *)pixels;
for(uint32 i=0;i<size;i+=3) swap(p[i],p[i+2]);
}

Pat
09-04-2002, 11:35 AM
I don't think the last reply is correct.

I believe RGB is the expected byte order and the scan lines in the bitmap are stored
from bottom up according to the documentation that I found.

pbrown
09-05-2002, 02:47 AM
Originally posted by Pat:
I'm using glReadPixels to get the image data from my OpenGL window. I'm then creating a Windows bitmap file with this data. It works fine other than the image is upside down. I've been reordering the array of bytes returned from the glReadPixels before saving the bitmap.

Is there an easy way to force OpenGL return the array in the order that I would like (top down) instead of (bottom to top)?

Thanks

One way to do this that might work, but which I wouldn't recommend is to screw around with PixelStore. Pass a pointer to the last row in your buffer and set the PACK_ROW_STRIDE to a negative value. So when the buffer is read back, the driver will read the first (bottommost) row back to the memory you point to. Then the next row will be read back to pointer + PACK_ROW_STRIDE (which will be less than pointer).

I think it is OK to pass negative values into PixelStore, but I'm not 100% positive. This approach would probably also guarantee that a driver won't use its fastest ReadPixels implementation.

rIO
09-05-2002, 03:04 AM
Regarding the component swap, as far as I know it's true that BMP format has red and blue component swapped....
When I wrote my hown bmp loader (aux functions suxx) I ahd to swap theese components to get the right colours.

Is it not possible to pass a negative value to the readpixel command ?

Thaellin
09-05-2002, 03:50 AM
BMP 24bpp pixel order: BGR

Upside-down image returned from ReadPixels: set the 'height' field in the bitmap info header to '-(height)'.

Important note: each scanline in the bitmap file needs to be padded to the nearest quadword boundary.

Enjoy,
-- Jeff