グレイスケール(1画素が輝度値で表現されている)データをテクスチャとして使用することを考える。RGB(A)に変換しないでできれば何かと便利になる。
typedef GLshort gray_t; const int P_COUNT = 4; gray_t texdata[P_COUNT]; //テクスチャ(画像)作成 // 2*2のグレイスケール画像 texdata[0] = 255; texdata[1] = 128; texdata[2] = 50; texdata[3] = 0;
GL_LUMINANCEなどを指定すればよいのだが、これは最近では非推奨らしい。
代わりに、GL_R8I,GL_R8UI,GL_R16I,GL_R16UI,GL_R32I,GL_R32UI等を使えば、RGBではなくグレイスケールとしてテクスチャを転送できる。
glTexImage2D( GL_TEXTURE_2D, 0, GL_R8UI, //8bitのunsinged int TEXWIDTH, //テクスチャ画素数 TEXHEIGHT, //テクスチャ画素数 0, GL_RED_INTEGER, //整数 GL_UNSIGNED_BYTE, //unsigned の 1byte
texdata
);
glTexImage2D( GL_TEXTURE_2D, 0, GL_R16I, //16bitのsigned int TEXWIDTH, //テクスチャ画素数 TEXHEIGHT, //テクスチャ画素数 0, GL_RED_INTEGER, //整数 GL_SHORT, //signed の 2byte texdata );
sampler2Dを使うと、データ範囲が0.0~1.0の間で正規化されて取得できる。それでいい時も多いと思うのだが、グレースケールデータの値を正確に参照したい場合は不便というか、元の値を正確に得られる保証がない。そこでisampler2Dを使うと、テクスチャのデータをもとのままで参照できる。
#version 460 core out vec4 FragColor; //色の出力はfloatでいい uniform isampler2D uTex; //データをint型で受け取る。符号なしintのときはusampler2D in vec2 vTexCoord; //テクスチャ座標 void main() { int c = texture(uTex,vTexCoord).x; //分岐はどうのとか今はいい。本題ではない。 if( c == 255) FragColor =vec4( 1.0,0,0,1); else if( c == 128) FragColor =vec4( 0.0,1.0,0,1); else if( c == 50) FragColor =vec4( 0.0,0.0,1.0,1); else FragColor =vec4( float(c)/255.0,float(c)/255.0,float(c)/255.0,1.0); }