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