iaskdumbstuff
iaskdumbstuff

Reputation: 433

glTexImage2D crashing program

Here is my code:

int h, w, c;
unsigned char* img = stbi_load("bricks.jpg", &w, &h, &c, 0);
if (img == NULL) {
    printf("Error in loading the image\n");
}
printf("Image loaded with width of %d, height of %d, and %d channels", w, h, c);

GLuint txtr = 0;
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &txtr);
glBindTexture(GL_TEXTURE_2D, txtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);

For some reason, my window no longer opens when I un-comment glTexImage2D. w and h are both calculated by stbi_load, which is a part of the stb_image.h library. Where is my mistake here?

Upvotes: 3

Views: 3576

Answers (3)

Rabbid76
Rabbid76

Reputation: 210918

The jpg image consists of 3 color channels (GL_RGB) and stbi_load returns a tightly packed image. The number of bytes of the of the image buffer (img) is w * h * 3.

By default OpenGL assumes that the start 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, and is tightly packed the start of a row is possibly misaligned.
So the size of the image buffer is assumed to by aligne(w*3, 4) * h.

The crash is caused, because glTexImage2D. access the buffer out of bounds.

Change the the GL_UNPACK_ALIGNMENT parameter to 1, before specifying the two-dimensional texture image (glTexImage2D):

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);

Note, glPixelStorei sets a global state, which is kept until it is changed again.

Upvotes: 7

Deedee Megadoodoo
Deedee Megadoodoo

Reputation: 863

I suppose the source of your problem here is a mismatch between number of channels in the pixmap loaded by stbi_load method and number of channels in the original image format you passed as 7'th argument into glTexImage2D method. Basically, glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, WIDTH, HEIGHT, 0, SOURCE_FORMAT, SOURCE_TYPE, SOURCE_PIXMAP_DATA) causes OpenGL to create a 2D texture that has internal pixel representation of INTERNAL_FORMAT, that has is WIDTH pixels wide and HEIGH pixels high from the source pixmap SOURCE_PIXMAP_DATA which consists of a sequence of pixels encoded in SOURCE_FORMAT, SOURCE_TYPE.

I think stbi_load read a 3 channel, 24 byte per pixel (GL_RGB, GL_BYTE) image from a file, but you tell OpenGL to treat the source pixmap as 4 channel, 32 byte per pixel (GL_RGBA, GL_BYTE) image. It's incorrect.

You should either check c variable before specifying the source pixmap format or request stbi_load to load 4-color-channel image by assigning 4 to its 4'th argument (damn, a lot of 4's here).

Upvotes: 1

iaskdumbstuff
iaskdumbstuff

Reputation: 433

Well, the problem was apparently with GL_RGBA. I changed it to GL_RGB, and the program no longer crashes; though, I do wonder why it was crashing in the first place.

Upvotes: 0

Related Questions