0

In my OpenGL program, I'm loading a 24BPP image with the width of 501. The GL_UNPACK_ALINGMENT parameter is set to 4. They write it shouldn't work because the size of each of the rows which are being uploaded (501*3 = 1503) cannot be divided by 4. However, I can see a normal texture without artifacs when displaying it.

So my code works. I'm considering why to understand this fully and prevent the whole project from getting bugged.

Maybe (?) it works because I'm not just calling glTexImage2D. Instead, at first I'm creating a proper (with dimensions which are powers of two) blank texture, then uploading pixels with glTexSubImage2D.

EDIT:

But do you think it does a sense to write some code like that?

// w - the width of the image
// depth - the depth of the image

bool change_alignment = false;

if (depth != 4 && !is_divisible(w*depth)) // *
{
    change_alignment = true;
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}

// ... now use glTexImage2D

if (change_alingment) glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // set to default

// * - of course we don't even need such a function
// but I wanted to make the code as clear as possible

Hope it should prevent the application from crashing or malfunction?

somnock
  • 147
  • 10

1 Answers1

2

It depends on where your image data is coming from.

The Windows BMP format, for example, enforces a 4-byte row alignment. Indeed, formats like this are exactly why OpenGL has a row-alignment field: because some image formats enforce a row alignment.

So how correct it is to use a 4-byte row alignment on your data depends entirely on how your data is aligned in memory. Some image loaders will automatically align to 4 bytes. And some will not.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Right, silly me. I've forgotten about the source of pixels - I'm using IMG_Load(...) function from the SDL_image library. So it seems that, at least when it comes to bitmaps with 3 bytes per pixel, that it converts it to 32BPP. However I can't be sure it would work like that in any situations (meaning: any loaded formats), right? So I opened its manual but there's no pretty much information about it. I think I should start searching in the libraries which are parts of the SDL_image, such as libpng, libtiff, etc. And if I find out, I still can't be sure how SDL_image uses them. – somnock Aug 30 '13 at 22:39
  • @somnock: No. You're going to have to actually read the documentation for whatever image loader and figure out what the *actual* row alignment is. Just because pixels aren't 4 bytes in size does not mean that it doesn't use a 4-byte row alignment. – Nicol Bolas Aug 30 '13 at 22:59
  • I'm not sure if I understand you correctly. So the actual row alignment depends only on a file format? And where should I look for this information? Could you give me a link for an example? – somnock Aug 30 '13 at 23:08
  • 1
    @somnock: It depends on the file format and whatever loading code you use. You have to look it up. – Nicol Bolas Aug 30 '13 at 23:09
  • Okay, I'm going to check it and if any problem of question occurs, I'll post here. Thanks, man! – somnock Aug 30 '13 at 23:12
  • @Nicol Bolas Is it possible for GL to behave differently depending if pixels are coming from an unpack buffer? I have no issues glTexImage2D-ing a 4byte aligned 24bit image, but if I copy it to a an unpack buffer first, and use the buffer as source, images of certain sizes will come up wrong - upper parts shifted, not the whole diagonally shifted, just the upper parts. After two days, only if I use lesser alignment (and copy the image line by line) it will be ok. Any ideas? Thanks! – user362515 Nov 17 '14 at 09:46