4

私はD3D11を使ったゲームプログラミングの基本についての本をフォローしています。Direct3Dの絶対的な基本を理解しました:)

しかし...質問があります。この本では、私は常に一度に1つのデモを作成する必要がありました。今、私はそれを使って2Dゲームを作ろうとしています。悪い習慣に慣れたくないのでアドバイスが必要です。

この本では、常に(texcoordとpositionメンバーを使用してVertexPosを構築する)OR(XMFLOAT3ポジションメンバーのみを使用してVertexPosを構築する)を定義する必要がありました。私が作成しているゲームでは、テクスチャのないソリッドサーフェスとテクスチャのあるサーフェスの両方を描画できるようにしたいと考えています。これを効率的に行うことは言うまでもなく、これを行う方法がわかりません。

これが私のレンダリング関数です:

void GameSpriteDemo::Render()
{
    if (m_pD3DContext == 0)
    {return;}

    float ClearColor[4] = {0.0f, 0.0f, 0.25f, 1.0f};
    m_pD3DContext->ClearRenderTargetView(m_pBackBufferTarget,ClearColor);

    UINT stride = sizeof(VertexPos);
    UINT offset = 0;

    m_pD3DContext->IASetInputLayout(m_pInputLayout);
    m_pD3DContext->IASetVertexBuffers(0,1,&m_pVertexBuffer, &stride, &offset);
    m_pD3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    m_pD3DContext->VSSetShader(m_pSolidColorVS,0,0);
    m_pD3DContext->PSSetShader(m_pSolidColorPS,0,0);
    m_pD3DContext->PSSetShaderResources(0,1,&m_pColorMap);
    m_pD3DContext->PSSetSamplers(0,1,&m_pColorMapSampler);

    for(int i=0; i < 2; ++i)
    {
        XMMATRIX world = m_Sprites[i].GetWorldMatrix();
        XMMATRIX mvp = XMMatrixMultiply( world, m_VpMatrix );
        mvp = XMMatrixTranspose(mvp);

        m_pD3DContext->UpdateSubresource(m_pMvpCB,0,0,&mvp,0,0);
        m_pD3DContext->VSSetConstantBuffers(0,1,&m_pMvpCB);

        m_pD3DContext->Draw(6,0);
    }

    m_pSwapChain->Present(0,0);
}

では、複数の頂点バッファー、入力レイアウト、シェーダー、ブレンダーなどを使用して、これをどのように効率的に処理する必要がありますか?

それらの複数のバージョンを作成し、Draw呼び出しの後に入力アセンブリ、シェーダーなどをリセットするように設定する必要がありますか?またはこれは機能しません/これは効率的ではありませんか?

ありがとう :)

4

1 に答える 1

4

簡単な答えはイエスです。複数の頂点バッファー、入力レイアウト、シェーダーなどを作成し、対応する各描画呼び出しの前に適切なものを設定する必要があります。これは機能し、かなり効率的です (最新のハードウェアでの 2D ゲームには十分効率的であるはずです)。

完全な 3D ゲーム エンジンでは、状況が少し複雑になる傾向があります。通常、レンダリング エンジンには、頂点やインデックス バッファー、入力レイアウト、シェーダーなどのプリミティブ オブジェクトの上に階層化された追加の内部レベルの抽象化があります。

物事を構造化する合理的に一般的な単純な方法は、すべての頂点バッファー、インデックス バッファー、入力レイアウト、シェーダー、テクスチャなどを認識する Mesh クラスを用意することです。単一の描画呼び出しであり、それらすべてを設定し (多くの場合、ブレンド モード、カリング モードなどのレンダリング状態の他のビットと共に)、対応する描画呼び出しを発行します。

デバイスの状態の変更にはコストがかかるため、レンダリング エンジンは多くの場合、必要な状態の変更の数を最小限に抑えるために、特定のフレームで描画する必要があるすべてのオブジェクトを試して並べ替えるように設計されています。たとえば、Dawn of War 2 レンダラーでは、すべてのメッシュ ジオメトリを並べ替えて、異なる頂点とインデックス バッファー、テクスチャを使用してすべてのスペース マリーン ボディを描画する前に、最小限の状態変更ですべてのスペース マリーン ヘルメットを描画できるようにしました。等

最新の 3D ハードウェアと API では、状態を変更するためのオーバーヘッドが以前よりもいくらか少ないため、状態の変更を最小限に抑えるための並べ替えは、以前ほど重要ではありませんが、PC で最大のパフォーマンスを得る必要があるゲームでは、依然として一般的な方法です。

スキン アニメーション、地形、パーティクル システム、フル スクリーン効果、2D UI などに加えて、柔軟な照明とマテリアル モデルをサポートするデータ駆動型レンダリング エンジンでは、ゲーム オブジェクトの描画に必要なすべての状態を管理し、最大限の効率で描画できるように並べ替えると、非常に複雑になる可能性があり、物事を構造化するためのさまざまなアプローチがあります。「レンダラーの状態管理」として分類できるすべてのコードは、一般的なレンダリング エンジンのコードのかなりの部分を占めることがよくあります。

于 2011-09-06T23:11:48.320 に答える