XLoader Color

XLoader Color

Windows10 の XLoader で「頂点+法線+色」のモデルを描画します。
法線が設定されていないモデル「頂点+色」のときは、プログラムで法線を計算します。

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

XLoader Color Model

  1. XLoader Class で「頂点+法線+色」のモデルを描画します。
    XLoader を組み込むと修正するのは XLoader Class とシェーダ関係だけです。
    Win10 XLoader を参照してベースプロジェクトを作成して下さい。
      System⇒App.cpp⇒App1Main⇒Model⇒XLoader
    
  2. X Model から ConeColor.x をダウンロードしてプロジェクトに組み込んで下さい。
    X-FILE は「頂点+法線+色」で構成されるモデルなら何でも良いので適当に調達して来ても構いません。
    法線が設定されていないモデル(頂点+色)のときは、プログラムで法線を計算するので試してみて下さい。
    モデルの描画が大きすぎる(または小さすぎる)ときは Model Class のカメラで調整して下さい。
    組み込んだ X-FILE のソースを取得するのに BasicReaderWriter.h(.cpp) を使います。
    Windows10 DirectX Library を参照してプロジェクトに加えて下さい。
  3. シェーダーは Win10 Shader から「頂点座標+法線+4色カラー」の物を使って下さい。
    float を使うので ShaderStructures.h で "BasicMath.h" を取り込んで下さい。
  4. XLoader.h のソースコードです。
    X-FILE を解析してモデルのデータを作成して描画するための関数や領域を定義します。
    色(マテリアル)はポリゴン(面)ごとに設定されていて結構解析が面倒です。
    頂点データとポリゴンの関係を解析するのに構造体を使用します。
    float3, float4 は ShaderStructures.h で定義して下さい。
    vector<string> VT; に X-FILE のソースを行で切り分けて格納します。
    #pragma once
    
    #include "..\Common\DeviceResources.h"
    #include "..\Common\StepTimer.h"
    #include "ShaderStructures.h"
    #include "BasicReaderWriter.h"
    #include <vector>
    
    using namespace std;
    using namespace Platform;
    
    // Face 構造体(FTBL)
    struct  Face
    {   int         Num;        // 頂点数
        vector<unsigned short>  Pos;    // 頂点 Index の並び
        vector<unsigned short>  Norm;   // 法線 Index の並び
        int         Midx;       // Material(MTBL) Index(-1:指定なし)
    };
    // Polygon3 構造体(POL3)
    struct  Pol3
    {
        unsigned short  Pos[3];     // 頂点 Index の並び
        unsigned short  Norm[3];    // 法線 Index の並び
        int     Midx;               // Material(MTBL) Index
    };
    // Material 構造体(MTBL)
    struct  Mat
    {   string              matName;
        float4              faceColor;
        float               power;
        float3              specularColor;
        float3              emissiveColor;
    };
    
    namespace App1
    {
        class XLoader
        {
        public:
            XLoader(const std::shared_ptr<DX::DeviceResources>& deviceResources);
            void Load();
            void Draw(ModelViewProjectionConstantBuffer);
            void Release();
    
        private:
            std::shared_ptr<DX::DeviceResources> m_deviceResources;
    
            Microsoft::WRL::ComPtr<ID3D11InputLayout>   m_inputLayout;
            Microsoft::WRL::ComPtr<ID3D11Buffer>        m_vertexBuffer;
            Microsoft::WRL::ComPtr<ID3D11Buffer>        m_indexBuffer;
            Microsoft::WRL::ComPtr<ID3D11VertexShader>  m_vertexShader;
            Microsoft::WRL::ComPtr<ID3D11PixelShader>   m_pixelShader;
            Microsoft::WRL::ComPtr<ID3D11Buffer>        m_constantBuffer;
    
            uint32  m_indexCount;
            bool    m_loadingComplete;
    
            //★ X-FILE の領域
            std::string     m_x;            // X-FILE TEXT
            vector<string>  VT;             // X-FILE を行で切り分け
            int             VT_size;        // VT の大きさ
            vector<Face>    FTBL;           // Face Table
            vector<Pol3>    POL3;           // Polygon3 Table
            vector<Mat>     MTBL;           // Material Table
    
            vector<float3> m_pos;           // 頂点座標
            vector<float3> m_norm;          // 法線ベクトル
            int     m_Line, m_Col, m_Top;
            string  Word;
            bool    m_normflag;             // 法線の取得フラグ
    
            bool Search(char *key);
            void Token();
            bool LineToken();
            bool Setfloat3(char *key, vector<float3> *f3);
            void ComputeNorm(VertexPosition *Vertices, int siz);
            bool SetFTBL();
            bool SetNorm();
            void Convt_3P(bool flg);
            void SetMTBL();
            void MatList();
        };
    }
    
  5. XLoader.cpp のソースコードです。
    Load() 関数で X Model を取得して解析します。
    Draw() 関数でモデルを描画します。
    ポリゴンが裏返るときはカリングモードの設定を参照して下さい。
    X-FILE を解析する全ソースコードは Windows10 X_FILE や Windows10 Load_X Class を参照して下さい。
        // ★X-FILE を入力して解析
        BasicReaderWriter^ reader = ref new BasicReaderWriter();
        Array<byte>^ buf = reader->ReadData("ConeColor.x");
    
    // モデルを描画
    void XLoader::Draw(ModelViewProjectionConstantBuffer BuffData)
    {
        // 読み込みは非同期です。読み込みが完了した後にのみ描画してください。
        if (!m_loadingComplete)
        {   return; }
    
        auto context = m_deviceResources->GetD3DDeviceContext();
    
        // レンダー ターゲットを画面に設定します。
        ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetView() };
        context->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());
    
        // 定数バッファーを準備して、グラフィックス デバイスに送信します。
        context->UpdateSubresource(
            m_constantBuffer.Get(),
            0, NULL, &BuffData, 0, 0);
    
        // 各頂点は、VertexPositionColor 構造体の 1 つのインスタンスです。
        UINT stride = sizeof(VertexPosition);
        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);
    }
    
  6. このプロジェクトは X-FILE Loader_2 をリメークしたものです。
    説明不足な点は、こちらも併せて参照して下さい。
    Win10 MaterialModel でも X-FILE の Color(Material) Model を組み込んで描画しています。

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