OBJ Tex-2

Win10 OBJ Multi Texture

Windows10(Store) DirectX3D で OBJ Multi Texture Model を描画します。

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

プログラムの説明

  1. Windows10(ストアアプリ)で Wavefront の「頂点+法線+複数テクスチャ+色」が設定されたモデルを描画します。
    Win10 OBJ Model では頂点座標だけのモデルを描画しました。
    Win10 OBJ Normal Model では「頂点+法線」のモデルを描画しました。
    Win10 OBJ Color Model では「頂点+法線+色」のモデルを描画しました。
    Win10 OBJ Texture Model では「頂点+法線+テクスチャ+色」のモデルを描画しました。
    今回は複数のテクスチャを貼り付けたモデルを描画します。
  2. 「頂点+法線+複数テクスチャ+色」のモデルを定義した cube.obj は、一枚のテクスチャを貼り付けるモデルと同じです。
    Win10 OBJ Texture Model を参照して下さい。
  3. material.mtl のソースコードです。
    OBJ Model File と同様に Shift-JIS でタイプして下さい。
    map_Kd が貼り付けるテクスチャ画像ファイルの名前ですが star.jpg, kishi.jpg, test.jpg, white.jpg の4種類の画像が使われています。
    事前にプロジェクトのフォルダーに画像ファイルを格納して下さい。
    white.jpg はテクスチャを使わないときに使用する全面が白の画像です。
    #エメラルド
    newmtl emerald
    Ns 600
    d 1
    Ni 0.001
    illum 2
    Ka 0.0215  0.1745   0.0215
    Kd 0.07568 0.61424  0.07568
    Ks 0.633   0.727811 0.633
    map_Kd star.jpg
    
    #真珠
    newmtl pearl
    Ns 88
    d 1
    Ni 0.001
    illum 2
    Ka 0.25     0.20725  0.20725
    Kd 1.0      0.829    0.829
    Ks 0.296648 0.296648 0.296648
    map_Kd kishi.jpg
    
    #サファイア
    newmtl sapphire
    Ns 100
    d 1
    Ni 0.001
    illum 2
    Ka 0.05375  0.05     0.1625
    Kd 0.3275   0.375    0.925
    Ks 0.332741 0.328634 0.346435
    map_Kd test.jpg
    
    #ひすい
    newmtl jade
    Ns 100
    d 1
    Ni 0.001
    illum 2
    Ka 0.135    0.2225   0.1575
    Kd 0.54     0.89     0.63
    Ks 0.316228 0.316228 0.316228
    map_Kd white.jpg
    
    #ルビー
    newmtl ruby
    Ns 60
    d 1
    Ni 0.001
    illum 2
    Ka 0.1745   0.01175   0.01175
    Kd 0.61424  0.04136   0.04136
    Ks 0.727811 0.626959  0.626959
    map_Kd white.jpg
    
    #金
    newmtl gold
    Ns 400
    d 1
    Ni 0.001
    illum 2
    Ka 0.24725  0.1995    0.0745
    Kd 0.75164  0.60648   0.22648
    Ks 0.628281 0.555802  0.366065
    map_Kd star.jpg
    
  4. テクスチャを設定して(切り替えて)描画するコードは、次のようになります。
    ComPtr<ID3D11ShaderResourceView> textureView; が貼り付けるテクスチャの切り替えです。
    描画数は描画する頂点データ個数で、開始 Offset は描画を開始する頂点 Index の開始位置です。
    つまり「textureView を使って、開始から始まる描画数」の頂点データを描画します。
        Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> textureView;
    
        context->PSSetShaderResources(0, 1, textureView.GetAddressOf());
        context->DrawIndexed(描画数, 開始, 0);
    
  5. テクスチャを切り替えて描画するために、Load_OBJ.h で Texture 構造体(TTBL) を定義します。
    テクスチャ画像が切り替わる毎に、描画数と開始位置を記録します。
    // Texture 構造体(TTBL)
    struct  Stex
    {
        Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> textureView;
        uint32  Offset;     // 描画開始 Offset
        uint32  Num;        // 描画数 Index
    };
    
        vector<Stex>    TTBL;       // Texture 構造体(TTBL)
    
  6. AddVertex() 関数に Texture 構造体の設定を追加します。
    m_Vertex.size() が描画開始 Offset です。
    m_Vertex.size() - stex.Offset が今回のテクスチャで描画する数です。
    // Vertex を追加
    void Load_OBJ::AddVertex()
    {
        Stex    stex;
        if (m_idxP.size() > m_idxN.size())  m_NormFlag = false;
        if (m_idxP.size() > m_idxT.size())  m_TexFlag = false;
        // 4角ポリゴン ⇒ 3角ポリゴン
        PX_P3(m_idxP, &m_idxP3);
        if (m_idxN.size() == m_idxP.size()) PX_P3(m_idxN, &m_idxN3);
        if (m_idxT.size() == m_idxP.size()) PX_P3(m_idxT, &m_idxT3);
    
        stex.textureView = MTBL[MT_num].m_textureView;
        stex.Offset = m_Vertex.size();
    
        // 頂点データとインデックスデータを作成
        uint32 vtx_size = m_idxP3.size();
        VertexPosition Vertex;
        uint16 bs = (uint16)m_Index.size();
    
        for(uint32 i=0; i<vtx_size; i++)
        {
            uint32  idx = m_idxP3[i]-1;
            if (idx<m_pos.size())
            {   Vertex.pos.x = m_pos[idx].x;
                Vertex.pos.y = m_pos[idx].y;
                Vertex.pos.z = m_pos[idx].z;
            }
            else    Debug(L"m_pos Index Error", idx);
            if (m_TexFlag)
            {   idx = m_idxT3[i]-1;
                if (idx<m_tex.size())
                {   Vertex.tex.x = m_tex[idx].x;
                    Vertex.tex.y = m_tex[idx].y;
                }
                else    Debug(L"m_tex Index Error", idx);
            }
            if (m_NormFlag)
            {
                idx = m_idxN3[i]-1;
                if (idx<m_norm.size())
                {   Vertex.norm.x = m_norm[idx].x;
                    Vertex.norm.y = m_norm[idx].y;
                    Vertex.norm.z = m_norm[idx].z;
                }
                else    Debug(L"m_norm Index Error", idx);
            }
            Vertex.color.x = MTBL[MT_num].Kd.x;
            Vertex.color.y = MTBL[MT_num].Kd.y;
            Vertex.color.z = MTBL[MT_num].Kd.z;
            Vertex.color.w = 1.0f;
    
            m_Vertex.push_back(Vertex);
            m_Index.push_back(bs + i);
        }
        stex.Num = m_Vertex.size() - stex.Offset;
        TTBL.push_back(stex);
    }
    
  7. Load_OBJ Class にモデルを描画する View() 関数を定義します。
    SetCullMode() と SetTexMode() は使わないので削除して下さい。
    // モデルの描画
    void Load_OBJ::View()
    {
        auto context = m_deviceResources->GetD3DDeviceContext();
        context->RSSetState(m_RasterizerState);
        context->PSSetSamplers(0, 1, m_sampler.GetAddressOf());
        for (uint32 k = 0; k < TTBL.size(); k++)
        {
            context->PSSetShaderResources(0, 1, TTBL[k].textureView.GetAddressOf());
            context->DrawIndexed(TTBL[k].Num, TTBL[k].Offset, 0);
        }
    }
    
  8. Sample3DSceneRenderer::Render() で描画するときは、View() 関数を呼び出すだけです。
        // ピクセル シェーダーをアタッチします。
        context->PSSetShader(
            m_pixelShader.Get(),
            nullptr,
            0
            );
    
        model->View();
    }
    

[Previous Chapter ↑] Win10 OBJ Model

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