Tuesday, July 7, 2015

OpenGL ES 2.0のglBindAttribLocationと、ES 3.0のInput Layout Qualifiers

OpenGL ES 3.0以降では、GLSLから頂点属性の入力位置をlayoutから始まる構文で指定することが出来ます。これをKhronosの公式文書ではInput Layout Qualifiersと呼んでいます。



OpenGL ES 2.0の場合はInput Layout Qualifiersが無いのでGLSLにlocationを記述できませんが、glBindAttribLocationでC側から同じ事ができます。glLinkProgramの直前にglBindAttribLocationを使って頂点属性の名前とlocationを任意に指定できます。



ただし、Input Layout Qualifiersを使う場合Cはlocationの番号だけ知っていればよいのに対し、glBindAttribLocationを使うと名前と番号の両方をCから指定するので冗長な感じがします。

GLSLでlocationを指定せず、glBindAttribLocationもしないとglLinkProgramの時点で自動的にlocationが振り分けられます。この場合、glGetAttribLocationでlocationを問い合わせる必要があります。



こうするとES2.0でもES3.0でも動く上、名前のみで頂点attributeを結び付けられる為に分かり易いという利点があります。いいことずくめのようですが、locationの割り当てが実装依存で予想できない為、複数シェーダでlocationを共有できないという欠点があります。同じ頂点バッファを複数のシェーダで描画する場合、シェーダを切り替える毎にglGetAttribLocationで問い合わせる煩雑さがあります。

この煩雑さはES 3.0でVAO(Vertex Array Object)を使いはじめると特に顕著です。シェーダ毎にlocationが異なるとVAOをシェーダー毎に作り直さなければいけません。一つのVAOを複数のシェーダで使いまわす為にはlocationの番号を固定する必要があります。

ある程度の規模のフレームワークを作ることを考えると、glBindAttribLocationかInput Layout Qualifiersを使い、"position"は0番、"normal"は1番などと、あらかじめlocationを決めておくとうまく書けそうです。

(2016/03/29 追記)
使いやすいフレームワークのためのもっといい方法を思いついたので書きました。
http://glhub.blogspot.kr/2016/03/opengldirectx.html

No comments:

Post a Comment