Search code examples
copenglsdlsdl-image

SDL OpenGL Textures Plagued with Green Tint


I am receiving an unexpected output when attempting to use SDL_image to load an image to an OpenGL texture.

The pertinent parts of my code are:

/**
 * Load texture
 * @param {char*} [filename] File name to load
 * @param {int*} [textw] Texture width pointer (value returned)
 * @param {int*} [texth] Texture height pointer (value returned)
 * @return {GLuint}
 * @link http://sdl.beuc.net/sdl.wiki/OpenGL_Texture_Example
 **/
GLuint LoadTexture(char *filename, int *textw, int *texth) {

    GLuint textureid;
    int mode;

    SDL_Surface *surface = IMG_Load(filename);

    // could not load filename
    if (!surface) {
        return 0;
    }

    // work out what format to tell glTexImage2D to use...
    if (surface->format->BytesPerPixel == 3) { // RGB 24bit
        mode = GL_RGB;
        printf( "GL_RGB\n" );
    } else if (surface->format->BytesPerPixel == 4) { // RGBA 32bit
        mode = GL_RGBA;
        printf( "GL_RGBA\n" );
    } else {
        SDL_FreeSurface(surface);
        return 0;
    }

    // Record texture dimensions
    *textw = surface->w;
    *texth = surface->h;

    // create one texture name
    glGenTextures(1, &textureid);

    // tell opengl to use the generated texture name
    glBindTexture(GL_TEXTURE_2D, textureid);

    // this reads from the sdl surface and puts it into an opengl texture
    glTexImage2D(GL_TEXTURE_2D, 0, mode, surface->w, surface->h, 0, mode, GL_UNSIGNED_BYTE, surface->pixels);

    // these affect how this texture is drawn later on...
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // clean up
    SDL_FreeSurface(surface);

    return textureid;

}

/**
 * Render
 * @param {GLuint} [textureid] OpenGL texture to apply
 **/
void render( textureid ) {

    //Clear color buffer
    glClear( GL_COLOR_BUFFER_BIT );

    //Render quad
    if ( gRenderQuad ) {

        // Set color
        glColor3f(0.0f,1.0f,0.0f); 

        // tell opengl to use the generated texture name
        glBindTexture(GL_TEXTURE_2D, textureid);
        glEnable(GL_TEXTURE_2D);

        // Draw rectangle
        glBegin( GL_QUADS );

        // Top left
        glTexCoord2i(0, 1);
        glVertex2f( -1.0f, -1.0f );

        // Top right
        glTexCoord2i(1, 1);
        glVertex2f( 1.0f, -1.0f );

        // Bottom left
        glTexCoord2i(1, 0);
        glVertex2f( 1.0f, 1.0f );

        // Bottom right
        glTexCoord2i(0, 0);
        glVertex2f( -1.0f, 1.0f );

        glEnd();

        glDisable(GL_TEXTURE_2D );

    }

}

The native image I load is:

input.jpg

But the output is:

output.jpg

From what I have read on another Stack Overflow post, I believe it may be an inverted channel issue, but the proposed solution does not fix my issue. What is wrong with my approach/code?


Solution

  • There is nothing wrong with the loading of the texture as far as I can tell. The reason the output has a green tint is because you set:

    glColor3f(0.0f, 1.0f, 0.0f);
    

    This color value will be multiplied with the color sample from the texture meaning that the red and blue components of the final output will always be 0, which is why the image appears to have a green tint. If you want to use the original texture color you should always set:

    glColor3f(1.0f, 1.0f, 1.0f);