PDA

View Full Version : Problems with PBOs and frame grabbing



dv
05-19-2007, 03:20 AM
Hi,
I wrote code for grabbing some screenshots using a PBO. it works well - but only with certain window sizes. 800x600 works fine. With 961x713, the PBO contains only black pixels. 1268 x 942 works fine again.

What is going on here? Are there any size restrictions I am unaware of? Already tried 962x714, it gives me a black shot too, so the restriction doesnt seem to be even-sizes-only.

yooyo
05-19-2007, 04:24 AM
Did you try to adjust pack alignment (glPixelStorei call)? Post some code if this hint doesnt help.

GianT
05-19-2007, 04:31 AM
Hi there.

The specs mention glPixelStore, so my guess is the problem is 4 byte (OpenGL's default) padding.
800 % 4 = 0 and 1268 % 4 = 0 !

Try calling glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
before your PBO operations.

Pixel Buffer Objects:
http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt

glPixelStore:
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pixelstore.html

Btw, the other glPixelStore options might let you download only a subrectangle of the texture, in case you need such functionality too.

GianT
05-19-2007, 04:32 AM
Ooops yooyo was faster...
Hope it helps anyway :-)

g0l3m
05-21-2007, 02:41 AM
Just a quick clarification...From what I understood, you need to call glPixelStore once, before you start playing arround with your TexImage calls or PBO calls. You do NOT need to call it everytime you bind a texture or a buffer, right?

So, I'm guessing if this only affects one particular area of your code...it's probably best to have something like:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

/*
lots of code here that does PBO operations and
glBindTexture, glTexSubImage2D, etc.
*/

// set it back to it's default value so you don't mess other things up.
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

Am I right in assuming this? (or do I need to call it more often?).

cheers,
g.

GianT
05-21-2007, 04:13 AM
Yes, you are right.
According to the specs, the GL_UNPACK_ALIGNMENT flag is initialized to 4.

But as said before, you might want to change the GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SKIP_PIXELS values to only download/upload a subrectangle of a given texture/image.

Therefore, i would advise you to call:
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); // Save state
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Maybe some other glPixelStorei calls
and
glPopClientAttrib(); // Back to the previous state

Rather than
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
and
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

g0l3m
05-21-2007, 04:45 AM
sure thing...pushing and popping is much better...
But still, do I need to call all the glPixelStore stuff ONCE, or do I need to call them everytime I bind a texture/buffer?

GianT
05-21-2007, 06:00 AM
Yes, you can call it once.

It is a (client) state, therefore the 'value' remains as it is unless another glPixelStore call on the same flag is made.

If you're sure you only want 1 unpack/pack alignment, then you can call glPixelStore once for all before any operation affected by the related states.