OpenGLシェーダープログラムの属性の場所を設定するとき、2つのオプションに直面します。
リンクする前のglBindAttribLocation()は、属性の場所を明示的に定義します。
または
リンク後のglGetAttribLocation()は、自動的に割り当てられた属性の場所を取得します。
どちらか一方を使用するためのユーティリティは何ですか?
そして、もしあれば、どれが実際に好まれますか?
回答:
明示的な場所の定義を好む理由の1つを知っています。
ジオメトリデータを頂点配列オブジェクトに保持することを検討してください。特定のオブジェクトに対して、インデックスが対応するようにVAOを作成します。次に例を示します。
ここで、2つの異なるシェーダーを使用して1つのオブジェクトを描画するとします。1つのシェーダーは入力として位置と通常のデータを必要とし、もう1つは位置とテクスチャ座標を必要とします。
これらのシェーダーをコンパイルすると、最初のシェーダーは属性インデックス0の位置を期待し、法線は1を期待することに気付くでしょう。他のシェーダーは、0の位置を期待しますが、テクスチャ座標は1です。
https://www.opengl.org/wiki/Vertex_Shaderの引用:
自動割り当て
前の2つの方法のどちらも入力を属性インデックスに割り当てない場合、プログラムがリンクされると、インデックスはOpenGLによって自動的に割り当てられます。割り当てられるインデックスは完全に任意であり、まったく同じ頂点シェーダーコードを使用している場合でも、リンクされているプログラムごとに異なる場合があります。
これは、VAOを両方のシェーダーで使用できないことを意味します。たとえば、オブジェクトごとに1つのVAOを使用する代わりに、最悪の場合、シェーダーごとにオブジェクトごとに個別のVAOが必要になります。
を介してシェーダーに独自の属性番号付け規則を使用させると、glBindAttribLocation
この問題を簡単に解決できます。必要なのは、属性とその確立されたIDの間の一貫した関係を維持し、リンク時にシェーダーにその規則を使用するように強制することです。
(個別のVAOを使用しない場合、これはそれほど大きな問題ではありませんが、コードがより明確になる可能性があります。)
ところで:
OpenGLシェーダープログラムの属性の場所を設定するとき、2つのオプションに直面します
OpenGL / GLSL 3.3には3番目のオプションがあります:シェーダーコードで直接場所を指定します。次のようになります。
layout(location=0) in vec4 position;
ただし、これはGLSLESシェーダー言語にはありません。
3番目のオプション、つまりlayout(location=0) in vec4 position;
シェーダーコードは、OpenGL ES 3.0 / GLSL 300esで使用できるようになりました。ただし、頂点シェーダー入力変数の場合のみ。
glBindAttribLocation
Linuxでうまく機能するグラフィックエンジンをわざわざ使用することはありませんでした。Windowsに移植したとき、法線を頂点として使用していました。シェーダーを機能glBindAttribLocation
させるには、シェーダー内の変数の順序を明示的に指定する必要がありました...