Skip to main content
GameDev.net gamedev.net
🔒 Locked

glReadPixels*

Started by Jehsup Jun 25, 2004 at 2:20 PM 11 replies 5.9k views
Original Post
Jehsup
Jehsup
Hello all, I am working on a Perlin noise generator. I got it working and displaying my image. When I go to save the image however using glReadPixels I get an image that has its row order swapped. In other words the bottom of the original image is the top of the one that I write out. I do: //heightmap (the array to hold my data) is declared as follows: BYTE heightmap[IMAGE_SIZE*IMAGE_SIZE]; glReadPixels( 0, 0, IMAGE_SIZE, IMAGE_SIZE, GL_RED, GL_UNSIGNED_BYTE, &heightmap); I have played with glPixelStore and it settings over and over and nothing has any effect? There is an option for skipping rows and pixels, and for swapping the pack and unpack byte orders, but NOTHING has any effect. Any ideas? Thanks in advance. J
Monder
Monder
The first two arguments of glReadPixels specify the lower-left corner of the region you want to grab, so try using something like:

glReadPixels( 0, SCREEN_HEIGHT, IMAGE_SIZE, IMAGE_SIZE, GL_RED, GL_UNSIGNED_BYTE, &heightmap);


instead.
Jehsup
Jehsup
I am not saving it as a bitmap, just in raw form. I just create an array of values[IMAGE_SIZE][IMAGE_SIZE] and assign grayscale color to each point via a Perlion noise function I got off of the internet.

I then draw the image to the screen.

I then read the pixels when save is pressed as follows (this includes the snipped originally posted above:

void SaveImageAsRaw( char* filename )
{
glReadPixels( 0, 0, IMAGE_SIZE, IMAGE_SIZE, GL_RED, GL_UNSIGNED_BYTE, &heightmap);


//write them out
FILE* pFile;

//open a file to write to
pFile= fopen( filename, "wb" );


//write the data to the file
fwrite( heightmap, 1, IMAGE_SIZE*IMAGE_SIZE, pFile );

//Close the file
fclose( pFile );



}

Monder: When I tried what you suggested I get a completely white image written out.
GKW
GKW
Width and Heigth can't be negative. You basically have three options:

1 - Flip the image with a bunch of memory copying CPU side
2 - Use glPixelZoom which is very slow
3 - Copy the framebuffer to a texture and redraw the image back to the framebuffer on a quad then use glReadPixels
"... we should have such an empire for liberty as she has never surveyed since the creation ..."Thomas Jefferson
GKW
GKW
GL_INVALID_VALUE is set if either width or height is negative.
"... we should have such an empire for liberty as she has never surveyed since the creation ..."Thomas Jefferson
Null and Void
Null and Void
Quote:
Original post by GKW
2 - Use glPixelZoom which is very slow

That's not always true. With certain implementations ("drivers") X and Y zoom factors of -1.0 are special-cased so that they're relatively quick. I think the specific example I'm recalling is NVidia's implementation, but other vendors may do this as well. Still, if it's a performance critical section of code I wouldn't necessarily trust glPixelZoom to always be quick :).
GKW
GKW
I have a nvidia card. It is over 20 times slower to use glPixelZoom than to use render-to-texture to flip a 32bit image.
"... we should have such an empire for liberty as she has never surveyed since the creation ..."Thomas Jefferson
GameCat
GameCat
In OpenGL pixel 0,0 is in the bottom left corner (math standard) but most bitmap formats have (0,0) at the *top* left corner (tv standard). Since you usually write out one scanline at a time anyway to get the pitch right, just write the scnalines in reversed order and you'll be fine.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.