Reputation: 433
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
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
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
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