X12Camera

Win10 X12Camera

DirectX 12 アプリ(ユニバーサル Windows)に MyCamera を組み込みます。

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

プロジェクトの作成

  1. DirectX 12 アプリは、見かけは DirectX 11 アプリと変わりませんが、プログラム的には相当な違いがあるようです。
    システムで面倒を見ていた処理が、ユーザーレベルに降りてきた感じで、X11 に比べてプログラムが面倒です。
    但し、MyCamera の組み込みに関しては Win10 MyCamera と同じ要領です。
  2. Win10 Template を参照して DirectX 12 アプリ(ユニバーサル Windows)を作成して下さい。
    Win10 MyCamera から MyCamera.h と MyCamera.cpp を Content\ のフォルダーに格納してプロジェクトに追加します。
  3. Sample3DSceneRenderer.h で MyCamera.h を組み込んで、Class MyCamera の領域を定義します。
    #include "MyCamera.h"
        MyCamera        *my_camera = nullptr;
    
  4. Sample3DSceneRenderer.cpp の Constructor で MyCamera を生成します。
    引数として m_deviceResources を渡して下さい。
    MyCamera の Constructor では、一般的な値でカメラ座標を初期化しています。
    Sample3DSceneRenderer::Sample3DSceneRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
        m_loadingComplete(false),
        m_radiansPerSecond(XM_PIDIV4),  //1 秒間に 45 度の速度で回転させます
        m_angle(0),
        m_tracking(false),
        m_mappedConstantBuffer(nullptr),
        m_deviceResources(deviceResources)
    {
        LoadState();
        ZeroMemory(&m_constantBufferData, sizeof(m_constantBufferData));
    
        CreateDeviceDependentResources();
        CreateWindowSizeDependentResources();
        my_camera = new MyCamera(m_deviceResources);
    }
    
  5. CreateWindowSizeDependentResources() からは Projection() を呼び出します。
    X12 では viewport の設定が追加されています。
    void Sample3DSceneRenderer::CreateWindowSizeDependentResources()
    {
        D3D12_VIEWPORT viewport = m_deviceResources->GetScreenViewport();
        m_scissorRect = { 0, 0, static_cast<LONG>(viewport.Width), static_cast<LONG>(viewport.Height) };
        if (my_camera!=nullptr) my_camera->Projection();
    }
    
  6. Rotate() 関数では、回転情報を my_camera->model に設定します。
    void Sample3DSceneRenderer::Rotate(float radians)
    {
        XMStoreFloat4x4(&my_camera->m_model, XMMatrixTranspose(XMMatrixRotationY(radians)));
    }
    
  7. Render() 関数では MyCamera の描画環境(m_projection, m_view, m_model)を m_constantBufferData に設定します。
    DirectX 11 アプリと比べて、かなり違いがあるようです。
    bool Sample3DSceneRenderer::Render()
    {
        // 読み込みは非同期です。読み込みが完了した後にのみ描画してください。
        if (!m_loadingComplete)
        {
            return false;
        }
    
        DX::ThrowIfFailed(m_deviceResources->GetCommandAllocator()->Reset());
    
        // ExecuteCommandList() が呼び出された後、コマンド一覧をいつでもリセットできます。
        DX::ThrowIfFailed(m_commandList->Reset(m_deviceResources->GetCommandAllocator(), m_pipelineState.Get()));
    
        //☆ camera の情報を設定
        m_constantBufferData.projection = my_camera->m_projection;
        m_constantBufferData.view = my_camera->m_view;
        m_constantBufferData.model = my_camera->m_model;
    
        PIXBeginEvent(m_commandList.Get(), 0, L"Draw the cube");
        {
            //このフレームで使用されるグラフィックのルート署名と記述子ヒープを設定します。
            m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());
            ID3D12DescriptorHeap* ppHeaps[] = { m_cbvHeap.Get() };
            m_commandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);
    
            // 現在のフレームの定数バッファーをパイプラインにバインドします。
            CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHandle(m_cbvHeap->GetGPUDescriptorHandleForHeapStart(), m_deviceResources->GetCurrentFrameIndex(), m_cbvDescriptorSize);
            m_commandList->SetGraphicsRootDescriptorTable(0, gpuHandle);
    
            // ビューポートとシザリング四角形を設定します。
            D3D12_VIEWPORT viewport = m_deviceResources->GetScreenViewport();
            m_commandList->RSSetViewports(1, &viewport);
            m_commandList->RSSetScissorRects(1, &m_scissorRect);
    
            //このリソースをレンダー ターゲットとして使用することを指定します。
            CD3DX12_RESOURCE_BARRIER renderTargetResourceBarrier =
                CD3DX12_RESOURCE_BARRIER::Transition(m_deviceResources->GetRenderTarget(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
            m_commandList->ResourceBarrier(1, &renderTargetResourceBarrier);
    
            //描画コマンドを記録します。
            D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView = m_deviceResources->GetRenderTargetView();
            D3D12_CPU_DESCRIPTOR_HANDLE depthStencilView = m_deviceResources->GetDepthStencilView();
            m_commandList->ClearRenderTargetView(renderTargetView, DirectX::Colors::CornflowerBlue, 0, nullptr);
            m_commandList->ClearDepthStencilView(depthStencilView, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
    
            m_commandList->OMSetRenderTargets(1, &renderTargetView, false, &depthStencilView);
    
            m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
            m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
            m_commandList->IASetIndexBuffer(&m_indexBufferView);
            m_commandList->DrawIndexedInstanced(36, 1, 0, 0, 0);
    
            //レンダー ターゲットが、コマンド リストがいつ実行を完了するかを表すために使用されることを示します。
            CD3DX12_RESOURCE_BARRIER presentResourceBarrier =
                CD3DX12_RESOURCE_BARRIER::Transition(m_deviceResources->GetRenderTarget(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
            m_commandList->ResourceBarrier(1, &presentResourceBarrier);
        }
        PIXEndEvent(m_commandList.Get());
    
        DX::ThrowIfFailed(m_commandList->Close());
    
        //コマンド リストを実行します。
        ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
        m_deviceResources->GetCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
    
        return true;
    }
    

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