Menu

SDL OpenGL + FreeImage = swapped red / blue

Help
2010-02-09
2012-10-31
  • James Russell

    James Russell - 2010-02-09

    Hey guys.

    So this is a problem that has plagued our 2-man dev team for a while now. When
    we originally started using FreeImage a year or so ago for our project using
    SDL OpenGL for rendering, we discovered that images loaded by FreeImage, of
    any type we used (jpg, png, tga), seems to swap the red and blue channels upon
    loading.

    We have fixed this, as of right now, by telling OpenGL that a RGB image is BGR
    and RGBA image is BGRA, which works fine. It is still nagging at me, however.

    We load the image with the following code.

    void FreeImageBitmap::Load()
    {   
        this->bitmap = FreeImage_Load(FreeImage_GetFIFFromFilename(this->path.c_str()), this->path.c_str());
    
        if (this->bitmap == ZNULL)
            return false;
    
        this->height = FreeImage_GetHeight(this->bitmap);
        this->width = FreeImage_GetWidth(this->bitmap);
    
        switch(FreeImage_GetColorType(this->bitmap))
        {
        case FIC_RGB:
            this->model = CM_RGB;
                                               this->channels = 3;
            break;
        case FIC_RGBALPHA:
            this->model = CM_RGBA;
                                               this->channels = 4;
            break;
        default:
            this->model = CM_UNDEFINED;
                                               return false;
        }
    
        return true;    
    }
    

    We then try to load the image as a texture using the following code...

        GLenum cmodel;
    
        /* setup color model */
        //TODO: This is backwards; need to know why.
        switch (this->material->texture->img->model)
        {
            case CM_RGB : cmodel = GL_BGR;
                        break;
            case CM_RGBA : cmodel = GL_BGRA;
                        break;
            case CM_UNDEFINED :
            default: //LOG_EVENT invalid color model... this is a bad place to find this out.
                    break;
        }
    
    //OpenGL Stuff Happens...
    
            // no mipmaps
            glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexImage2D(GL_TEXTURE_2D,
                         0,
                         this->material->texture->img->channels,
                         this->material->texture->img->width,
                         this->material->texture->img->height,
                         0,
                         cmodel,
                         GL_UNSIGNED_BYTE,
                         (void*)FreeImage_GetBits(((FreeImageBitmap*)this->material->texture->img)->bitmap));
    

    As you can see, RGB is put in as GLenum BGR, and RGBA as BGRA. That causes the
    correct behavior - otherwise we have swapped red/blue channels.

    I had found a bug report about swapped channels that mentioned it being
    existent for an earlier version, so I updated FreeImage, but no dice.

    Any ideas? Couldn't find the answer through searching.

    Thanks,
    James

     
  • Mihail Naydenov

    Mihail Naydenov - 2010-02-11

    Hum, I have no experience using FI + OpenGL, but in general you can swap R-B
    in the freeimage.h line 104 and recompile...
    I have done this myself, though there is some problems(inconsistencies) still
    (now, IIRC, images with alpha are swapped).

     
  • Hervé Drolon

    Hervé Drolon - 2010-02-13

    I don't know if this can help, but there's a OpenGL sample in the distribution
    that show how to display an image with OpenGL. See
    FreeImage\Examples\OpenGL\TextureManager

     

Log in to post a comment.

MongoDB Logo MongoDB