iOS semi-transparent textures

edited May 2011 in Help request
hey,
I got a problem using semi-transparent textures on the iOS platform.
textures having containing transparency of either 0 or 255 are rendered completely normal. however textures having values inbetween will be rendered somehow "greyish".

when I change the blending function in the render code
from
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
to
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
those textures will be rendered correctly. however this will of course mess up if you set the alpha value of some object manually, e.g. through some effect. so I suppose the alpha value is premultiplied somewhere.

I'm gonna investigate that further now...

Comments

  • edited May 2011
    ok there is no possibility to create a bitmap context( CGBitmapContextCreate) that doesn't premultiply the alphavalue. there is a constant named kCGImageAlphaLast, but it's seems like it's not implemented.

    so when drawing the image(CGContextDrawImage) in that context it will be premultiplied.

    so that's the cause. now the question is what will be a decent solution :D
  • edited May 2011
    ok here is a solution to the problem:
    Index: orxDisplay.m
    ===================================================================
    --- orxDisplay.m	(revision 314)
    +++ orxDisplay.m	(working copy)
    @@ -1089,6 +1089,7 @@
           {
             glEnable(GL_BLEND);
             glASSERT();
    +        //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
             glASSERT();
             break;
    @@ -2108,7 +2109,12 @@
               CGColorSpaceRef oColorSpace;
               CGContextRef    oContext;
               GLint           iTexture;
    +          orxU32          iImageSize;
    +          GLubyte         *au8ImagePointer;
               
    +          iImageSize = uiRealWidth * uiRealHeight;
    +          au8ImagePointer = au8ImageBuffer;
    +          
               /* Creates a device color space */
               oColorSpace = CGColorSpaceCreateDeviceRGB();
               
    @@ -2125,6 +2131,20 @@
               /* Copies image data */
               CGContextDrawImage(oContext, CGRectMake(0, 0, uiWidth, uiHeight), oImage);
               
    +          /* The context will have multiplied the image with the alpha value. Undo that now. */
    +          for(orxU32 i=0;i<iImageSize;i++)
    +          {
    +            GLubyte alpha = au8ImagePointer[3];
    +            if (alpha)
    +            {
    +              for(orxU32 j=0;j<3;j++)
    +              {
    +                au8ImagePointer[j] = au8ImagePointer[j]*255/alpha;
    +              }
    +            }
    +            au8ImagePointer+=4;
    +          }
    +          
               /* Pushes display section */
               orxConfig_PushSection(orxDISPLAY_KZ_CONFIG_SECTION);
               
    

    this code will just remove the premultiplied alpha, after drawing the image into the context.

    that's also how the SDL and the OSG guys did it:
    http://bugzilla.libsdl.org/show_bug.cgi?id=868
    http://www.openscenegraph.org/svn/osg/OpenSceneGraph/trunk/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp https://forum.orx-project.org/uploads/legacy/fbfiles/files/iphonepremultipliedalphabug.zip
  • edited May 2011
    Thanks for pointing it out. I could swear I wrote a very similar code to remove the premultiplied alpha but somehow I messed up and it never made it up to the svn. :(

    Thanks for the patch, I'll integrate it tonight! :)
Sign In or Register to comment.