Sign in to follow this  
RunningInt

Sprite Transparency problem

Recommended Posts

I am implementing sprites using alpha transparency. But there is a problem: The image on the left is the RGB bitmap. I convert this bitmap to ARGB. A pixel has 0 alpha if it is red, full alpha otherwise. The image on the right shows the result of drawing the ARGB bitmap using alpha blending. The problem is the red border around the edge of the sprite. Also notice that the two red lines at the top of the image are actually the feet which have wrapped round! It seems that anti-aliasing is likely causing this problem. I was wondering if there is some simple solution to this.

Share this post


Link to post
Share on other sites
Try playing with this section of code:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0);

basically, mess with the zero, try changing it to a one. and make sure you delete every other blending command first. The lines are caused by texture streching and the wrap around can be fixed by a "GL_CLAMP" (if I remember correctly) instead of GL_WRAP at texture creation. (again if I remember correctly for that constant as well).

Let me know if it works!!

Share this post


Link to post
Share on other sites
Quote:
Original post by RunningInt
It seems that anti-aliasing is likely causing this problem. I was wondering if there is some simple solution to this.


Close, but not quite right. Your problem is texture filtering - red pixels may have an alpha of zero after conversion, but the interpolation at the sprite edges means you get part alpha and part red edges. There are a couple of ways to fix it:

1. Disable texture filtering (or more accurately, switch the MAG_FILTER to NEAREST). This of course means you get a pixely enlargement rather than the smoothed version you've got now.

2. Don't scale the sprite, use the sprite at its proper size. This really is just a way of getting no filtering though.

3. The proper way - ditch the hacky conversion with a colour key and create and load proper RGBA files from disk. Use an image library if you don't want to rewrite yet another png/etc. loader.

To fix the foot wrapping thing, specify CLAMP_TO_EDGE (not CLAMP!) for your GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T parameters.

Share this post


Link to post
Share on other sites
if u disable GL_BLEND your set..

forget glblend. it doesnt exempt the sprite from the zbuffer and in this picture of yours has no function.

By using just glalpha you will get a nice effect.

Drop me ur email ill send u my own 2d application and you can see how nice it looks close up if you use GL_ALPHA and dump GL_BLEND



[Edited by - phantom on November 28, 2005 9:55:41 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
Quote:
Original post by RunningInt
It seems that anti-aliasing is likely causing this problem. I was wondering if there is some simple solution to this.


Close, but not quite right. Your problem is texture filtering - red pixels may have an alpha of zero after conversion, but the interpolation at the sprite edges means you get part alpha and part red edges. There are a couple of ways to fix it:

1. Disable texture filtering (or more accurately, switch the MAG_FILTER to NEAREST). This of course means you get a pixely enlargement rather than the smoothed version you've got now.

2. Don't scale the sprite, use the sprite at its proper size. This really is just a way of getting no filtering though.

3. The proper way - ditch the hacky conversion with a colour key and create and load proper RGBA files from disk. Use an image library if you don't want to rewrite yet another png/etc. loader.

To fix the foot wrapping thing, specify CLAMP_TO_EDGE (not CLAMP!) for your GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T parameters.


Thanks this fixes the problem. I just switched the mag_filter to nearest. I am making a total war like game, so the units can be blocky, and I guess there is a slight speed advantage with using nearest rather than linear.

I am actually loading RGBA files from disk. I have no paint program that can create bitmaps with alpha channel so I made a program to convert an RGB bitmap file into a raw ARGB data file using a key color.

I had to use GL_CLAMP as I don't seem to have CLAMP_TO_EDGE defined. Is there a problem with GL_CLAMP?

Share this post


Link to post
Share on other sites
Quote:
Original post by arbuckle911
Try playing with this section of code:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0);

basically, mess with the zero, try changing it to a one. and make sure you delete every other blending command first. The lines are caused by texture streching and the wrap around can be fixed by a "GL_CLAMP" (if I remember correctly) instead of GL_WRAP at texture creation. (again if I remember correctly for that constant as well).

Let me know if it works!!


The GL_CLAMP helps, but changing the rest of the code doesn't solve the problem. I changed the texture filtering parameters and that solved it.

Share this post


Link to post
Share on other sites
Quote:
Original post by RunningInt
I am actually loading RGBA files from disk. I have no paint program that can create bitmaps with alpha channel so I made a program to convert an RGB bitmap file into a raw ARGB data file using a key color.


To clarify, bmps do not support alpha channels. I would recommend using TGAs instead, as they maintain the image quality and support alpha. If you are looking for a good paint program, I use The Gimp for my textures and image conversion needs. It is free and pretty powerful. There is also a tutorial on nehe.gamedev.net that goes over tga loading (without using RLE compression, search these forums to find some code for that).

Hope this helps.

Share this post


Link to post
Share on other sites
Quote:
Original post by RunningInt
I had to use GL_CLAMP as I don't seem to have CLAMP_TO_EDGE defined. Is there a problem with GL_CLAMP?


CLAMP just clamps to the border colour (ie a single colour for the whole texture) and isn't the right way to go about it. CLAMP_TO_EDGE correctly limits the texture coords to not wrap around as you need. CLAMP_TO_EDGE was introduced in OpenGL 1.2, so it's not in the default 1.1 headers that come with Visual Studio. Check the forum faq for a good overview of using greater than 1.1.

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