6

Opengl ESでiPhone用のゲームを書いていますが、アルファブレンディングで問題が発生しています。

私はglBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)アルファブレンディングを実現するために使用しており、静止画像の代わりにそれらを別々に移動できるように、いくつかの「レイヤー」でシーンを構成しようとしています。Photoshopでプレビューを作成し、iPhoneでも同じ結果を達成しようとしましたが、テクスチャを半透明の領域とブレンドすると、黒いハローが表示されます。

画像を添付しました。左はiPhoneのスクリーンショット、右はフォトショップで構図を作ったときのスクリーンショットです。この画像は、グラデーションとフェザーエッジのある砂の画像で構成されています。

これは予想される動作ですか?暗い境界線を回避する方法はありますか?

ありがとう。

編集:砂を含むpngの部分をアップロードしています。完全なpngは512x512で、他の画像もあります。

次のコードを使用して画像を読み込んでいます。

NSString *path = [NSString stringWithUTF8String:filePath];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
if (image == nil) NSLog(@"ERROR LOADING TEXTURE IMAGE");

GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( context, 0, height - height );
CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image.CGImage );

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

CGContextRelease(context);

free(imageData);
[image release];
[texData release];

代替テキスト 代替テキスト

4

4 に答える 4

6

私は自分の質問に答える必要があります:

ImageIOフレームワークを使用して動作させることができなかったため、プロジェクトにlibpngソースを追加し、それを使用して画像をロードしました。今は完璧に動作しますが、次の問題を解決する必要がありました。

画像が読み込まれ、シミュレーターで正常に表示されましたが、実際のデバイスではまったく読み込まれていませんでした。Webで、PNG画像形式ファイルのピクセル順序がRGBAからBGRAに変換され、圧縮ユーティリティ「pngcrush」によってカラー値にアルファチャネル値が事前に乗算されていることがわかりました。 (デバイス固有の効率上の理由から、UIKitインターフェイスでプログラミングする場合)。

ユーティリティはファイルのヘッダーの名前も変更し、libpngで新しいPNGファイルを使用できなくなります。これらの変更は、PNGファイルがiPhoneに展開されるときに自動的に行われます。これはUIKitには問題ありませんが、libpng(およびその他のApple以外のライブラリ)は通常、ファイルを読み取ることができません。

簡単な解決策は次のとおりです。

  1. PNGファイルの名前を別の拡張子に変更します。
  2. iPhone -device- buildの場合、次のユーザー定義設定を追加します。

    IPHONE_OPTIMIZE_OPTIONS | -skip-PNGs

私は2番目を実行しましたが、シミュレーターとデバイスで完全に機能するようになりました。

于 2010-10-26T11:56:49.557 に答える
3

スクリーンショットとフォトショップのモックアップは、画像のカラーチャンネルがアルファチャンネルに対して事前に乗算されていることを示しています。

于 2010-10-25T08:05:59.787 に答える
2

元のソース画像がどのように見えるかはわかりませんが、正しくブレンドされているように見えます。ブレンドモードを使用すると、レイヤー間で泥だらけのブレンドを取得できます。

フォトショップバージョンは、各レイヤーに適切な透明度があるように見えますが、ブレンドされていません。ピクセルのアルファを正確に明示的に設定したくない場合は、glAlphaFuncを試してみることができると思います。

---以下のコメントに関連するコード(アルファ事前乗算の削除)---

int pixelcount = width * height;
unsigned char* off = pixeldata;
for (int pi=0; pi<pixelcount; ++pi)
{
    unsigned char alpha = off[3];
    if( alpha!=255 && alpha!=0 )
    {
        off[0] = ((int)off[0])*255/alpha;
        off[1] = ((int)off[1])*255/alpha;
        off[2] = ((int)off[2])*255/alpha;
    }
    off += 4;
}
于 2010-10-25T06:10:39.880 に答える
2

この投稿は古くからあることは承知していますが、同じ問題が発生し、いくつかの解決策を試し、何日も苦しんだ後、次のブレンドパラメータを使用して事前に乗算されたRGBApngの問題を解決できることを発見しました。

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

私の場合GL_ONE、パラメータがパラメータに置き換わりましたGL_SRC_ALPHA

これで、グリフテキストを不快に見せてしまう灰色のアルファエッジ効果なしでRGBAPNGを使用できるようになりました。

編集:さて、もう1つ、フェードなど(コードでアルファチャネルを設定する)の場合、ブレンドが上記のように設定されている場合は、手動で事前に乗算する必要があります。

glColor4f(r*a, g*a, b*a, a);
于 2013-09-11T18:22:09.793 に答える