~プログラミング~ DirectX 11の頂点バッファとインデックスバッファ

C++言語でDirectX 11を使ったアプリケーションを開発してみよう。

 

前回は簡単な三角形を表示させる事が出来ましたが、そこでは頂点バッファのみを使ってポリゴンを作成しました。複数のポリゴンが同じ頂点を共有する場合などは、頂点バッファに加えてインデックスバッファを利用すると便利です。

 

ここでは、インデックスバッファも使って2つの三角形を作り表示させてみようと思います。

頂点バッファーを作る

頂点データの準備

頂点データを作ります。

前回とほぼ同じですが、頂点の数が4つになっています。

struct Vertex {
        float pos[ 3 ];
        float col[ 4 ];
};

Vertex g_VertexList[] {
        { { -0.5f,  0.5f, 0.5f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
        { {  0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
        { { -0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
        { {  0.5f,  0.5f, 0.5f }, { 1.0f, 1.0f, 0.0f, 1.0f } }
};

頂点バッファーの作成

頂点データをDirect3Dのパイプラインに流し込む為のバッファーを作成します。

バッファーの作成にはID3D11Device::CreateBufferメソッドを使います。

        D3D11_BUFFER_DESC vbDesc;
        vbDesc.ByteWidth           = sizeof( Vertex ) * 4;
        vbDesc.Usage               = D3D11_USAGE_DEFAULT;
        vbDesc.BindFlags           = D3D11_BIND_VERTEX_BUFFER;
        vbDesc.CPUAccessFlags      = 0;
        vbDesc.MiscFlags           = 0;
        vbDesc.StructureByteStride = 0;

        D3D11_SUBRESOURCE_DATA vrData;
        vrData.pSysMem          = g_VertexList;
        vrData.SysMemPitch      = 0;
        vrData.SysMemSlicePitch = 0;

        hr = m_pDevice->CreateBuffer( &vbDesc, &vrData, &m_pVertexBuffer );
        if ( FAILED( hr ) )
                return hr;

インデックスバッファを作る

インデックスバッファは頂点のポリゴンを構成する頂点の順番を格納する為のバッファです。

インデックスデータの準備

ひとまずグローバル変数として用意してみました。

頂点の順番を6つ指定して2つの三角形を作るようになっています。

配列の型は今回 WORD で作っていますが DWORD なども利用できます。

(配列の型はコンテキストにバッファをセットする時指定できます)

WORD g_IndexList[] {
        0, 1, 2,
        0, 3, 1,
};

インデックスバッファの作成

頂点バッファと同様にID3D11Device::CreateBufferメソッドを使って作成します。

BindFlagsにはD3D11_BIND_INDEX_BUFFERを指定します。

        D3D11_BUFFER_DESC ibDesc;
        ibDesc.ByteWidth           = sizeof( WORD ) * 6;
        ibDesc.Usage               = D3D11_USAGE_DEFAULT;
        ibDesc.BindFlags           = D3D11_BIND_INDEX_BUFFER;
        ibDesc.CPUAccessFlags      = 0;
        ibDesc.MiscFlags           = 0;
        ibDesc.StructureByteStride = 0;

        D3D11_SUBRESOURCE_DATA irData;
        irData.pSysMem          = g_IndexList;
        irData.SysMemPitch      = 0;
        irData.SysMemSlicePitch = 0;

        hr = m_pDevice->CreateBuffer( &ibDesc, &irData, &m_pIndexBuffer );
        if ( FAILED( hr ) )
                return hr;

描画する

必要なオブジェクトが準備出来たら、それらをデバイスコンテキストへセットして描画します。

    UINT strides = sizeof( Vertex );
    UINT offsets = 0;
    m_pImmediateContext->IASetVertexBuffers( 0, 1, &m_pVertexBuffer, &strides, &offsets );
    m_pImmediateContext->IASetIndexBuffer( m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
    m_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

        :
        :

    m_pImmediateContext->DrawIndexed( 6, 0, 0 );

    m_pSwapChain->Present( 0, 0 );

ID3D11DeviceContext::IASetVertexBuffersメソッドで頂点バッファをセットします。

さらにID3D11DeviceContext::IASetIndexBufferメソッドでインデックスバッファをセット。

ここでインデックスバッファの配列の型を指定します。

 

インデックスバッファを使わない場合はID3D11DeviceContext::Drawメソッドで描画していましたが、インデックスバッファを使う場合はID3D11DeviceContext::DrawIndexedメソッドを使います。

 

 

うまく出来たら↓のように表示されるはずです。