PDA

View Full Version : How to read buffers from upper left corner to bottom of the image?



Zoran Zivkovic
04-08-2001, 02:46 AM
glReadPixels reads always from lower left corner upwards. I am working under Windows and the rest of my application likes it the other way around (upper left corner as a the origin).

Is there a solution?

I could maybe play with projection matrix (idea how?) and horizontaly invert the scene, render it to the back buffer and read it from there. This introduces less overhead than reading the pixels and inverting them myself (at least if there is GL hardware support). But still i woud like it faster for my real-time applications. I there something in OpenGL itself to make it read the buffers the other way around?

Deiussum
04-08-2001, 06:22 AM
The math calculation for inverting the coordinates is pretty simple.

newY = (height - oldY - 1);

Just use that calculation to determine which area to read before you actually read. No real need to invert ALL the pixels.

[This message has been edited by Deiussum (edited 04-08-2001).]

Deiussum
04-08-2001, 06:32 AM
On second thought... there could be reasons you'd need to invert them first, but you don't really say what you are doing with the data so in your case it's not clear what would really be the best way to go about it. http://www.opengl.org/discussion_boards/ubb/smile.gif

My initial thought was that you were just trying to get a rectangle at given screen coordinates. You probably meant that you need the returned data to be in a top-down format rather than bottom-up, right?

In that case it's hard to say what would be the best way w/o knowing more about what you are doing. glReadPixels is generally slow, so I'm guessing that's going to slow you down more than however you invert the data.

Zoran Zivkovic
04-08-2001, 11:12 PM
glReadPixels might be slow but it is the only way to read the buffers. Further, I want to read the whole image in top down order.
Example: I use windows stuff to save the image, then windows wants the data in reverse order than GL gives.
Here the speed is not important but I also use it in some other ways that are speed critical. And you are right, if I invert the image myself makes the whole thing tooo slow.

I just hope that there is a trick to do it fast.

j
04-09-2001, 06:38 AM
There are scaling settings for glReadPixels.

glPixelZoom(zoomx, zoomy). Just set the vertical scale to -1.0f and the horizontal scale to 1.0f and it should work (I think). This is going to slow down glReadPixels even more, though.

j

fathom
04-09-2001, 01:29 PM
You could do a series of glReadPixels, each getting one scanline. Do this in the order you want scanline wise and you won't need to do any byte copying on your own.

Zoran Zivkovic
04-09-2001, 11:26 PM
Thanx for trying to help!
glZoomPixel seamed as a good idea but unfortunately it doesn't have any influence on glReadPixels.
Scanning line by line might be used but the overhead seems still too big. My solution by drawing the inverted scene in the back buffer and reading from there is maybe better (at least it is done by the hardware).

Deiussum
04-11-2001, 04:50 AM
What is it you are using the resulting data for? If you are using it in a way that just gets things pixel by pixel, simply invert your coordinates there...

I don't know how big your scene is, but rendering it twice just to get an inverted image seems pretty extreme to me.

Is this something you have to do each frame?

This is just a guess, but I'm thinking that using a single glReadPixels for the whole thing and inverting it yourself would be faster than using a glReadPixels for each scanline. If a single glReadPixels is slow, I can only imagine how slow 600 would be (in 800x600 mode for example.)

Inverting the data yourself is just a simple pair of nested for loops.

for (y=0;y<height/2;x++)
{
for (x=0;x<width;x++)
{
int topIndex = getTopIndex;
int bottomIndex = getBottomIndex;

swap(data[topIndex], data[bottomIndex]);
}
}

In the end, I think the only way you are really going to know what is faster for your situation is to benchmark the different methods.