2011-08-31 173 views
1

繪製當我試圖繪製PNG圖片的透明度,使用OpenGL,我得到一個奇怪的黑色邊框周圍:黑色邊框,用OpenGL

Two images with borders

但原始圖像乾淨,正常:

Normal icons

我的代碼:

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

UIImage* allIcons = [[appDelegate load_image_from_zip: pl.icons[ico_index]] retain]; 

       CGRect rect = CGRectMake(0, 0, allIcons.size.width/nIcons, allIcons.size.height); 
       UIGraphicsBeginImageContext(rect.size); 

       CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

       CGContextTranslateCTM (currentContext, 0, allIcons.size.height); 
       CGContextScaleCTM (currentContext, 1, -1); 

       CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height); 
       CGContextClipToRect(currentContext, clippedRect); 
       CGRect drawRect = CGRectMake(rect.origin.x * -1, rect.origin.y * -1, allIcons.size.width, allIcons.size.height); 
       CGContextDrawImage(currentContext, drawRect, allIcons.CGImage); 

回答

1

假設您的TexEnv是默認GL_MODULEATE在繪製之前嘗試glColor4ub(255, 255, 255, 255)

1

問題是,您的圖像預乘alpha,其中每個像素的顏色已乘以其alpha值。 iPhone上的UIKit更喜歡預乘Alpha圖像 - 將它們混合的速度更快 - 但OpenGL並不認爲,所以Alpha通道的透明度效果會導致兩次應用,這會導致圖像中半透明像素顯得比黑暗他們實際上是。嘗試關閉項目構建設置中的「壓縮PNG文件」選項。

0

嘗試這些

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
2

這是可怕的預乘alpha的問題。在找出答案之前,我爲此奮鬥了好一個星期。告訴你的項目不壓縮.png文件並不能解決問題,因爲各種API調用將重新乘以alpha。這是我解決它的方式。

當設置混合模式和顏色:

blendFuncSource = premultAlpha ? GL_ONE : GL_SRC_ALPHA; 
blendFuncDestination = GL_ONE_MINUS_SRC_ALPHA; 

if (premultAlpha) 
{ 
    glColor4f(colorfilter.red*colorfilter.alpha, colorfilter.green*colorfilter.alpha, colorfilter.blue*colorfilter.alpha, colorfilter.alpha); 
} 
else 
{ 
    glColor4f(colorfilter.red, colorfilter.green, colorfilter.blue, colorfilter.alpha); 
} 

你需要弄清楚你的圖像使用預乘alpha。你可以做到這一點我檢查PNG頭在加載時:

CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(image); 

...

switch(bitmapInfo & kCGBitmapAlphaInfoMask) 
{ 
case kCGImageAlphaPremultipliedFirst: 
    premultAlpha = YES; 
    srcFormat = GL_BGRA; 
    break; 

case kCGImageAlphaFirst: 
    srcFormat = GL_BGRA; 
    break; 

case kCGImageAlphaNoneSkipFirst: 
    srcFormat = GL_BGRA; 
    break; 

default: 
    srcFormat = GL_RGBA; 
} 

我在這裏複述了大量的代碼,希望它仍然是有幫助的。