Win10 Create Color

Windows10 DirectX3D で Color Model を生成するクラスを組み込みます。

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

プロジェクトの作成

  1. Win10 Create Model で Normal Model を生成するプロジェクトを紹介しているのですが、ちょっと難しいかも知れません。
    そこで前段階として Color Model を生成する Class CreateColor のプロジェクトを紹介します。
    Win10 Template を参照して DirectX 11 アプリ(ユニバーサル Windows)を生成して下さい。
    生成したアプリは「頂点+カラー」のモデルを描画するプロジェクトなのでシェーダー関係はそのまま使えます。
  2. Content\ のフォルダーに Class CreateColor のファイルを格納してプロジェクトに追加します。
    ソースコードはこの後に掲載します。
    ファイル 説明
    Content\CreateColor.h CreateColor の Header File
    Content\CreateColor.cpp CreateColor の Program File
  3. Sample3DSceneRenderer.h で CreateColor.h を組み込んで、Class の領域を定義します。
    #include "CreateColor.h"
    
        CreateColor     *model;
    
  4. Sample3DSceneRenderer.cpp でモデルを生成して描画します。
    model = new CreateColor(m_deviceResources); で Class を生成します。
    model->CreateModel(&m_vertexBuffer, &m_indexBuffer, &m_indexCount); でカラーモデルを取得します。
    void Sample3DSceneRenderer::CreateDeviceDependentResources()
    {
        // シェーダーを非同期で読み込みます。
        auto loadVSTask = DX::ReadDataAsync(L"SampleVertexShader.cso");
        auto loadPSTask = DX::ReadDataAsync(L"SamplePixelShader.cso");
    
        // 頂点シェーダー ファイルを読み込んだ後、シェーダーと入力レイアウトを作成します。
        auto createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData) {
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreateVertexShader(
                    &fileData[0],
                    fileData.size(),
                    nullptr,
                    &m_vertexShader
                    )
                );
    
            static const D3D11_INPUT_ELEMENT_DESC vertexDesc [] =
            {
                { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
                { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            };
    
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreateInputLayout(
                    vertexDesc,
                    ARRAYSIZE(vertexDesc),
                    &fileData[0],
                    fileData.size(),
                    &m_inputLayout
                    )
                );
        });
    
        // ピクセル シェーダー ファイルを読み込んだ後、シェーダーと定数バッファーを作成します。
        auto createPSTask = loadPSTask.then([this](const std::vector<byte>& fileData) {
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreatePixelShader(
                    &fileData[0],
                    fileData.size(),
                    nullptr,
                    &m_pixelShader
                    )
                );
    
            CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer) , D3D11_BIND_CONSTANT_BUFFER);
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreateBuffer(
                    &constantBufferDesc,
                    nullptr,
                    &m_constantBuffer
                    )
                );
        });
    
        // 両方のシェーダーの読み込みが完了したら、メッシュを作成します。
        auto createCubeTask = (createPSTask && createVSTask).then([this]() {
            model = new CreateColor(m_deviceResources);
            model->CreateModel(&m_vertexBuffer, &m_indexBuffer, &m_indexCount); 
        });
    
        // モデルが読み込まれたら、オブジェクトを描画する準備が完了します。
        createCubeTask.then([this]()
        {   m_loadingComplete = true;  });
    }
    
  5. CreateModel(&m_vertexBuffer, &m_indexBuffer, &m_indexCount); で取得したモデルのデータを使って Render() で描画します。
    void Sample3DSceneRenderer::Render()
    {   if (!m_loadingComplete)
        {   return;  }
    
        auto context = m_deviceResources->GetD3DDeviceContext();
        context->UpdateSubresource1(
            m_constantBuffer.Get(), 0, NULL, &m_constantBufferData, 0, 0, 0);
    
        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, 0);
    
        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
        context->IASetInputLayout(m_inputLayout.Get());
    
        context->VSSetShader(m_vertexShader.Get(), nullptr, 0);
        context->VSSetConstantBuffers1(0, 1, m_constantBuffer.GetAddressOf(), nullptr, nullptr);
        context->PSSetShader(m_pixelShader.Get(), nullptr, 0);
    
        context->DrawIndexed(m_indexCount, 0, 0);
    }
    
  6. CreateColor.h のソースコードです。
    // カラーモデルを生成する  前田 稔
    #pragma once
    #include "..\Common\DeviceResources.h"
    struct VertexPositionColor
    {
        DirectX::XMFLOAT3 pos;
        DirectX::XMFLOAT3 color;
    };
    
    namespace App1
    {
    class CreateColor
    {
      public:
        CreateColor(std::shared_ptr<DX::DeviceResources>& deviceResources);
        void CreateModel(
            _Out_ ID3D11Buffer **vertexBuffer,
            _Out_ ID3D11Buffer **indexBuffer,
            _Out_ uint32 *indexCount
            );
    
      private:
        std::shared_ptr<DX::DeviceResources> m_deviceResources;
    };
    }
    
  7. CreateColor.cpp のソースコードです。
    CreateModel() で4面体のカラーモデルを生成します。
    // カラーモデルを生成する  前田 稔
    #pragma once
    
    #include "pch.h"
    #include "CreateColor.h"
    #include "..\Common\DirectXHelper.h"
    using namespace App1;
    using namespace DirectX;
    
    CreateColor::CreateColor(std::shared_ptr<DX::DeviceResources>& deviceResources) :
        m_deviceResources(deviceResources)
    {
    }
    
    void CreateColor::CreateModel(
        _Out_ ID3D11Buffer **vertexBuffer,
        _Out_ ID3D11Buffer **indexBuffer,
        _Out_ uint32 *indexCount
        )
    {
        // 各頂点には、位置と色があります。
        static const VertexPositionColor cubeVertices[] =
        {
            { XMFLOAT3(0.0f,1.22474f,0.0f), XMFLOAT3(1.0f,1.0f,1.0f) },
            { XMFLOAT3(0.0f,-0.40825f,-1.1547f), XMFLOAT3(1.0f,0.0f,0.0f) },
            { XMFLOAT3(-1.0f,-0.40825f,0.57735f), XMFLOAT3(0.0f,1.0f,0.0f) },
            { XMFLOAT3(1.0f,-0.40825f,0.57735f), XMFLOAT3(0.0f,0.0f,1.0f) },
        };
    
        D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
        vertexBufferData.pSysMem = cubeVertices;
        vertexBufferData.SysMemPitch = 0;
        vertexBufferData.SysMemSlicePitch = 0;
        CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
        DX::ThrowIfFailed(
            m_deviceResources->GetD3DDevice()->CreateBuffer(
                &vertexBufferDesc,
                &vertexBufferData,
                vertexBuffer
            ));
    
        static const unsigned short cubeIndices [] =
        {   0,1,3,
            0,2,1,
            0,3,2,
            1,2,3,
        };
    
        *indexCount = ARRAYSIZE(cubeIndices);
        D3D11_SUBRESOURCE_DATA indexBufferData = {0};
        indexBufferData.pSysMem = cubeIndices;
        indexBufferData.SysMemPitch = 0;
        indexBufferData.SysMemSlicePitch = 0;
        CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);
        DX::ThrowIfFailed(
            m_deviceResources->GetD3DDevice()->CreateBuffer(
                &indexBufferDesc,
                &indexBufferData,
                indexBuffer));
    }
    
  8. 今回は自動生成されるプロジェクトに合わせて「頂点座標+色」のモデルを使っているのでプログラムは簡単です。
    モデルが大きすぎる(小さすぎる)ときは eye のZ座標で調整して下さい。
        //static const XMVECTORF32 eye = { 0.0f, 0.7f, 1.5f, 0.0f };
        static const XMVECTORF32 eye = { 0.0f, 0.7f, 3.0f, 0.0f };
    
    Class CreateColor には4面体のモデルしか定義していませんが、同じ要領で他のモデルも加えて下さい。
    「頂点座標+法線ベクトル」のモデルを作成する Class は Win10 Create Model を参照して下さい。

親・子・孫で回転します。
[Next Chapter ↓] Win10 Men4 2Model

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