音ゲーの出来ない雑魚のブログ

LWJGLとかのことをいうブログ

「moreover lwjgl」 10 現代的なテクスチャ表示(2) ~stbを使って~

「現代的な」テクスチャ表示の続きです。

シェーダの説明を主にします。

どうでもいいですが、STBという名前は、作者 Sean T. Barrett 氏の名前の頭文字から取ったそうです。どうでもよかったですね。

ということで、ソースコード(シェーダのみ)

シェーダ

解説

v2,3行目 : シェーダ内で使う頂点情報をOpenGL側から受け取ります。

in
APIOpenGL)側からの受け取りの変数である、つまり、入力であることを意味しています。

GLSLでは前は attribute というものも使えましたが、頂点シェーダでしか使うことが出来なかったので、今は in を使うことが推奨されています。というより、廃止されています

逆に、APIに受け渡す値の変数、つまり出力を表すのが、 out です。これも、昔は varying というものが有りましたが、非推奨になりました。

in / outinout というのもある)などを、合わせて"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行目 : テクスチャのサンプラーのユニフォームを受け取ります。

Uniform
ユニフォームは、GLSL内で使える変数の一つで、一つの物体(Primitive)ごとに渡すことが出来ます。

OpenGLから値を受け取れる点で in と似ています。さらに、GLSL内で値を定義することも出来ます。ただし、読み込み専用で、初期化した値から変更することは出来ません。
また、 in はシェーダごとにしか使えませんが、ユニフォームは同じ名前なら、すべてのシェーダで共通の値として使うことが出来ます。

ユニフォームの値は、GLSLでその場で代入するか、OpenGL側で、glGetUniformLocationで探してから、glUniform系で代入して下さい。

f15行目 : 組み込み変数"gl_FragColor"に組み込み関数の"texture(sampler, bias)"を使って画素毎の色を渡しています。

texture(sampler, P)は、指定されたサンプラー(sampler)と、テクスチャ座標(P)を使って、1画素毎の色を探しだす(lookup)関数です。

vec4 texture(sampler2D sampler,vec2 uv)

Pには、1次元(float)、2次元(vec2),3次元(vec3)などを入れることが出来ます。今回は、2次元テクスチャなので、vec2(gl_TexCoord[0])を使ってテクスチャ座標を指定しています。"gl_TexCoord[0]"は先程の「テクスチャユニット"0"のテクスチャ座標」です。





実行結果はこちら

f:id:cakkby:20160419214246p:plain


これでやっと「現代的な」方法で画像を表示することが出来ました。シェーダを使わないと描画できなくなったのは面倒ですが、逆に言えば、シェーダを変えるだけで、画像を色々(思い通りに)と加工することが出来るようになりました。

今度は動かないとつまらないということで、箱を動かしたいと思います。