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?
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.