2017-10-27 20 views
3

OS X SierraのSDL2 2.0.7およびSDL2_image 2.0.2を使用して、アルファチャンネルでエンハンスされた高さマップを使用して、32ビットRGBAノーマルマップテクスチャを読み込みます。OS Xの表面をロードするときにSDL2アルファチャンネルを事前に乗算する?

これらのテクスチャのすべてのピクセルは、方向ノーマルベクトルを符号化し、ゼロでないRGB値を持ちます。 (0,0,0)の方向ベクトル(すなわち)は無効です。

私はSDL2_imageを介して、このようなテクスチャをロードするとき、まだ、0の0 収率RGB値のアルファ値を有するテクスチャーの領域は、私は、SDLは、おそらくこれらのピクセルのアルファ値を事前に乗算されると思います?

これらのノーマルマップテクスチャのいずれかが添付されています。あなたはそれが有効であることを確認することができます。 GIMPを使用し、透明領域の1つでカラーピッカーを使用します。確かに、透明領域にはまだ青色(エンコードされた法線ベクトル)のRGBカラーがあります。

32 bit RGBA normalmap with alpha-encoded heightmap for parallax mapping

そして以下に添付PNGファイルの問題を示す、最小限のテストケースである:

#include <SDL_image.h> 
#include <assert.h> 

int main(int argc, char **argv) { 

    SDL_Surface *s = IMG_Load("green3_2_nm.png"); 
    assert(s); 

    for (int i = 0; i < s->w * s->h; i++) { 
     const Uint32 *in = (Uint32 *) (s->pixels + i * s->format->BytesPerPixel); 

     SDL_Color color; 
     SDL_GetRGBA(*in, s->format, &color.r, &color.g, &color.b, &color.a); 

     assert(color.r || color.g || color.b); 
    } 

    SDL_FreeSurface(s); 

    return 0; 
} 

私はgcc $(pkg-config --cflags --libs sdl2_image) test.c

ライン15上の主張で、このテストケースをコンパイルしていますいくつかの行が画像に失敗します。つまり、正確にアルファ値が0に下がったところです。

私は試しましたTGAとPNGの両方の画像フォーマットをサポートしていますが、SDLはその両方に同じことを行います。

これはSDLのバグですか、それとも不足していますか?私は人々が他のプラットフォームでも同じ問題を抱えているのが不思議です。

===

回答: - 常にコアグラフィックス、アップルのOS X上SDL2_imageのデフォルトの画像の読み込みバックエンド、事前乗算アルファ確かにありません。解決策は、コアグラフィックスのサポートなしでSDL2_imageを再コンパイルし、代わりのlibpng、のlibjpeg、およびその他の必要な画像コーデックを有効にするには、次のとおりです。

./configure \ 
--disable-imageio \ 
--disable-png-shared \ 
--disable-tif-shared \ 
--disable-jpg-shared \ 
--disable-webp-shared 

私のシステムでは、私はコアグラフィックス(imageioを無効にしなければならなかったともあなたが見ることができるように、他のコーデックの共有ライブラリの読み込み。これはlibpng、libjpgなどと静的にリンクされていたfat SDL2_image.soを生成しましたが、期待どおりに動作しました。

答えて

3

SDL_imageは、すべてのプラットフォームで同じイメージローダーを使用するのではなく、プラットフォーム固有のイメージローディングコードを包むラッパーです。

  • のLinux:のlibpng、のlibjpeg
  • MacOSの、iOSの:コアグラフィックス
  • のWindows:WinCodec

それが持っていないので、これは、SDL_imageの大きさを減少させるという利点を有します画像のデコードコードがあればそれを出荷し、システムに既にインストールされているものと動的にリンクすることができます。しかし、macOSとiOSでは、Core Graphicsは非プレミキシングアルファをサポートしていないので、SDL_imageはそれを元に戻す必要があります。

参照:2007年5月からmac-opengl - Re: kCGImageAlphaFirst not implemented (Was: (no subject))(ウェイバックマシンから):

正直なところ、私はCGBitmapContextCreate()が非プリマルチプライ済みアルファをいつでもすぐにサポートするために期待していません。 ImageIOで+ CoreGraphicsを使用している場合

...

私はよく分からないが、これまで実際にOpenGLアプリケーションのための画像の読み込みスキームのために使用されているをターゲットました。

この現象はLibSDL bug #838 - OSX SDL darkens colours proportional to increase in alphaで発見され、回避策はSDL_image changeset 240で導入されました。

回避策が単にアルファを事前に除外していることがわかります。これはひどく損失の多いプロセスです。

これに対処するには、LibPNGを使用するmacOSで独自のバージョンのSDL_imageを構築することができます。これはコンフィギュレーションだけで可能です。SDL_imageコード自体を変更する必要はありません。これを行うには、--disable-imageioオプションを使用します。 SDL_imageには独自のLibPNGコードが付属しているため、LibPNGをインストールする必要はありません。

+0

ありがとうございました。私がそれを受け入れる前に、なぜこれもTGA画像の場合にも説明できますか?私はSDLがデコードしてロードするのは正しいと思いますか?もしそうなら、なぜ彼らもこの問題を抱えていますか? – jdolan

+1

SDLは、コアグラフィックスがサポートするすべてのフォーマット(TGA、TIFFなど)で、macOS上でCore Graphicsを使用します。 –

+0

SDL_imageはイメージ自体を実際にはデコードしません。それはそのためのライブラリを使用します。 SDL_imageは、他のすべてのライブラリとの共通インタフェースをラッパーに提供するだけです。 (いくつかの例外があるかもしれません。) –

関連する問題