I have started to make a program with ImGui and opengl, besides stb for the images. When I show the default image of the demo it appears correctly. While if I load one using stb and link it with opengl and then display it, it looks like this. I do not know what it could be. Btw loading the same image as icon for the window works just fine.
FUNCTION TO LOAD THE IMAGE:
bool FeatherGUI::loadImage(std::string _path) {
//Load texture from file
CurrentImage.data = stbi_load(_path.c_str(), &CurrentImage.width, &CurrentImage.height, &CurrentImage.channels, 3);
if (!CurrentImage.data) {
fprintf(stderr, "Cannot load image '%s'\n", _path.c_str());
CurrentImage.loaded = true;
return false;
}
// Create a OpenGL texture identifier and binding
glGenTextures(1, &CurrentImage.texture);
glBindTexture(GL_TEXTURE_2D, CurrentImage.texture);
// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Upload pixels into texture
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, CurrentImage.width, CurrentImage.height, 0, GL_RGB, GL_UNSIGNED_BYTE, CurrentImage.data);
stbi_image_free(CurrentImage.data);
CurrentImage.loaded = true;
return true;
}
FUNCTION TO CREATE THE GUI:
void FeatherGUI::BuildGUI() {
using namespace ImGui;
Begin("Imagen Displayer");
Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / GetIO().Framerate, GetIO().Framerate);
if (!CurrentImage.loaded) {
//load image
if (!loadImage("B:/naranja.png")) {
Text("Error loading image");
}
}
//Show CurrentImage data in ImGui
if (CurrentImage.loaded) {
Text("------------------------------------------------");
Text("Identifier = %p", CurrentImage.texture);
Text("Size = %d x %d", CurrentImage.width, CurrentImage.height);
Text("Channels: %d", CurrentImage.channels);
}
//Show CurrentImage in ImGui
if (CurrentImage.data != NULL) {
Image((void*)(intptr_t)CurrentImage.texture, ImVec2(CurrentImage.width, CurrentImage.height));
}
End();
}
CodePudding user response:
By default OpenGL assumes that the start of each row of an image is aligned to 4 bytes, because the GL_UNPACK_ALIGNMENT
parameter by default is 4. Since the image has 3 color channels (GL_RGB
), and is tightly packed the size of a row of the image is not aligned to 4 bytes, when 3*CurrentImage.width
is not divisible by 4. Therefore GL_UNPACK_ALIGNMENT
has to be set to 1, before specifying the texture image with glTexImage2D
:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, CurrentImage.width, CurrentImage.height, 0,
GL_RGB, GL_UNSIGNED_BYTE, CurrentImage.data);