3
votes

I'm creating a 2d application for the iPad using OpenGL ES and having some issue drawing transparent images.

I'm using png-24 images with full transparency. I'm also changing the color of some of some textures, which are white with some areas transparent or semi-transparent. That all works fine.

When I try to set the alpha value of one of these textures, however, it's not working quite right. The colors are much too saturated, and if the alpha value = 0, i'm left with a white rather than transparent image over a light grey background. When such a transparent image is over a dark image, the dark image becomes a color similar to color of the transparent image.

I've tried a many parameter combinations of the glTexEnvi and glBlendFunc with no success.

I'm not very knowledgable about OpenGL, so if anyone has any suggestions, that would be great. Let me know if there are any details that would help.

Thanks.


Here is the initialization of OpenGL

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    glDisable(GL_DEPTH_TEST);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_BLEND);
4

4 Answers

4
votes

Sounds like you told OpenGL your texture had premultiplied alpha, but it actually doesn't.

What parameters are you using for glBlendFunc?

More explanation of pre-multiplied alpha

2
votes

Thanks for everyone's input. I think I've found a solution.

The problem was that the textures had premultiplied alpha but the polygons the textures are being applied to did not. With glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); and glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); in place all I had to do was manually multiply the R, G, and B color values of the polygons by the alpha value so that everything is essentially using premultiplied alpha and renders consistently.

I'm not sure if this is the most efficient solution, but it seems to work perfectly so far and it was just a matter of adding a few lines of code to my image rendering class to update the color values whenever the opacity is changed.

wooo

1
votes
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ALPHA);

This is not valid, are you checking GL errors? Check the glTexEnv man page to see the valid values:

http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml

GL_ALPHA is not a texture function, the valid texture functions are GL_ADD, GL_MODULATE, GL_DECAL, GL_BLEND, GL_REPLACE, and GL_COMBINE.

You might want to replace that GL_ALPHA with GL_MODULATE so you can control the texture alpha with the vertex color (glColor). This mode multiplies the texture with the vertex color.

0
votes

Chances are if you're using a 24-bit PNG, you wont have the alpha channel. Try converting to a 32-bit PNG and editing the alpha channel. Alternatively you can convert from 24bit to 32bit yourself and generate the alpha channel from the image data (eg: by chroma-keying).

Then use glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); or glBlendFunc(GL_SRC_ALPHA, GL_ONE); if you want additive blending.