alpha not working in SDL image

Apprentice
Posts: 17
Joined: 2007.02
Post: #1
I'm trying to make an SDL-based game using SDL image for texturing, but I can't seem to render PNGs and TGAs correctly. I created 3 different textures in different programs, one in Blender, another in Photoshop, and the last in Flash. All the textures have alpha channels, but in my application instead of seeing an image with a transparent background I see the image with a colored background the same color as the background (as in Blender) or as the secondary painting color (Photoshop and Flash).

I am using code based on http://gpwiki.org/index.php/SDL:Tutorial...ith_OpenGL (the key difference is that I'm using IMG_Load instead of SDL_LoadBMP). I'm using SDL image version 2.1, is it not capable of rendering transparent pixels or does the problem lie in the code?
Quote this message in a reply
Member
Posts: 111
Joined: 2002.06
Post: #2
I haven't tried the code in the tutorial you linked to, but I have gotten texture loading with SDL_image to work on Mac OS X with the following settings:

Internal Format: GL_RGBA8
Format: GL_RGBA
Type: GL_UNSIGNED_INT_8_8_8_8

Just because an image has an alpha channel doesn't mean OpenGL is going to automatically draw a transparent background properly. You have to tell OpenGL not to draw the transparent pixels. Telling OpenGL not to draw transparent pixels requires two function calls. The first function call is glAlphaFunc(). The following call tells OpenGL to draw pixels with an alpha value greater than 0:

Code:
glAlphaFunc(GL_GREATER, 0);

The second function to call is glEnable(). You must enable the alpha test.

Code:
glEnable(GL_ALPHA_TEST);

Mark Szymczyk
http://www.meandmark.com
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #3
szymczyk has got the right idea: It's most likely that alpha is properly loaded, but it's not used properly. Using RGBA instead of RGB is a good first step. However, Alpha testing will give you rather wonky results unless you know exactly what you are doing (or using 1-to-1 texel to pixel mapping). Blending is the way to go.

Code:
glEnable(GL_BLEND) ;
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

- Sohta
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2007.02
Post: #4
I tried both and neither worked. Now nothing but the black background shows up.
Quote this message in a reply
Member
Posts: 111
Joined: 2002.06
Post: #5
You might have an endian issue. Try setting the internal format to GL_UNSIGNED_INT_8_8_8_8_REV and see if that helps.

Another thing to try is changing the environment mode using the glTexEnvf() function.

Code:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);

There are four modes: GL_REPLACE, GL_BLEND, GL_DECAL, and GL_MODULATE. GL_REPLACE is the default mode.

If those two suggestions don't work, I don't know what to tell you.

Mark Szymczyk
http://www.meandmark.com
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
szymczyk Wrote:There are four modes: GL_REPLACE, GL_BLEND, GL_DECAL, and GL_MODULATE. GL_REPLACE is the default mode.

No, GL_MODULATE is (much more useful, and should not need changing).
Quote this message in a reply
Member
Posts: 320
Joined: 2003.06
Post: #7
It would be useful to see some code, and perhaps some example images if you can put them up somewhere. The first thing I would do however is check that SDL_Surface actually has 4 channels. Try printing the nOfColors variable, that way you at least can rule out the possibility of the images being RGB.

Chopper, iSight Screensavers, DuckDuckDuck: http://majicjungle.com
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2007.02
Post: #8
Now I tried using GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, and glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, with all 4 modes). Every time it ether messed up the colors or did nothing. Also I checked and the image is definitely RGBA. I guess discribing my problem isn't good enough anymore so here's some of my code.
Code:
// this is the function that draws a tile. It is called by a function called //generateMap().
void createTile(SDL_Surface *from, int x, int y)
{
    // get the number of channels in the SDL surface
    nOfColors = from->format->BytesPerPixel;
    if (nOfColors == 4)     // contains an alpha channel
    {
        if (from->format->Rmask == 0x000000ff)
            texture_format = GL_RGBA;
            else
                    texture_format = GL_BGRA;
    } else if (nOfColors == 3)     // no alpha channel
    {
        if (from->format->Rmask == 0x000000ff)
            texture_format = GL_RGB;
        else
            texture_format = GL_BGR;
        } else {
        printf("warning: the image is not truecolor..  this will probably break\n");
        // this error should not go unhandled
    }
    glGenTextures( 1, &texture);
    
    glBindTexture(GL_TEXTURE_2D, texture);
    
    // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    
    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, 4, from->w, from->h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, from->pixels );
    
    glTranslatef(x, y, 0.0f);
    
    glBegin(GL_QUADS);
    
    glTexCoord2f(0.0, 0.0); glVertex2f(0.0f, 0.0f);
    glTexCoord2f(1.0, 0.0); glVertex2f(100.0f, 0.0f);
    glTexCoord2f(1.0, 1.0); glVertex2f(100.0f, 100.0f);
    glTexCoord2f(0.0, 1.0); glVertex2f(0.0f, 100.0f);
    
    glEnd();
    
    // delete the textures
    glDeleteTextures(1, &texture);
}

// this contains all the startup OGL code. it is called in main.cpp to be executed
void interface(int windowWidth, int windowHeight)
{
    cMap mapOb;

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glClearColor(0.0, 0.0, 0.0, 0);
    //glClearDepth(1.0f);
    //glDepthFunc(GL_LEQUAL);
    //glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0);
    glEnable(GL_TEXTURE_2D);
        
    // this is the file viewport where the user sees all of the elements that makes their game. x=20% y=80%
    glViewport(0, 0, windowWidth, windowHeight);
    
    // Set the projection matrix to ortho view
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, windowWidth >> 1, windowHeight >> 1, 0);
    
    glPushMatrix();
    
    //createTile(grass, 1, 6);
    mapOb.generateMap(8, 8);
    
    glPopMatrix();
    
    glFlush();

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    
}
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Pasting an image with alpha mask on a texture Najdorf 10 6,042 Jun 24, 2008 03:23 PM
Last Post: Najdorf
  png without alpha fine, png with alpha, nothing dave05 6 7,009 Jun 11, 2005 10:31 AM
Last Post: dave05
  Image Scrolling, Not Working Snibril 5 3,099 Aug 18, 2003 08:16 PM
Last Post: aaronsullivan