Sign in to follow this  
gcsaba2

Transparent images - HOW?

Recommended Posts

Hello, I have been trying to make an image transparent for the last 5 hours and it simple doesn't work! I've been looking all over the Internet, read NeHe's tutorial and some other examples how to use blending... I've even talked over IRC where a guy told me a way that would work 100%... but it didn't work... So could someone please explain this to me step-by-step? Please don't say just "use blending" or "use alpha channels" cause I've tried all that and it didn't work. What I actually want is this: I have a simple image, let's say something like this: I want the pink color to be transparent. I actually want to use many pictures like this, and they will all contain pink and I want them to be transparent as well. Simply said, I want to establish pink as a transparent color and not think about it anymore. I don't want to blend it 50% or something, I want it to be 100% transparent. I've tried using a PNG image like the one I posted here. It has alpha channel which says that pink is 100% transparent. For example, if you see the tree's background as white, then it means your browser has already translated the pink color into transparent. OK so I've tried not using blending and using a simple image like this, and it didn't work... I tried using blending, and setting the clearColor to be pink (255,0,255) I tried setting glColor3f(1.0f, 0.0f, 1.0f) this didn't work either. In some cases the image was not transparent at all. In some cases it was blended so-so. In some cases it was not visible at all. In one case I managed to make pink a transparent color, but then I used another image which contained blue and other colors, and it immediately failed. I tried using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBlendFunc(GL_SRC_ALPHA, GL_ONE) glBlendFunc(GL_SRC_ALPHA, GL_ZERO) and lots of other combinations... So can someone explain this to me how this works? Perhaps a very, very simple program which just loads 1 image and makes it transparent? Thanks, Csaba

Share this post


Link to post
Share on other sites
You seem to incorrectly assume that the alpha channel has something to do with the pink color. Actually, alpha 0 will make any color transparent, and the RGB value has nothing to do with the opacity/transparency of a pixel.

In your loader, you should replace any pink pixel's alpha value with 0, if you want to emulate color-keying the pink out of the images.

Another (and better) option is to load an image which actually has an alpha channel in it's pixel data, and just drop the colorkeying idea altogether.

I don't remember the actual OpenGL procedure for setting alpha blending, but the concept is as follows:

Source color blend factor = source alpha * source color;
Destination color blend factor = (1-source alpha) * destination color;
Blend operation = additive;

This way, the source and destination color channels get linearly interpolated by the alpha channel contained in the source, thus making the source color data more "visible" when the alpha value nears 1 and more transparent when it nears 0.

EDIT:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //set the blending factors
glEnable(GL_BLEND); //enable blending

Share this post


Link to post
Share on other sites
Here's what you want to do:

Write a simple function to convert all 'pink' pixels to an alpha value of zero. Something like this will do:


GLuint CreateAlphaTexture(byte r, byte g, byte b, unsigned short w, unsigned short h, GLubyte *data)
{
int size = w*h*3;
GLubyte *adata = NULL;
adata = new GLubyte[size+(size/3)];
int pos=0;
GLuint tex;

for(int a=0; a < size; a += 3)
{
adata[pos] = data[a];
adata[pos+1] = data[a+1];
adata[pos+2] = data[a+2];
if(data[a] == r && data[a+1] == g && data[a+2] == b)
adata[pos+3] = 0;
else
adata[pos+3] = 255;
pos += 4;
}

glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, adata);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

if(adata != NULL)
delete[] adata;

return tex;
}




Now that the proper alpha values are set overtop the 'pink' pixels, you can now enable alpha testing, which will prevent the pixels with a lower alpha value from being drawn:


glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL, 0.6f); // Tweak the second value as necessary




Hope that helps.

Share this post


Link to post
Share on other sites
Quote:
Original post by HopeDagger
Here's what you want to do:

Write a simple function to convert all 'pink' pixels to an alpha value of zero. Something like this will do:

*** Source Snippet Removed ***

Now that the proper alpha values are set overtop the 'pink' pixels, you can now enable alpha testing, which will prevent the pixels with a lower alpha value from being drawn:

*** Source Snippet Removed ***

Hope that helps.


That works great! Thanks!
There are still some minor problems with converting the code to Java but I think this will really do it for me [grin]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this