iDevGames Forums
Smoothing edges with alpha mask - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Smoothing edges with alpha mask (/thread-4877.html)

Pages: 1 2


Smoothing edges with alpha mask - McSebi - Oct 25, 2005 11:22 AM

Hello,

there's a graphics glitch when blitting alpha masked textures to my quads in a 2D context. Check out the png image

in Photoshop: [Image: shot2.png]
in my game: [Image: shot1.png]

As you can see the edges are not as smooth as in Photoshop. What could be the cause for this?

My programming environment:

I created a 2D context with glOrtho
I use textured quads with blending glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

I played around with some glTexParameter calls but this makes no difference. Any ideas? If it is necessary to post more source code I'd do that...

Thanks

Sebastian


Smoothing edges with alpha mask - Duane - Oct 25, 2005 12:03 PM

I wouldn't sweat it; I can barely notice a difference.


Smoothing edges with alpha mask - TomorrowPlusX - Oct 25, 2005 01:24 PM

I can't say for certain without seeing your code, but it's very possible that your PNGs have premultiplied alpha -- if you're using Cocoa to load them -- and that might cause the subtle errors you're seeing.

You should dig around for the quicktime image loading code that's floating around here ( I can post my variation on it if you want ). That'll get you raw, non-premultiplied alpha.

The other issue is that Photoshop's PNG export is not too good. It's good for web, but not for OpenGL use. I can't recall what's so bad about it... but google for the SuperPNG photoshop export plugin. It's excellent.


Smoothing edges with alpha mask - OneSadCookie - Oct 25, 2005 02:00 PM

The problem here is that photoshop uses a white background for the image. That means that the white background is visible on semitransparent parts.

There are two ways to get around this, one is to extend the colors of the opaque parts out over the transparent bits, goodness only knows how you can manage that. The other is to premultiply your image and use a premultiplied blending function. If you search the forums you'll find a thread started by Ivan which covers this in more detail.


Smoothing edges with alpha mask - TomorrowPlusX - Oct 25, 2005 02:57 PM

Actually, a perfectly good way to extend the colors of your image is to make a layer behind the image in photoshop that's a merged-copy of the image and run a blur on it, or a maximum/minimum filter to "spread" it out. I do this for the foliage in my game.

But then, if you use the SuperPNG exporter and use a formal alpha channel ( in the channels palette ) this problem won't happen in the first place.


Smoothing edges with alpha mask - Max - Oct 25, 2005 06:17 PM

Hi, I'm the graphic artist of McSebi. Following Tomorrow's advice, I tried SuperPNG to create the PNGs and the results are the same. Jagged edges. I also used Apple's Preview and GraphicConverter. Got the same results. I never thought OpenGL would be so troublesome. And I thought the PlayStation 2 had the the worst graphic technology...


Smoothing edges with alpha mask - Jake - Oct 25, 2005 06:40 PM

What I do is select the image, stroke 1 pixel on the outside with a color matching the outside of the image, and them stroke a 98% clear over top of those pictures. It fixed the premultiplied problem and the halo effect several of us have ran into.

But I seriously couldn't notice the difference between the two images before I read what they were.


Smoothing edges with alpha mask - akb825 - Oct 28, 2005 01:17 AM

This may be a stupid question, but I have to ask: do you have the texture filtering set to GL_LINEAR?

I can barely notice the difference, as well.


Smoothing edges with alpha mask - Max - Oct 28, 2005 11:06 AM

akb825 Wrote:I can barely notice the difference, as well.
The aliased edges are quite noticeable when the game runs in fullscreen mode.


Smoothing edges with alpha mask - akb825 - Oct 28, 2005 12:08 PM

Another thing to check: do you have the GL_TEXTURE_ENV_MODE for that texture set to GL_MODULATE? If it's anti-aliased with alpha, it will carry that alpha to a white quad. I'm not sure if GL_REPLACE does alpha the same way, but I'm pretty sure that GL_DECAL is RGB only.


Smoothing edges with alpha mask - McSebi - Oct 29, 2005 01:16 PM

Ok, thanks for all your input. Here is my code which generates one texture. If I try Fix 1 everything looks great when rendered onto a black background, but all my masks have gone :-) Why that?
Fix 2 is a a bit strange because I draw the image twice but this leads to a better result. It seems drawing the image with Quartz produces the problem.

TRect is a wrapper for CGRect

Code:
    // CGImageRef bitmap; // Created from png using CGImageCreateWithPNGDataProvider

    unsigned char* bitmap_data = new unsigned char[bitmap_datasize];
    
    CGImageAlphaInfo alpha_info = (bitmap.GetDepth() == 32 ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNoneSkipLast);
    CGColorSpaceRef    cg_colorspace = CGColorSpaceCreateDeviceRGB();
    CGContextRef cg_context = CGBitmapContextCreate(bitmap_data, width_, height_, 8, buffer_rowbytes, cg_colorspace, alpha_info);
    
    CGContextSetFillColorSpace(cg_context, cg_colorspace);
    CGContextSetStrokeColorSpace(cg_context, cg_colorspace);
    
// Fix 1 deactivated
//    float comp[] = { 0.0f, 0.0f, 0.0f, 1.0f };
//    CGColorRef color = CGColorCreate(cg_colorspace, comp);
//    CGContextSetFillColorWithColor(cg_context, color);
//    CGContextFillRect(cg_context, TRect(width_, height_));
//    CGContextFlush(cg_context);
    
    TRect rect(pic_width_, pic_height_);
    rect.Move(0, height_ - pic_height_);

    CGContextDrawImage(cg_context, rect, bitmap);

    // Fix 2
    for (int i = 0; i < bitmap_datasize; i += 4)
    {
        bitmap_data[i]        =  0x00;
        bitmap_data[i + 1]    =  0x00;
        bitmap_data[i + 2]    =  0x00;
    }
        
    CGContextDrawImage(cg_context, rect, bitmap);
    // Fix 2 end

    glGenTextures(1, &id_);

    glBindTexture(GL_TEXTURE_2D, id_);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

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

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap_data);



Smoothing edges with alpha mask - akb825 - Oct 29, 2005 07:58 PM

Like I said with my first suggestion, you need linear filtering. Change the GL_NEAREST to GL_LINEAR and it won't be blocky. You will only need to draw it once with that, too.


Smoothing edges with alpha mask - unknown - Oct 29, 2005 08:07 PM

You making a pac man game?


Smoothing edges with alpha mask - Max - Oct 29, 2005 10:42 PM

unknown Wrote:You making a pac man game?
Uh-ho! Busted! LOL
It's Pac the Man, you know, the most popular Pac-Man clone for the Mac. Grin


Smoothing edges with alpha mask - Max - Oct 30, 2005 09:01 AM

akb825 Wrote:Like I said with my first suggestion, you need linear filtering. Change the GL_NEAREST to GL_LINEAR and it won't be blocky. You will only need to draw it once with that, too.
akb825, thanks for the solution. GL_LINEAR works perfectly. However, it blurs the graphics when our video game runs in fullscreen mode. Is there a way to disable the blur?