Two Model

Win10 Two Model

Windows10 DirectX3D で二体のモデルを並べて描画します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. Windows10 で Class CreateModel を組み込んで、二体のモデルを並べて描画します。
    Win10 Template を参照して DirectX 11 アプリ(ユニバーサル Windows) を生成して下さい。
    生成したアプリは「頂点+カラー」のモデルを描画するプロジェクトです。
    「頂点+法線」のモデルを描画出来るように修正して下さい。
    次に Class CreateModel を組み込んで、多角錐のモデルを描画します。
    詳細は Win10 Create Model を参照して下さい。
  2. Sample3DSceneRenderer.h に "CreateModel.h" を組み込んで、二体のモデル領域を定義します。
    #include "CreateModel.h"
    
        Microsoft::WRL::ComPtr<ID3D11Buffer>        m_vertexBuffer1;
        Microsoft::WRL::ComPtr<ID3D11Buffer>        m_vertexBuffer2;
        Microsoft::WRL::ComPtr<ID3D11Buffer>        m_indexBuffer1;
        Microsoft::WRL::ComPtr<ID3D11Buffer>        m_indexBuffer2;
    
        ModelViewProjectionConstantBuffer   m_constantBufferData1;
        ModelViewProjectionConstantBuffer   m_constantBufferData2;
        uint32          m_indexCount1;
        uint32          m_indexCount2;
        CreateModel     *m_CreateModel;
    
  3. Sample3DSceneRenderer.cpp で二体のモデルを生成して描画します。
    Constructor で m_indexCount1, m_indexCount2 を初期化します。
    Sample3DSceneRenderer::Sample3DSceneRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
        m_loadingComplete(false),
        m_degreesPerSecond(45),
        m_indexCount1(0),
        m_indexCount2(0),
        m_tracking(false),
        m_deviceResources(deviceResources)
    {
        CreateDeviceDependentResources();
        CreateWindowSizeDependentResources();
    }
    
  4. m_constantBufferData1 と m_constantBufferData2 に描画環境を設定します。
        XMStoreFloat4x4(
            &m_constantBufferData1.projection,
            XMMatrixTranspose(perspectiveMatrix * orientationMatrix)
            );
        XMStoreFloat4x4(
            &m_constantBufferData2.projection,
            XMMatrixTranspose(perspectiveMatrix * orientationMatrix)
            );
    
    	static const XMVECTORF32 eye = { 0.0f, 0.7f, 3.0f, 0.0f };
    	static const XMVECTORF32 at = { -1.0f, -0.1f, 0.0f, 0.0f };
    	static const XMVECTORF32 at2 = { 1.0f, -0.1f, 0.0f, 0.0f };
    	static const XMVECTORF32 up = { 0.0f, 1.0f, 0.0f, 0.0f };
    
    	XMStoreFloat4x4(&m_constantBufferData1.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
    	XMStoreFloat4x4(&m_constantBufferData2.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at2, up)));
    
  5. Rotate() 関数では、モデル1をY軸で,モデル2をX軸で回転します。
    void Sample3DSceneRenderer::Rotate(float radians)
    {
        //更新されたモデル マトリックスをシェーダーに渡す準備をします
        XMStoreFloat4x4(&m_constantBufferData1.model, XMMatrixTranspose(XMMatrixRotationY(radians)));
        XMStoreFloat4x4(&m_constantBufferData2.model, XMMatrixTranspose(XMMatrixRotationX(radians)));
    }
    
  6. Render() 関数ではモデル1に続いてモデル2を描画します。
    void Sample3DSceneRenderer::Render()
    {
        // 読み込みは非同期です。読み込みが完了した後にのみ描画してください。
        if (!m_loadingComplete) {  return;  }
    
        //☆モデル1を描画
        auto context = m_deviceResources->GetD3DDeviceContext();
        // 定数バッファーを準備して、グラフィックス デバイスに送信します。
        context->UpdateSubresource(
            m_constantBuffer.Get(), 0, NULL, &m_constantBufferData1, 0, 0);
    
        // 各頂点は、VertexPositionColor 構造体の 1 つのインスタンスです。
        UINT stride = sizeof(VertexPositionColor);
        UINT offset = 0;
        context->IASetVertexBuffers(
            0, 1, m_vertexBuffer1.GetAddressOf(), &stride, &offset);
    
        context->IASetIndexBuffer(
            m_indexBuffer1.Get(), DXGI_FORMAT_R16_UINT, 0);
    
        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
        context->IASetInputLayout(m_inputLayout.Get());
    
        // 頂点シェーダーをアタッチします。
        context->VSSetShader(
            m_vertexShader.Get(), nullptr, 0);
    
        // 定数バッファーをグラフィックス デバイスに送信します。
        context->VSSetConstantBuffers(
            0, 1, m_constantBuffer.GetAddressOf());
    
        // ピクセル シェーダーをアタッチします。
        context->PSSetShader(
            m_pixelShader.Get(), nullptr, 0);
    
        // オブジェクトを描画します。
        context->DrawIndexed(
            m_indexCount1, 0, 0);
    
        //☆モデル2を描画
        context = m_deviceResources->GetD3DDeviceContext();
        context->UpdateSubresource(
            m_constantBuffer.Get(), 0, NULL, &m_constantBufferData2, 0, 0);
    
        stride = sizeof(VertexPositionColor);
        offset = 0;
        context->IASetVertexBuffers(
            0, 1, m_vertexBuffer2.GetAddressOf(), &stride, &offset);
    
        context->IASetIndexBuffer(
            m_indexBuffer2.Get(), DXGI_FORMAT_R16_UINT, 0);
    
        context->DrawIndexed(
            m_indexCount2, 0, 0);
    }
    
  7. カラーモデルでは "COLOR" になっていますが、"NORMAL" に修正します。
        static const D3D11_INPUT_ELEMENT_DESC vertexDesc [] =
        {
            {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
            {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},
        };
    
  8. CreateModel で二体のモデルを生成します。
        // 両方のシェーダーの読み込みが完了したら、メッシュを作成します。
        auto createCubeTask = (createPSTask && createVSTask).then([this] () {
            m_CreateModel = new CreateModel(m_deviceResources);
            m_CreateModel->CreateCone(4, &m_vertexBuffer1, &m_indexBuffer1, &m_indexCount1);
            m_CreateModel->CreateCone(5, &m_vertexBuffer2, &m_indexBuffer2, &m_indexCount2);
        });
    
        // キューブが読み込まれたら、オブジェクトを描画する準備が完了します。
        createCubeTask.then([this] () {
            m_loadingComplete = true;
        });
    
  9. コンパイル&実行すると二体のモデル重なって回転しながら描画されます。
    モデル1はY軸で、モデル2はX軸で回転しながら描画されます。

カメラを振って描画

カメラを左右に振ってモデルが重ならないように描画します。
m_constantBufferData1 と m_constantBufferData2 に設定する「カメラの向き」をX方向に振って設定します。
    static const XMVECTORF32 eye = { 0.0f, 0.7f, 3.0f, 0.0f };
    static const XMVECTORF32 at = { -1.0f, -0.1f, 0.0f, 0.0f };
    static const XMVECTORF32 up = { 0.0f, 1.0f, 0.0f, 0.0f };
    XMStoreFloat4x4(&m_constantBufferData1.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
    static const XMVECTORF32 at2 = { 1.0f, -0.1f, 0.0f, 0.0f };
    XMStoreFloat4x4(&m_constantBufferData2.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at2, up)));
モデルの描画では m_constantBufferData1 と m_constantBufferData2 を使い分けます。
これでモデルが重ならなくなります。
    //☆モデル1を描画
    context->UpdateSubresource(
        m_constantBuffer.Get(), 0, NULL, &m_constantBufferData1, 0, 0);

    //☆モデル2を描画
    context->UpdateSubresource(
        m_constantBuffer.Get(), 0, NULL, &m_constantBufferData2, 0, 0);

超初心者のプログラム入門(DirectX Store)