user10363171
user10363171

Reputation:

Texture not showing correctly?

I am trying to display a JPG texture using OpenGL, but I have some problems. This is the important part of my code:

unsigned char* data = stbi_load("resources/triangle.jpg", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}

The JPG file that I am trying to load can be downloaded here. It works with certain JPG files but not this one, so it is clearly something regarding the formatting - but what and why?

This is how the texture is displayed

Upvotes: 1

Views: 189

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

It works with certain JPG files but not this one, so it is clearly something regarding the formatting - but what and why?

By default OpenGL assumes that the size of each row of an image is aligned 4 bytes.

This is because the GL_UNPACK_ALIGNMENT parameter by default is 4.

Since the image has 3 color channels (because its a JPG), and is tightly packed the size of a row of the image may not be aligned to 4 bytes. Note if the width of an image would by 4, then it would be aligned to 4 bytes, because 4 * 3 = 12 bytes. But if the width would be 5, it wouldn't be aligned to 4, because 5 * 3 = 15 bytes.

This cause that the rows of the image seems to be misplaced. Set the GL_UNPACK_ALIGNMENT to 1, to solve your issue:

glPixelStore( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);

Further note, you are assuming that the image has 3 color channels, because of the GL_RGB format parameter in glTexImage2D. In this case this works, because of the JPG file format. stbi_load returns the number of color channels contained in the image buffer (nrChannels).
Take respect on it, by either using GL_RGB or GL_RGBA for the format parameter, somehow like that:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
    nrChannels == 3 ? GL_RGB : GL_RGBA,
    GL_UNSIGNED_BYTE, data);

Upvotes: 1

Related Questions