Blending conondrum

Member
Posts: 306
Joined: 2009.03
Post: #1
I have a image thats a small circle which around its borders has a larger very transparent green(190,255,190) circle. When I draw this using the following settings:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Onto a darker green background, the center non transparent part looks fine but the transparent part actually makes the dark green background get darker. Shouldn't it blend the color between the light color and the dark background, based on the transparency, and result in a color somewhere between the 2?
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #2
The filtering has nothing to do with the blending, so the glTexParameteri is not necessary to take into account.

I'm having a hard time envisioning exactly what is happening. What is your glColor4f set to?

I assume you have your blend mode set to modulate, correct? Like glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); It is the default on iPhone, so if you didn't explicitly set it yourself then you can assume it is already set to modulate.

Also, I used to call things transparent when they weren't actually transparent, but somebody corrected me on the usage. Transparent means fully clear. Translucent is the term to use for something which still has some color value or opaqueness to it. So like a partially see-through green would be translucent. The edge of a sprite using an alpha channel where no image shows up at all would be transparent.

A screen shot might be helpful.
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #3
Ill post one. Just a min to prepare.
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #4
http://www.greyhoundgames.com/blend.jpg

You can see a,b,c
A is supposed to be a green lighter then c(the background). A has rgb like 90,255,90 and an alpha thats quite low(so translucent).

C has an rgb(aprox 8,133,8) thats much darker, and the center circle is the same as the outer ring(a), but with a much higher alpha(closer to 1). C is not transparent at all.

I haven't used this before:glTexEnvi should I? Is default ok?
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #5
Are you loading the image using UIImage? If so the alpha is premultiplied and you need to change your blending function to accommodate. Instead of GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA you would use GL_ONE and GL_ONE_MINUS_SRC_ALPHA. Otherwise you are multiplying by the alpha twice on the src fragments and making them too dark.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #6
Oh. Try using GL_ONE, GL_ONE_MINUS_SRC_ALPHA

[edit] Skorche beat me to it.

I missed that you were using GL_SRC_ALPHA until I saw the screenshot...

[edit2] No you don't need to mess with glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); since it's default. There really isn't much use for other modes.
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #7
Ok i tried this. Showing my artist cause it looks very different now so I'll let you know if this is what he expected it to look like. Thanks guys. P.S I tried change from
spriteImage = [UIImage imageNamed:filename].CGImage;
to
spriteImage = [UIImage imageWithContentsOfFile:filename].CGImage;

to save on memory and my textures just draw as pure white. Should I need to change some other render settings based on this? Also is there a downside to this premixed alpha that scorch described? I'm trying to think about how it effects blending in 2d. Should I not be using UIImage?
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #8
Hmm. There seems to be a side effect to this. I was using alpha on my render to pulse this over time using:
Code:
int modulus=(tickNumber+tickOffset)%360;
GLfloat alpha;
if(modulus>=345)
{
    modulus-=345;
    //have it fade in quickly right at the end so its not a sudden change
    alpha=0.0833f+(modulus/15.0f)*0.916f;
}
else
{
    alpha=(360-modulus)/360.f;
}
glColor4f(1, 1, 1, 0.25f+3.0f*alpha/4.0f);
//Draw code

But now its alpha doesn't seem to dim at all as time goes by.
Does using the fixed 1 mean it ignores the alpha I pass in?
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #9
Using GL_ONE, GL_ONE_MINUS_SRC_ALPHA means that the blending equation requires that you need to multiply each color channel by your alpha now, like so:

glColor4f(r * a, g * a, b * a, a);

Other than that little detail, no there isn't really any drawback to using premultiplied alpha on iPhone. On Mac it might be an issue if you need color separated for a shader, but otherwise it's not an issue there either.

> spriteImage = [UIImage imageWithContentsOfFile:filename].CGImage;

If that draws white, are you sure spriteImage isn't NULL?
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #10
Code:
Yeah your right. Well thats odd. Its the same filename as before.
//spriteImage = [UIImage imageNamed:filename].CGImage;
UIImage* temp=[UIImage imageWithContentsOfFile:filename];
if(temp==NULL)
{
    [Logger LogErrorString:[NSString stringWithFormat:@"Null image for file:%s",filename] forID:@"TextureAtlas"];
}
spriteImage = temp.CGImage;

Ill try the alpha thing. Thanks again. You guys are so helpfull.
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #11
Ok i see. The one is fully qualifed, the other is automatically looking in your app. Ill need to find a way to generate the fully qualified path. Thanks again!
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #12
Try something like: [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"]] CGImage];
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #13
UIImage* temp=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"png"]] ;
//UIImage* temp=[UIImage imageWithContentsOfFile:filename];
if(temp==NULL)
{
[Logger LogErrorString:[NSString stringWithFormat:@"Null image for file:%s",filename] forID:@"TextureAtlas"];
}

Still null, but i can probably figure this part out. I got the blending all working and I have to say this is looking much sharper and cleaner. Thanks a ton guys. If my app does well I will buy you each a present Smile
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #14
AnotherJake Wrote:you don't need to mess with glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); since it's default. There really isn't much use for other modes.

On the contrary; understanding TexEnv is the only way to achieve "interesting" effects in ES1.1.
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #15
arekkusu Wrote:On the contrary; understanding TexEnv is the only way to achieve "interesting" effects in ES1.1.

Got any examples handy?
Quote this message in a reply
Post Reply