Changeset 10855

Show
Ignore:
Timestamp:
12/04/09 18:25:23 (5 years ago)
Author:
robert
Message:

From Tatsuhiro Nishioka, "> The workaround/solution was to add a block of code at the end of the

loader to un-premultiply the alpha (now in the codebase).

Applying the code brightens the semi-transparent portion, but the black edges are still there (same on both osgviewer and FlightGear?).
Therefore I believe that the alpha channel is completely ignored (on png, gif, tiff, etc...). I tweaked and tweaked and finally got a workaround.

Please commit the enclosed file to fix these issues.

My workaround is a bit tricky (and some lines are even weird for me), but it resolves the black edges.
These workarounds also work on GIF, TIFF, TGA, and PSD as long as I've tested so far.

Please read this for more info on this issue:
http://macflightgear.sourceforge.net/home/development-notes/devnote-dec-02-2009
http://macflightgear.sourceforge.net/home/development-notes/devnote-dec-03-2009

I'm very happy if some of you guys find a better means of solving the black edges.

"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/imageio/ReaderWriterImageIO.cpp

    r10854 r10855  
    312312            break; 
    313313        } 
    314         case 16: 
    315         { 
    316             // FIXME: Is this really a reasonable assumption: GL_LUMINANCE_ALPHA? 
    317             internal_format = GL_LUMINANCE_ALPHA; 
    318             pixel_format = GL_LUMINANCE_ALPHA; 
    319             data_type = GL_UNSIGNED_BYTE; 
    320 //            color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); 
    321             color_space = CGColorSpaceCreateDeviceGray(); 
    322             break; 
    323         } 
    324314        case 24: 
    325315        { 
     
    338328            break; 
    339329        } 
     330        // 
     331        // Tatsuhiro Nishioka 
     332        // 16 bpp grayscale (8 bit white and 8 bit alpha) causes invalid argument combination 
     333        // in CGBitmapContextCreate.  
     334        // I guess it is safer to handle 16 bit grayscale image as 32-bit RGBA image. 
     335        // It works at least on FlightGear 
     336        // 
     337        case 16: 
    340338        case 32: 
    341339        { 
    342              
     340 
    343341            internal_format = GL_RGBA8; 
    344342            pixel_format = GL_BGRA_EXT; 
     
    349347            color_space = CGColorSpaceCreateDeviceRGB(); 
    350348//            bitmap_info = kCGImageAlphaPremultipliedFirst; 
     349 
    351350#if __BIG_ENDIAN__ 
    352351            bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big; /* XRGB Big Endian */ 
     
    381380    CGContextRelease(bitmap_context); 
    382381 
     382    //  
     383    // Reverse the premultiplied alpha for avoiding unexpected darker edges 
     384    // by Tatsuhiro Nishioka (based on SDL's workaround on the similar issue) 
     385    // http://bugzilla.libsdl.org/show_bug.cgi?id=868 
     386    //  
     387    if (bits_per_pixel > 8 && (bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) { 
     388        int i, j; 
     389        GLubyte *pixels = (GLubyte *)image_data; 
     390        for (i = the_height * the_width; i--; ) { 
     391            GLuint *value = (GLuint *)pixels; 
     392#if __BIG_ENDIAN__ 
     393            //  
     394            // swap endian of each pixel for avoiding weird colors on ppc macs 
     395            // by Tatsuhiro Nishioka 
     396            // FIXME: I've tried many combinations of pixel_format, internal_format, and data_type  
     397            // but none worked well. Therefore I tried endian swapping, which seems working with gif,png,tiff,tga,and psd. 
     398            // (for grayscaled tga and non-power-of-two tga, I can't guarantee since test images (made with Gimp)  
     399            // get corrupted on Preview.app ... 
     400            *value = ((*value) >> 24) | (((*value) << 8) & 0x00FF0000) | (((*value) >> 8) & 0x0000FF00) | ((*value) << 24); 
     401#endif 
     402            GLubyte alpha = pixels[3]; 
     403            if (alpha) { 
     404                for (j = 0; j < 3; ++j) { 
     405                    pixels[j] = (pixels[j] * 255) / alpha; 
     406                } 
     407            } 
     408            pixels += 4; 
     409        } 
     410    } 
     411 
     412    // 
     413    // Workaround for ignored alpha channel 
     414    // by Tatsuhiro Nishioka 
     415    // FIXME: specifying GL_UNSIGNED_INT_8_8_8_8_REV or GL_UNSIGNED_INT_8_8_8_8 ignores the alpha channel. 
     416    // changing it to GL_UNSIGNED_BYTE seems working, but I'm not sure if this is a right way. 
     417    // 
     418    data_type = GL_UNSIGNED_BYTE; 
    383419    osg::Image* osg_image = new osg::Image; 
    384420