What does glPixelStore() do?

I’m rendering few bitmaps on the screen and without calling glPixelStore(), I get weird looking bitmaps.

This code,

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

and this code,

glPixelStorei(GL_UNPACK_ALIGNMENT, 2);

does exact same thing. What’s the difference between these two codes?

According to official docs, there is no difference if your bitmaps` width is even.
TL;DR: this invocation tells OGL to assume each row of application-supplied byte data to be aligned, since aligned memory reads tend to be faster than unaligned.
1 means no alignment, 2 — each row starts at even address, 4 — each row starts at the address divisible by 4, etc…

Thanks for the answer but I still don’t get it.

1 means no alignment, 2 - each row starts at even address

What is it mean by no alignment and ‘each row starts at even address’?

Also, what’s the difference between GL_UNPACK_ALIGNMENT and GL_PACK_ALIGNMENT?

they seems to do the same job.

Memory addresses are just numbers. An even address means that the address is a multiple of two.

Arrays declared as variables or allocated with e.g. malloc() or “new” can safely be assumed to be aligned to a 4-byte boundary (i.e. the address of the first byte of data in the array will be a multiple of 4). Thus you only need to concern yourself with GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT if the number of bytes per row isn’t also a multiple of 4.

The GL_PACK_* settings affect operations which transfer data from OpenGL to the application (e.g. glReadPixels()). The GL_UNPACK_* settings affect operations which transfer data from the application to OpenGL (e.g. glTexImage2D()).

Data in application memory is considered “packed”, data held within the OpenGL implementation is considered “unpacked” (i.e. where the implementation can get at it).

Ok, let me get this right.

According to this article, Chapter 8 - OpenGL Programming Guide

  1. Different computers(hardwares) stores arrays in different ways such as 2 byte, 4 byte and 8 byte alignment. So to control the byte alignment, I use glPixelstore() to set the specific byte alignment.

GLubyte foo[1] = {
	0xc0
};

since GLubyte is an unsigned char which is only 1 byte long, I can call

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

which makes sense because my array is 1 byte long each. But this is where i’m confused.

glPixelStorei(GL_UNPACK_ALIGNMENT, 2);

How come above code works fine if unsigned char is only 1 byte long?

Or am I just completely misunderstanding something?

  1. If my array was something like
unsigned long int x[] = {5, 2, 6};

then I don’t need to call glPixelStorei because glPixelStorei’s default value is 4…

Sorry if this is bit long.

Size and alignment are different things.

Suppose that you have texture data with GL_RGB format (3 bytes per component) and a width of 123, with no padding between rows (i.e. the first byte of the first pixel of one row immediately follows the last byte of the last pixel of the previous row). The stride between rows will be 3*123 = 369 bytes. Note that 369 is not a multiple of 2 or 4.

If the first row of the texture data starts at an address which is a multiple of 4, the second row won’t.

If GL_UNPACK_ALIGNMENT is 4, and you try to upload the texture data with glTexImage2D(), the implementation will round the length of each row up to the next multiple of 4 (i.e. 372 bytes).

Unless you have an 8-bit CPU (and I don’t think there are any 8-bit systems which support OpenGL), the CPU will typically read and write memory in “words” (typically 32 or 64 bits) rather than bytes. For this reason, it’s more efficient to align data to a multiple of the word size.

Because aligning data in this way is so common, OpenGL has GL_UNPACK_ALIGNMENT and GL_PACK_ALIGNMENT, which allow you to say “if I ask you to read data, it will be aligned to a multiple of 2/4/8 bytes; if I ask you to write data, I want it aligned to a multiple of 2/4/8 bytes”.

The compiler will typically align x to a multiple of 4 bytes (or more), and each element will typically be either 4 or 8 bytes, so each element will be aligned to a multiple of 4 bytes (or more).

I’m sorry but I have one more question.

GLubyte foo[4] = {
	0xc0, 0xc0, 0xc0, 0xc0
};

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

This makes sense because foo is consist of 4 values which are 1 byte long each. So foo has stride of 1.

long int ham[4] = {
	0xc0, 0xc0, 0xc0, 0xc0
};

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

This makes sense because ham is consist of 4 values that are 4 bytes long each. So ham’s stride is 4.

GLubyte foo[4] = {
	0xc0, 0xc0, 0xc0, 0xc0
};

glPixelStorei(GL_UNPACK_ALIGNMENT, 2);

This works but i’m bit confused. Foo’s stride is 1 but how come 2 works fine?

and finally,

GLubyte foo[3] = {
	0xc0, 0xc0, 0xc0
};

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

Is this valid code? thanks and again sorry for the long question…

The pack/unpack alignments apply to reading and writing pixel rectangles. The spacing between rows has to be a multiple of the alignment.