Home > OS >  How can i fix this displayer image error in ImGui?
How can i fix this displayer image error in ImGui?

Time:07-12

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.

enter image description here

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);
             
  • Related