Search code examples
c++visual-studioopenglglut

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?


Solution

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