できてること
- webglで単純な何かを2Dで出す
- 何かを出すのにはインデックスバッファを用いる
やりたいこと
- 効率よくprimitiveな形状を出す
- primitiveな形状には2D用のものと3D用のものがある
- 2d Rectangle Circle 等
- 3d Box Sphere Cylinder 等
- 2dのものはどう考えても値がいじられまくる
- 3dのものは明らかに頂点情報を用意してやる以外に方法がない
考えていること
- 基本的な形状用の固定バッファを作る?
- それとも基本形状のデータはそのままシェーダに渡せる形式にする?
サンプル
共通事項
- rect は left top rigth bottom にアクセスできる
- gl には glのコンテキストが入っている
- 必要に応じてプリミティブ表示のためにrenderRectが呼ばれる
- gl に渡す position は vec3 であるため z軸に相当する部分は適当に埋めている
- glソースコンパイルやuseProgramはここより前に完了しているものとして変数programにそのプログラムオブジェクトが入っているとする
1 の場合
var buffer = { };
var att = {};
buffer.vp = gl.createBuffer();
buffer.vpd = new Float32Array(12);
buffer.index = gl.createBuffer();
buffer.indexd = new Int16Array( [0 , 1 , 2 , 1 , 2 , 3] );
att.position = gl.getAttribLocation( program, "position");
renderRect = function(rect)
{
buffer.vpd[0] = rect.left;
buffer.vpd[1] = rect.top;
buffer.vpd[2] = 0;
buffer.vpd[3] = rect.left;
buffer.vpd[4] = rect.bottom;
buffer.vpd[5] = 0;
buffer.vpd[6] = rect.right;
buffer.vpd[7] = rect.top;
buffer.vpd[8] = 0;
buffer.vpd[9] = rect.right;
buffer.vpd[10] = rect.bottom;
buffer.vpd[11] = 0;
gl.bindBuffer( gl.ARRAY_BUFFER , buffer.vp);
gl.bindData( gl.ARRAY_BUFFER , buffer.vpd, gl.STATIC_DRAW);
gl.vertexAttribPointer(att.position,3,gl.FLOAT,0,0);
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER , buffer.index);
gl.bindData( gl.ELEMENT_ARRAY_BUFFER , buffer.indexd, gl.STATIC_DRAW);
gl.drawElements(gl.TRIANGLES , rectBuf.index.length, gl.UNSIGNED_SHORT, 0);
}
- 結局毎回書き換えなければならない
- 但し各形状が持つデータは最小限でよさそう
2 の場合
var buffer = { };
var att = {};
buffer.index = gl.createBuffer();
buffer.indexd = new Int16Array( [0 , 1 , 2 , 1 , 2 , 3] );
att.position = gl.getAttribLocation( program, "position");
class Rectangle
{
constructor(left,top,right,bottom)
{
this.vpd = new Float32Array(12);
this.vpd[0] = left;
this.vpd[1] = top;
this.vpd[2] = 0;
this.vpd[3] = left;
this.vpd[4] = bottom;
this.vpd[5] = 0;
this.vpd[6] = right;
this.vpd[7] = top;
this.vpd[8] = 0;
this.vpd[9] = right;
this.vpd[10] = bottom;
this.vpd[11] = 0;
}
}
renderRect = function(rect)
{
gl.bindBuffer( gl.ARRAY_BUFFER , rect.vp);
gl.bindData( gl.ARRAY_BUFFER , rect.vpd, gl.STATIC_DRAW);
gl.vertexAttribPointer(att.position,3,gl.FLOAT,0,0);
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER , buffer.index);
gl.bindData( gl.ELEMENT_ARRAY_BUFFER , buffer.indexd, gl.STATIC_DRAW);
gl.drawElements(gl.TRIANGLES , rectBuf.index.length, gl.UNSIGNED_SHORT, 0);
}
- 明らかにデータ量が増える
- 明らかにパラメータ変更にかかるコストが増える
まとめ
- Rectangleのような2Dの単純な形状では1のほうがよさそうだと感じた
- RectangleやCircleは2Dでの単純な衝突判定などに用いられるため、単純に更新しやすいほうがよいし、データ量が少ないほうがよいと思われる
- それ以外,例えば4頂点すべて を持つ四角形や3Dでの基本形状であれば結局すべての頂点を保持するだろうから、2の形式のほうがよさそうだと思われる
- 今回は基本形状で考えたが、3Dモデル等は必然的にモデルが頂点すべてを保持し、管理する2の形式になると思われる