How can I load a PNG without premultiplied alpha?

Prime
Unregistered
 
Post: #1
I've been reading through the threads here about which image format to use for textures with transparency and I've noticed people like the PNG format. I used to use TGA because it was easy to load and didn't have premultiplied alpha but am trying out PNG and can't seem to get it to work. I found some code for using NSImage to load textures on the Apple Development website and when I use it with PNGs I get that funny halo that happens when the alpha is premultiplied. After messing with it for a while I discovered that if you use

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

as your blending function you don't need the non-premultiplied RGB data. Unfortunately, after playing around more I discovered that you can no longer assign a per-vertex alpha value when drawing quads. You can assign the RGB value just fine but I guess the GL_ONE blending function ignores both the texture pixel's alpha and the alpha value you assign with glColor4f(). Because of this issue I end up requiring the glBlendFunc() with GL_SRC_ALPHA.

I've found that any image format that has an alpha layer ends up with premultiplied RGB values when loaded using NSImage and am a bit frustrated now. I put together some pretty inefficient code to unmultiply the alpha value but I have no idea whether the correction I do will knock a value over 255 and end up wrapping to 0. Here is the code:

Code:
if (hasAlpha)   {
    for (i=0;i<width*height*4;i+=4) {
        if (bitmapData[i+3]>0)  {
            factor=(255./bitmapData[i+3]);
            bitmapData[i]=(unsigned char)(bitmapData[i]*factor);
            bitmapData[i+1]=(unsigned char)(bitmapData[i+1]*factor);
            bitmapData[i+2]=(unsigned char)(bitmapData[i+2]*factor);
        }
    }
}
In a thread on this forum that brought up the issue someone said Apple would be fixing the problem with premultiplied RGB data being loaded with PNG when they release Tiger. To me this is really frustrating because when that happens we will have to detect whether the values are premultiplied and then correct for them if they are because there would then be two different possible results for the loaded image.

Anyway, I've heard a lot of support for the PNG format on this forum and I'm wondering if there is some secret to loading PNGs into OpenGL that doesn't premultiply the RGB values. If not, is there a way of controlling the transparency of the vertices in the quads being drawn even with the GL_ONE blending function? If not that, is there any efficient code somewhere that can undo the premultiplication of alpha? If providing the NSImage loading code I'm using would help, I can do that.

Thanks ahead of time.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #2
Wouldn't setting the color to glColor4f(R*a, G*a, B*a, a), be the same as setting glColor4f(R,G,B,a) for a non-pre-multiplied image?
Quote this message in a reply
Prime
Unregistered
 
Post: #3
Skorche Wrote:Wouldn't setting the color to glColor4f(R*a, G*a, B*a, a), be the same as setting glColor4f(R,G,B,a) for a non-pre-multiplied image?
Well, I was gonna reply before the edit but what you have now works perfectly. Thanks!

Out of curiousity, is this how everyone deals with transparent textures loaded with NSImage? I really hope Apple doesn't change things with Tiger. It would be miserable to need to detect which operating system is used (or check a test image) before setting the blending function. Not to mention each time you use glColor4f(). Wacko
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2006.10
Post: #4
Prime Wrote:Out of curiousity, is this how everyone deals with transparent textures loaded with NSImage?

The shadow texture in Frenetic is loaded from a PNG with transparency using NSImage, and is mapped onto a mesh with per-vertex alpha values. But I'm not seeing the problems that you describe during the game. Do the shadows look weird on other computers?

On the other hand I have noticed that saving a screenshot of the game results in the odd haloing effect being apparent in the saved image.
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #5
Prime Wrote:Anyway, I've heard a lot of support for the PNG format on this forum and I'm wondering if there is some secret to loading PNGs into OpenGL that doesn't premultiply the RGB values.

Yep. You can use QuickTime to load the image. Take a look at the code here; a lot of people in this community use it for texture loading:

http://onesadcookie.is-a-geek.net/svn/re...LTexture.c

- Alex Diener
Quote this message in a reply
Prime
Unregistered
 
Post: #6
belthaczar Wrote:The shadow texture in Frenetic is loaded from a PNG with transparency using NSImage, and is mapped onto a mesh with per-vertex alpha values. But I'm not seeing the problems that you describe during the game. Do the shadows look weird on other computers?

On the other hand I have noticed that saving a screenshot of the game results in the odd haloing effect being apparent in the saved image.
If you are only using the shadow texture then you won't see any problems. If you want to quickly see things turn weird use "invert" in photoshop so the texture is white rather than black. The issue I was describing with premultiplication is that the RGB values are multiplied by the alpha value before being loaded. If RGB all equal 0 (as in the case of black) you won't notice a change. Just keep the discussion in mind if you start using colorful transparent textures.

ThemsAllTook Wrote:Yep. You can use QuickTime to load the image. Take a look at the code here; a lot of people in this community use it for texture loading:

http://onesadcookie.is-a-geek.net/svn/re...LTexture.c

- Alex Diener
Thanks. I saw that when searching the forum before but haven't tried it out yet. Knowing this NSImage problem is unfixable is a good enough reason for me to give it a shot. Grin
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
Just use QuickTime.

And don't worry about Tiger breaking NSImage. It will make sense when you read the documentation.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Starting with SDL, can't load BMP :( ngoles 14 11,440 Jan 21, 2014 11:19 AM
Last Post: SethWillits
  Premultiplied alpha halos IBethune 5 4,086 Feb 11, 2007 01:56 PM
Last Post: OneSadCookie
  png without alpha fine, png with alpha, nothing dave05 6 6,862 Jun 11, 2005 10:31 AM
Last Post: dave05
  Premultiplied alpha trouble Fenris 21 11,731 Nov 8, 2004 12:47 AM
Last Post: aaronsullivan
  need help getting quicktime to load textures xDexx 8 4,654 May 7, 2003 03:57 PM
Last Post: xDexx