Черные границы вокруг изображения PNG, нарисованного с помощью OpenGL - PullRequest
1 голос
/ 31 августа 2011

Когда я пытаюсь нарисовать изображение PNG с прозрачностью, используя 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);

Ответы [ 4 ]

2 голосов
/ 09 сентября 2011

Это страшная предварительно умноженная альфа-проблема. Я боролся с этим в течение хорошей недели прежде, чем понять это. Указание вашему проекту не сжимать файлы .png не решает проблему, поскольку различные вызовы API повторно умножают альфа. Вот как я это решил.

При настройке режимов наложения и цвета:

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);
}

Вам нужно выяснить, какие изображения используют предварительно умноженную альфа. Вы можете сделать это, проверив заголовки 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;
}

Я перефразирую много кода здесь, надеюсь, он все еще полезен.

1 голос
/ 31 августа 2011

Проблема заключается в том, что ваши изображения предварительно умножены на альфа, где цвет каждого пикселя умножается на его значение альфа. UIKit на iPhone предпочитает предварительно умноженные альфа-изображения - их смешивание происходит быстрее, но OpenGL не предполагает, что эффект прозрачности вашего альфа-канала как бы применяется дважды, что приводит к тому, что полупрозрачные пиксели в вашем изображении выглядят темнее, чем они на самом деле. Попробуйте отключить опцию «Сжатие файлов PNG» в настройках сборки вашего проекта.

1 голос
/ 31 августа 2011

Предполагая, что ваш TexEnv является значением по умолчанию GL_MODULEATE, попробуйте glColor4ub(255, 255, 255, 255) перед рисованием.

0 голосов
/ 01 сентября 2011

попробуйте эти

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...