MyCamera

Win10 MyCamera

Windows10 Direct3D で MyCamera を組み込みます。

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

プロジェクトの作成

  1. class MyCamera でプロジェクションやビュー座標やモデルの姿勢などを一元管理します。
    Win10 Template を参照して DirectX 11 アプリ(ユニバーサル Windows)を作成して下さい。
    カラーキューブが回転しながら描画されます。
    プロジェクトの名前は App1 になっています。
  2. Content\ のフォルダーに Class MyCamera のファイルを格納してプロジェクトに追加します。
    ソースコードはこの後に掲載します。
    ファイル 説明
    Content\MyCamera.h MyCamera の Header File
    Content\MyCamera.cpp MyCamera の Program File
  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_degreesPerSecond(45),
        m_indexCount(0),
        m_tracking(false),
        m_deviceResources(deviceResources)
    {
        CreateDeviceDependentResources();
        CreateWindowSizeDependentResources();
        my_camera = new MyCamera(m_deviceResources);
    }
    
  5. CreateWindowSizeDependentResources() では Projection() を呼ぶだけです。
    void Sample3DSceneRenderer::CreateWindowSizeDependentResources()
    {   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 に設定します。
        m_constantBufferData.projection = my_camera->m_projection;
        m_constantBufferData.view = my_camera->m_view;
        m_constantBufferData.model = my_camera->m_model;
    
    DrawIndexed でモデルを描画します。
        context->DrawIndexed(
            m_indexCount, 0, 0);
    
    Render() 関数全体のソースコードです。
    void Sample3DSceneRenderer::Render()
    {
        // 読み込みは非同期です。読み込みが完了した後にのみ描画してください。
        if (!m_loadingComplete)
        {   return;  }
    
        auto context = m_deviceResources->GetD3DDeviceContext();
    
        m_constantBufferData.projection = my_camera->m_projection;
        m_constantBufferData.view = my_camera->m_view;
        m_constantBufferData.model = my_camera->m_model;
    
        // 定数バッファーを準備して、グラフィックス デバイスに送信します。
        context->UpdateSubresource(
            m_constantBuffer.Get(), 0, NULL,
            &m_constantBufferData, 0, 0);
    
        // 各頂点は、VertexPositionColor 構造体の 1 つのインスタンスです。
        UINT stride = sizeof(VertexPositionColor);
        UINT offset = 0;
        context->IASetVertexBuffers(
            0, 1, m_vertexBuffer.GetAddressOf(),
            &stride, &offset);
    
        context->IASetIndexBuffer(
            m_indexBuffer.Get(),
            DXGI_FORMAT_R16_UINT, //各インデックスは、1 つの 16 ビット符号なし整数 (short) です。
            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_indexCount, 0, 0);
    }
    
  8. class MyCamera の Header File です。
    m_eye, m_at, m_up には、元の Sample3DSceneRenderer に習って定義しています。
    // MyCamera Header File  Ver-1  前田 稔
    #pragma once
    #include "..\Common\DeviceResources.h"
    using namespace DirectX;
    
    class MyCamera
    { public:
        MyCamera(std::shared_ptr<DX::DeviceResources>& deviceResources);
        void Projection();
    
        XMVECTOR    m_eye = { 0.0f, 0.7f, 1.5f, 0.0f };
        XMVECTOR    m_at = { 0.0f, -0.1f, 0.0f, 0.0f };
        XMVECTOR    m_up = { 0.0f, 1.0f, 0.0f, 0.0f };
    
        XMFLOAT4X4 m_projection;
        XMFLOAT4X4 m_view;
        XMFLOAT4X4 m_model;
    
      private:
        std::shared_ptr<DX::DeviceResources> m_deviceResources;
    };
    
  9. class MyCamera の Program File です。
    Constructor で標準的な projection, view, model を設定します。
    Projection() はウインドウサイズが変更されたときに呼び出される関数です。
    /*****************************************/
    /* MyCamera Program File  Ver-1  前田 稔 */
    /*****************************************/
    #pragma once
    
    #include "pch.h"
    #include "..\Common\DirectXHelper.h"
    #include "MyCamera.h"
    using namespace Windows::Foundation;
    
    MyCamera::MyCamera(std::shared_ptr<DX::DeviceResources>& deviceResources)
    {
        m_deviceResources = deviceResources;
        Projection();
        XMStoreFloat4x4(&m_view, XMMatrixTranspose(XMMatrixLookAtRH(m_eye, m_at, m_up)));
        XMStoreFloat4x4(&m_model, XMMatrixIdentity());
    }
    
    void MyCamera::Projection()
    {
        Size outputSize = m_deviceResources->GetOutputSize();
        float aspectRatio = outputSize.Width / outputSize.Height;
        float fovAngleY = 70.0f * XM_PI / 180.0f;
        if (aspectRatio < 1.0f)
        {   fovAngleY *= 2.0f;  }
        XMMATRIX perspectiveMatrix = XMMatrixPerspectiveFovRH(
        fovAngleY, aspectRatio, 0.01f, 100.0f);
    
        XMFLOAT4X4 orientation = m_deviceResources->GetOrientationTransform3D();
        XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);
        XMStoreFloat4x4(&m_projection, XMMatrixTranspose(perspectiveMatrix * orientationMatrix));
    }
    
  10. 今回の MyCamera は自動生成のプロジェクトに合わせて極力シンプルにコーディングしてみました。
    MyCamera の基本的な説明は Win10 CameraRot を参照して下さい。
    用途に合わせて順次バージョンアップしていく予定です。

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