2016-06-19 5 views
0

以前は、メッシュごとに別々の頂点とインデックスバッファを使用していましたが、DrawIndexed()呼び出しを減らすために単一の大きな頂点バッファを使用したいと思います。私は次の配列を持っているとしましょう:単一の頂点バッファで複数の三角形をレンダリングする

SimpleVertex vertices[] = 
{ 
    { XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) }, 
}; 

WORD indices[] = 
{ 
    3,1,0, 
    2,1,3, 

    0,5,4, 
    1,5,0, 

    3,4,7, 
    0,4,3, 

    1,6,5, 
    2,6,1, 

    2,7,6, 
    3,7,2, 

    6,4,5, 
    7,4,6, 
}; 

これは単一のインデックス付きキューブに最適です。しかし、もし私が2つの立方体を描こうとすればどうですか?インデックスバッファを設定するにはどうすればよいですか?そこで、基本的

SimpleVertex vertices[] = 
{ 
    //first cube 
    { XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) }, 
    //second cube 
    { XMFLOAT3(-2.0f, 2.0f, -2.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(2.0f, 2.0f, -2.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(2.0f, 2.0f, 2.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(-2.0f, 2.0f, 2.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(-2.0f, -2.0f, -2.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(2.0f, -2.0f, -2.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) }, 
    { XMFLOAT3(2.0f, -2.0f, 2.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) }, 
    { XMFLOAT3(-2.0f, -2.0f, 2.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) }, 
}; 
WORD indices[] = 
{ 
    //First cube 
    3,1,0, 
    2,1,3, 

    0,5,4, 
    1,5,0, 

    3,4,7, 
    0,4,3, 

    1,6,5, 
    2,6,1, 

    2,7,6, 
    3,7,2, 

    6,4,5, 
    7,4,6, 

    //second cube 
    11,9,8, 
    10,9,11, 

    8,13,12, 
    9,13,8, 

    11,12,15, 
    8,12,11, 

    9,14,13, 
    10,14,9, 

    10,15,14, 
    11,15,10, 

    14,12,13, 
    15,12,14, 
}; 

が、私はどのように理解しようとしている:彼らはのようなインクリメントしなければならない場合、私は、インデックスが各キューブに対してローカルであるかどうかについて混乱しているので、ちょうどすべての36個の指標を繰り返す必要があり、または複数のオブジェクトを持つ1つの大きなインデックスバッファを描画します。私はこれについて正しく考えていますか、バッファを何度も同じインデックスバッファを再利用する必要がありますか?

私はInstancingを使用していることに気付いていますが、ジオメトリが変更される場合がありますので、この場合は避ける必要があります。

答えて

0

理論的に盲目的な攻撃のコードを書き始めることに決めました。大きな頂点配列を1つのメッシュとして扱うためには、インデックス配列をインクリメントする必要があります。私が興味のある人のためにこれを説明するための関数を書いた:あなたはそれで終わった後

UINT* VertexCompiler::BuildIndexArray() 
{ 
    UINT* indices; 

    int indexCount = 0; 

    for (int i = 0; i < (int)mVertexObjects.size(); i++) 
     indexCount += mVertexObjects[i].NumIndices; 

    mIndexCount = indexCount; 

    indices = new UINT[indexCount]; 

    int numObjects = (int)mVertexObjects.size(); 
    int index = 0; 


    for (int i = 0; i < numObjects; i++) 
    { 
     for (int j = 0; j < (int)mVertexObjects[i].NumIndices; j++) 
     { 
      indices[index] = mVertexObjects[i].Indices[j] + (mVertexObjects[i].NumVertices * i); 
      index++; 
     } 

    } 

    return indices; 
} 

は、インデックスへのポインタを削除してください。通常は、関数内でメモリを割り当てて外部で削除するのは貧弱な設計ですが、デモンストレーションの目的にすぎません。通常は、インデックス配列を外部に割り当て、それを関数へのポインタとして渡す必要があります。

重要な点は、UINTを使用することです。サブジェクトのほとんどの教科書と記事は、WORDでより小さなインデックスバッファを割り当てます。インクリメントされたインデックス配列は、WORDメモリ割り当てを使用してインデックス値65535でオーバーフローします。したがって、インデックスが16ビットを超える多数の頂点をレンダリングする場合は、UINTを使用し、DXGI_FORMAT_R16_UINTの代わりにDXGI_FORMAT_R32_UINTに切り替えることを忘れないでください。

など。

IASetIndexBuffer(indicesBuffer, DXGI_FORMAT_R32_UINT, 0); 
+0

インデックスのインスタンス化を解除する必要がある理由はまだ不明です。すべてのオブジェクトの頂点とインデックスが単一のバッファにある場合。 DrawIndexedInstancedには、固定値をインデックスに追加するためのパラメータがあり、同様に頂点の読み取りをオフセットするためのパラメータもあります。ドローコールの間で状態を変更しない限り、それらはかなり安い(dx12では安いが、それでも安い)。 – galop1n

関連する問題