4

DevIL を使用して画像をロードし、OpenGL がピクセルからテクスチャを作成するテクスチャをロードするためのコードがいくつかあります。このコードは正常に機能し、テクスチャが適切に表示され、それで問題ありません。

それに加えて、プログラム内から配列を作成して、テクスチャを作成したり、テクスチャのピクセルを直接変更したりすることもできます。私の問題はここにあります.ピクセルを処理するとき、私が望んでいたように、ピクセルのフォーマットはRGBAではなくABGRのようです。

glTexImage2D 関数で渡される形式を参照するこのSO の質問に出くわしました。

(...) GL_RGBA と GL_UNSIGNED_INT_8_8_8_8 がある場合、これは、ピクセルが 32 ビット整数で格納され、色がそのような整数で RGBA の論理順序にある​​ことを意味します。たとえば、赤は上位バイトにあり、 alpha は下位バイトです。しかし、マシンが (Intel CPU のように) リトルエンディアンの場合、メモリ内の実際の順序は ABGR になります。一方、GL_UNSIGNED_BYTE を指定した GL_RGBA は、コンピューターがリトル エンディアンかビッグ エンディアンかに関係なく、バイトを RGBA 順に格納します。(...)

確かに私はIntelのCPUを持っています。画像は今のところ問題なくロードされており、実際には GL_RGBA モードと GL_UNSIGNED_BYTE タイプを使用しています。

GLuint makeTexture( const GLuint* pixels, GLuint width, GLuint height ) {

    GLuint texture = 0;

    glGenTextures( 1, &texture );

    glBindTexture( GL_TEXTURE_2D, texture );

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

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

    glBindTexture( GL_TEXTURE_2D, NULL );

    GLenum error = glGetError();
    if ( error != GL_NO_ERROR ) {
        return 0;
    }

    return texture;
}

この関数は、テクスチャを読み込む 2 つの方法で使用されます。ファイルから画像を読み込む方法と、配列からテクスチャを作成する方法です。

ピクセルの配列を作成してテクスチャを作成したいとしましょう。

GLuint pixels[ 128 * 128 ];
for ( int i = 0; i < 128 * 128; ++i ) {
    pixels[ i ] = 0x800000FF;
}
texture.loadImageArray( pixels, 128, 128 );

この値でピクセルをパディングすることで、少し暗い赤色が表示されると予想されます。

red = 0x80, green = 0x00, blue = 0x00, alpha = 0xFF

しかし、代わりに透明な赤が得られます。

alpha = 0x80, blue = 0x00, green = 0x00, red = 0xFF

生の unsigned int を使用するのではなく、個々のチャネルを処理するのに役立つ構造を作成しました。

struct Color4C {
    unsigned char alpha;
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    ...
};

unsigned int の配列を Color4C の配列に簡単に置き換えることができ、結果は同じです。チャンネルの順序を逆にすると (赤が最初、アルファが最後)、0xRRGGBBAA を簡単に渡して機能させることができます。

簡単な解決策は、これらの値を ABGR 形式で処理することです。しかし、RGBA 値を扱う方が簡単だとも思います。ハードコーディングされた色の値を使用したい場合は、0xAABBGGRR ではなく 0xRRGGBBAA のように書きたいと思います。

しかし、ABGR フォーマットを使い始めたとしましょう。自分のコードを別のマシンで実行すると、ピクセル/チャネルを直接変更した場所に突然奇妙な色が表示されますか? より良い解決策はありますか?

4

1 に答える 1