Search code examples
c++openglgraphicstexturesstb-image

Error when loading image with stb


I am attempting to load the following image:

enter image description here

As a texture for the stanford Dragon. The result however is as follows: enter image description here

I have read that other people have had issues with this due to either not binding the textures correctly or using the wrong number of components when loading a texture. I think that I don't have either of those issues as I am both checking for the format of the image and binding the texture. I have managed to get other images to load correctly, so this seems like there is an issue specific to this image (I am not saying the image is corrupted, rather that something about this image is slightly different to the other images I ahve tried).

The code I am using to initialize the texture is as follows:

//Main constructor
Texture::Texture(string file_path, GLuint t_target)
{
    //Change the coordinate system of the image
    stbi_set_flip_vertically_on_load(true);
    int numComponents;
    //Load the pixel data of the image
    void *data = stbi_load(file_path.c_str(), &width, &height, &numComponents, 0);
    if (data == nullptr)//Error check
    {
        cerr << "Error when loading texture from file: " + file_path << endl;

        Log::record_log(
            string(80, '!') +
            "\nError when loading texture from file: " + file_path + "\n" +
            string(80, '!')
        );
        exit(EXIT_FAILURE);
    }
    //Create the texture OpenGL object
    target = t_target;
    glGenTextures(1, &textureID);
    glBindTexture(target, textureID);
    //Name the texture
    glObjectLabel(GL_TEXTURE, textureID, -1,
        ("\"" + extract_name(file_path) +"\"").c_str());
    //Set the color format
    color_format = numComponents == 3 ? GL_RGB : GL_RGBA;

    glTexImage2D(target, 0, color_format, width, height, 0,
        color_format, GL_UNSIGNED_BYTE, data);
    //Set the texture parameters of the image
    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    //free the memory
    stbi_image_free(data);
    //Create a debug notification event
    char name[100];
    glGetObjectLabel(GL_TEXTURE, textureID, 100, NULL, name);
    string message = "Succesfully created texture: " + string(name) +
        ". Bound to target: " + textureTargetEnumToString(target);
    glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0,
        GL_DEBUG_SEVERITY_NOTIFICATION, message.size(), message.c_str());
}

Solution

  • A JPEG eh? Probably no alpha channel then. And 894 pixels wide isn't quite evenly divisible by 4.

    Double-check if you're hitting the numComponents == 3 case and if so, make sure GL_UNPACK_ALIGNMENT is set to 1 (default 4) with glPixelStorei() before your glTexImage2D() call.