WebGL 2シリーズの頂点配列オブジェクト

6636 ワード

頂点バッファリングテクノロジーを使用すると、ペイント効率が大幅に向上します.しかし、頂点の位置座標、法線ベクトル、テクスチャ座標などの異なるデータが使用されるたびに個別に指定され、不要な作業が繰り返される点が望ましくない.WebGL 2は、この問題を解決するためのオブジェクトである頂点配列オブジェクト(VAO)を提供する.このセクションでは、頂点配列オブジェクトについて説明します.
頂点配列オブジェクト(WebGL 1)は、OES_という名前の拡張オブジェクトです.vertex_array_object;WebGL 2では直接使用できます.WebGL 1で既にOESを使っていたらvertex_array_objectでは、WebGL 2とWebGL 1の呼び出し方法の違いを知るだけでいいです.
頂点配列オブジェクトについて詳しく説明します.
頂点配列オブジェクト
頂点配列オブジェクト(VAO)は、頂点プロセッサに関連するすべてのデータをカプセル化し、頂点キャッシュ領域とインデックスバッファの参照を記録し、実際のデータではなく頂点の様々な属性のレイアウトを記録するオブジェクトです.
頂点配列オブジェクトの利点
このような利点は、オブジェクトにVAOを指定すると、そのVAOオブジェクトを簡単にバインドすることで、オブジェクトのすべての参照とステータスをtonがインポートできることです.後でオブジェクトを描画するときは、オブジェクトの参照やステータスを手動でインポートする必要はありません.VCOはそれを覚えています.VAOによりバッファのバインディングプロセスを簡素化することができ,コードの呼び出し回数を減らすことができ,WebGL状態切替の効率を向上させることができる.
ケース:頂点配列オブジェクトで2つの三角形を描画する
次に、頂点配列オブジェクトの使用をコードで説明します.このケースコードでは、2つの頂点色の三角形を描き、最終的に表示される効果は次のとおりです.
var triangleArray = gl.createVertexArray();
        gl.bindVertexArray(triangleArray);

        var positions = new Float32Array([
            -0.5, -0.5, 0.0,
            0.0, -0.5, 0.0,
            0.0, 0.0, 0.0
        ]);
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0
        ]);
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

        var triangleArray2 = gl.createVertexArray();
        gl.bindVertexArray(triangleArray2);

        var positions2 = new Float32Array([
            0.0, -0.0, 0.0,
            0.5, 0.0, 0.0,
            0.0, 0.5, 0.0
        ]);
        var positionBuffer2 = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer2);
        gl.bufferData(gl.ARRAY_BUFFER, positions2, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors2 = new Float32Array([
            1.0, 1.0, 0.0,
            0.0, 1.0, 1.0,
            0.0, 1.0, 1.0
        ]);
        var colorBuffer2 = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer2);
        gl.bufferData(gl.ARRAY_BUFFER, colors2, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);
        ////////////////
        // DRAW
        ////////////////
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.bindVertexArray(triangleArray);
        gl.drawArrays(gl.TRIANGLES, 0, 3);

        gl.bindVertexArray(triangleArray2);
        gl.drawArrays(gl.TRIANGLES, 0, 3);

三角形関連データとバッファの定義
まず、三角形を定義した頂点データとバッファはWebGL 1のコードと似ています.次は三角関係データ定義のコードです.
var triangleArray = gl.createVertexArray();
        gl.bindVertexArray(triangleArray);

        var positions = new Float32Array([
            -0.5, -0.5, 0.0,
            0.0, -0.5, 0.0,
            0.0, 0.0, 0.0
        ]);
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0
        ]);
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

最初の2行で作成されたVAOとバインドされたVAOコードを除いて、他のコードはWebGL 1と同じコードであることがわかります.
  • 座標配列
  • を定義する.
  • 頂点座標バッファ
  • を作成する.
  • バッファをバインドし、バッファデータ
  • を埋め込む.
  • バッファをattribute変数
  • に割り当てる
  • attribute変数
  • を有効にする
    コードには、頂点座標と頂点カラーの2つの頂点情報が定義されています.
    別の三角形の関連データを作成するコードは、説明を繰り返さずに最初と類似しています.
    VAOオブジェクトの頂点データ作成における役割
    前の2行のコードに戻ります.
    var triangleArray = gl.createVertexArray();
    gl.bindVertexArray(triangleArray);

    1行目のコードはVAOオブジェクトを作成し、2行目のコードはVAOオブジェクトをバインドする.この2行目のコードの役割は、頂点バッファオブジェクトの操作と状態について、このVAOオブジェクトに記録され、後で描画するときはglを呼び出すだけである.bindVertexArrayメソッドでは、オブジェクトをバインドすると、関連するステータスが自動的に使用されます.
    VAOオブジェクトの描画時の役割
    次に、描画されたコードを見てみましょう.
           gl.clear(gl.COLOR_BUFFER_BIT);//        
            //         
            gl.bindVertexArray(triangleArray);
            gl.drawArrays(gl.TRIANGLES, 0, 3);
            //         
            gl.bindVertexArray(triangleArray2);
            gl.drawArrays(gl.TRIANGLES, 0, 3);

    最初の行のコードは、カラーバッファをクリアし、WebGL 1と同じです.最初の三角形を描きます
  • glを先に呼び出す.bindVertexArray(triangleArray)は、最初の三角形に関連するバッファ状態を回復し、
  • からglが呼び出される.drawaArrays(gl.TRIANGLES,0,3)描画
  • 2番目の三角形と1番目の三角形を描画します.振り返ると、頂点配列オブジェクトを使用しない場合、最初の三角形を描くコードは次のとおりです.
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(0);
            gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
            gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(1);
    
            gl.drawArrays(gl.TRIANGLES, 0, 3);

    2番目の三角形を描くのと似ていることから、VAOオブジェクトを使用する後、gl.bindVertexArrayの行コードは、次のコードに相当します.
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(0);
            gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
            gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(1);

    つまり、バッファオブジェクトをバインドしたり、attributeを割り当てたり、attribute変数を有効にしたりすることで、ペイント時に呼び出さなくてもいいです.VAOオブジェクトを使用するメリットは、次のとおりです.
  • コード量を減らし、開発効率を高める
  • は、描画効率を向上する(WebGL関連関数の呼び出しを低減し、WebGL内部でVAOを最適化するため)
  • .
    WebGL 1でのVAOの使い方
    WebGL 1.0のVAOは拡張方式で提供されており、まず対応する拡張オブジェクトを取得する必要があります.
    var ext = gl.getExtension("OES_vertex_array_object");

    返されたextビットnullがブラウザが拡張をサポートしていないことを示している場合.上のextオブジェクトがあれば、VAOを作成できます.
    var vao = ext.createVertexArrayOES();

    VAOオブジェクトがあれば、バインド操作を行うことができます.
    // bind
    ext.bindVertexArrayOES(vao);
    // unbind
    ext.bindVertexArrayOES(null);