「moreover lwjgl」 10 現代的なテクスチャ表示(2) ~stbを使って~
「現代的な」テクスチャ表示の続きです。
シェーダの説明を主にします。
どうでもいいですが、STBという名前は、作者 Sean T. Barrett 氏の名前の頭文字から取ったそうです。どうでもよかったですね。
ということで、ソースコード(シェーダのみ)
シェーダ
解説
v2,3行目 : シェーダ内で使う頂点情報をOpenGL側から受け取ります。
GLSLでは前は attribute というものも使えましたが、頂点シェーダでしか使うことが出来なかったので、今は in を使うことが推奨されています。というより、廃止されています。
逆に、APIに受け渡す値の変数、つまり出力を表すのが、 out です。これも、昔は varying というものが有りましたが、非推奨になりました。
in / out ( inout というのもある)などを、合わせて"Qualifier Prefix"と言います。
指定した2つのin変数は、OpenGL内では、glGetAttribLocationによって取得され、glVertexAttribPointerに渡されて
使われています。
v6行目 : 組み込み変数"gl_Position"に頂点の座標を代入しています。"gl_Position"では、すべてを変換し終わった後の座標を決めます。今回は、頂点の座標をそのまま写しています。
頂点座標は、x, y, z で表しているのですが、"gl_Position"はベクトルで渡さなければいけないので、w = 1を追加した、vec4(x, y, z, 1)を代入しています。
v7行目 : 組み込み変数"gl_TexCoord[0]"
にテクスチャ座標を代入しています。"gl_TexCoord[n]"はn番目のテクスチャユニットのテクスチャ座標を表していています。
テクスチャユニットというのは、OpenGL内でテクスチャを扱う時(サンプラーなどを掛けるとかも)のハードウェア側の保存番号のようなもので、"GL_TEXTURE0"をテクスチャユニット"0"としています。
gl_TexCoord[n] = GL_TEXTURE0 + n
このように、テクスチャユニット"n"は"GL_TEXTURE0"に n を足しあわせて表します。
f12行目 : テクスチャのサンプラーのユニフォームを受け取ります。
OpenGLから値を受け取れる点で in と似ています。さらに、GLSL内で値を定義することも出来ます。ただし、読み込み専用で、初期化した値から変更することは出来ません。
また、 in はシェーダごとにしか使えませんが、ユニフォームは同じ名前なら、すべてのシェーダで共通の値として使うことが出来ます。
ユニフォームの値は、GLSLでその場で代入するか、OpenGL側で、glGetUniformLocationで探してから、glUniform系で代入して下さい。
f15行目 : 組み込み変数"gl_FragColor"に組み込み関数の"texture(sampler, bias)"を使って画素毎の色を渡しています。
texture(sampler, P)は、指定されたサンプラー(sampler)と、テクスチャ座標(P)を使って、1画素毎の色を探しだす(lookup)関数です。
Pには、1次元(float)、2次元(vec2),3次元(vec3)などを入れることが出来ます。今回は、2次元テクスチャなので、vec2(gl_TexCoord[0])を使ってテクスチャ座標を指定しています。"gl_TexCoord[0]"は先程の「テクスチャユニット"0"のテクスチャ座標」です。
実行結果はこちら
これでやっと「現代的な」方法で画像を表示することが出来ました。シェーダを使わないと描画できなくなったのは面倒ですが、逆に言えば、シェーダを変えるだけで、画像を色々(思い通りに)と加工することが出来るようになりました。
今度は動かないとつまらないということで、箱を動かしたいと思います。