4

単純な2Dオブジェクトの配列があり、ほとんどが2つの三角形で構成されています。drawTriangles()オブジェクトは非常に単純ですが、各オブジェクトはステンシル操作を使用して描画されるため、すべてのオブジェクトに独自の呼び出しが必要になります。

これらのオブジェクトとその頂点およびインデックスバッファを保存および処理するための最良の方法は何ですか?

私はそれを行ういくつかの異なる方法を考えることができます:

  1. 起動時に、1つの大きな頂点とインデックスバッファを作成し、それに各オブジェクトを追加します。例:

    public function initialize():void{
        for each(object in objectList){
            vertexData.push(object.vertices);
            indexData.push(triangle1, triangle2);
        }
    
        indices  = context3D.createIndexBuffer( numTriangles * 3 );
        vertices = context3D.createVertexBuffer( numVertices, dataPerVertex );
        indices.uploadFromVector( indexData, 0, numIndices );
        vertices.uploadFromVector( vertexData, 0, numVertices );
    }
    

    すべてのオブジェクトのレンダリングループ中に、画面に表示されているオブジェクトを確認し、頂点を更新します。次に、頂点バッファ全体を再アップロードします。その後、表示されているオブジェクトをループして、各オブジェクトの三角形を描画します。drawTriangles()

    public function onRender():void{
        for each(object in objectList){
            if(object.visibleOnScreen)
                object.updateVertexData();
        }
    
        vertices.uploadFromVector( vertexData, 0, numVertices );
    
        for each(object in objectsOnScreen){
            drawTriangles(indices, object.vertexDataOffset, object.numTriangles);
        }
    }
    
  2. 必要な場合にのみ各オブジェクトの頂点データを再アップロードすることを除いて、番号1と同様のことを行うこともできます。

    public function onRender():void{
        for each(object in objectList){
            if(object.visibleOnScreen){
                if(object.hasChanged)
                    vertices.uploadFromVector( vertexData, object.vertexDataOffset, object.numTriangles );
                drawTriangles(indices, object.vertexDataOffset, object.numTriangles);
            }
        }
    }
    
  3. 各フレームに表示されているオブジェクトのみで構成される新しい頂点バッファを作成することもできます。

    public function onRender():void{
        for each(object in objectList){
            if(object.visibleOnScreen){
                vertexData.push(object.vertices);
                indexData.push(triangle1, triangle2);
            }
        }
    
        indices  = context3D.createIndexBuffer( numTriangles * 3 );
        vertices = context3D.createVertexBuffer( numVertices, dataPerVertex );
        indices.uploadFromVector( indexData, 0, numIndices );
        vertices.uploadFromVector( vertexData, 0, numVertices );
    
        for each(object in objectsOnScreen){
            drawTriangles(indices, object.vertexDataOffset, object.numTriangles);
        }
    }
    
  4. 別のオプションは、オブジェクトごとに個別の頂点バッファを作成することです。

    public function initialize():void{
        for each(object in objectList){
            object.indices  = context3D.createIndexBuffer( object.numTriangles * 3 );
            object.vertices = context3D.createVertexBuffer( object.numVertices, dataPerVertex );
        }
    }
    
    public function onRender():void{
        for each(object in objectList){
            if(object.visibleOnScreen){
                if(object.hasChanged)
                    object.vertices.uploadFromVector( object.vertexData, 0, object.numTriangles );
                drawTriangles(indices, 0, object.numTriangles);
            }
        }
    }
    

頂点バッファ全体をフレームごとにアップロードする必要があるため、オプション1は遅くなると想像できます。
オプション2には、変更された頂点データをアップロードするだけでよいという利点がありますが、への複数の呼び出しが発生する可能性がありますuploadFromVector

アップデート

Starlingフレームワークのソース、具体的にはQuadBatchクラスを確認しました:http:
//gamua.com/starling/
https://github.com/PrimaryFeather/Starling-Framework

すべての頂点は事前に手動で変換され、頂点バッファ全体が再構築され、フレームごとにアップロードされるようです。

4

1 に答える 1