矩形ポリゴンを X-FILE に保存する

プログラムで定義した矩形ポリゴンのデータを X-FILE として保存します。
DirectX10 では X-FILE を直接描画することが出来ないようなので、今のうちに X-FILE を解析しておきましょう。 (^_^;)
X-FILE の形式は X-FILE(Cone.x) の頂点データを定義する を参照して下さい。
Java で X-FILE を描画するプログラムを作成しています。
前田稔の超初心者のプログラム入門 から
「超初心者のプログラム入門(Java)」「Loader の作成」から「X-FILE Loader」を参照して下さい。

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

プロジェクトの説明

  1. DirectX Sample Browser で MultiMon10 のプロジェクトを作成して下さい。
    MultiMon10 のプロジェクトをコンパイルして、正常に実行されることを確かめて下さい。
    エラーが発生するときや、正常に実行出来ないときは、残念ながら現在の構成は相性が悪いようです。
  2. MultiMon10 のプロジェクトのフォルダーに次のファイルを格納して下さい。
    ファイル名 説明
    MultiMon10.cpp 矩形ポリゴンを polygon.x の名前で保存
    template.h X-FILE インターフェイスのヘッダファイル
    このプログラムは polygon.x を作成するだけで、描画は行いません。
    作成された polygon.x をダブルクリックで起動して、赤色の矩形が描画されることを確認して下さい。
  3. X-FILE は template と呼ばれる構造体のような記述に従って作成されています。
    従って X-FILE の作成には template が必要です。
    template は Cone.x などから読み込むことも出来るのですが、私は専用のヘッダファイル(template.h)を作成しました。
    X-FILE のインターフェイスを使うには d3dxof.lib をリンクして、dxfile.h をインクルードします。
    これらの処理は template.h の冒頭で行っています。
    #include  <dxfile.h>   // Xファイル関連を使用するのに必要
    #pragma once
    #pragma comment(lib,"d3dxof.lib")
    
  4. Main.cpp の説明です。
    DXUT.h に続いて template.h をインクルードして下さい。
    #include    "DXUT.h"
    #include    "template.h"
    
  5. Mesh(矩形ポリゴン)の定義です。
    template に従って polygon.x の作成に必要な構造体を定義します。
    Header や Material などの構造体は template.h で宣言されています。
    Header は { 1,0,1 } に設定します。
    Material は faceColor, power, specularColor, emissiveColor の順に定義します。
    faceColor を赤色(1.0f, 0.0f, 0.0f, 1.0f)に設定しています。
    // 矩形ポリゴンの定義
    // Header の定義
    struct Header   hed = { 1, 0, 1 };
    struct Material mat = { {1.0f, 0.0f, 0.0f, 1.0f}, 0.0f, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f} };
    
  6. MeshMatList 構造体でマテリアル情報を定義します。
    nMaterials がマテリアル数で、nFaceIndexes がフェース(ポリゴン)数で、faceIndexes がフェースのインデックスです。
    struct MeshMatList
    {   DWORD       nMaterials;
        DWORD       nFaceIndexes;
        DWORD       faceIndexes[1];
    }   matlist = { 1, 1, 0 };
    
  7. MeshNormals で法線ベクトルの情報を定義します。
    nNormals が法線ベクトル数で、normals が法線ベクトル{ 0, 0, -1 }です。
    nFaceNormals がフェース数で、faceNormals がインデックスです。
    一般的には三角形ポリゴンが使われるのですが、今回は四角形ポリゴン{ 4, 0, 0, 0, 0 }で定義します。
    struct  MeshNormals
    {   DWORD               nNormals;
        struct  Vector      normals[1];
        DWORD               nFaceNormals;
        struct  MeshFace4   faceNormals[1];
    }   normal = { 1, { 0, 0, -1 }, 1, { 4, 0, 0, 0, 0 } };
    
  8. MeshFace4 で法線ベクトルのインデックスを定義します。
    nFaceVertexIndices がインデックス数で、faceVertexIndices がインデックスです。
    一般的には三角形ポリゴンで構成されているのですが、今回は矩形なので四角形ポリゴンで定義します。
    // 四角形ポリゴン
    struct MeshFace4
    {   DWORD       nFaceVertexIndices;
        DWORD       faceVertexIndices[4];
    };
    
  9. Mesh 構造体の定義です。
    4 が頂点座標の個数で、四個の座標(X,Y,Z)を定義します。
    続く 1 がフェース数で、{ 4, { 0,1,3,2 } } が矩形ポリゴンのインデックスです。
    // Mesh の定義
    struct
    {   DWORD               nVertices;
        struct  Vector      vertices[4];
        DWORD               nFaces;
        struct  MeshFace    faces[1];
    }   mesh =
    { 4,
      { -1.0f,  1.0f,  0.0f,
         1.0f,  1.0f,  0.0f,
        -1.0f, -1.0f,  0.0f,
         1.0f, -1.0f,  0.0f
      },
      1,
      { 4, { 0,1,3,2 } },
    };
    
  10. WinMain() から polygon.x を作成する SaveXfile() 関数を呼び出します。
    // WinMain()
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
    {
        SaveXfile();
        return 0;
    }
    
  11. SaveXfile() 関数で polygon.x を作成します。
    X-FILE の作成は専用のインターフェイスが用意されています。
    DirectXFileCreate() で IDirectXFile を生成します。
    RegisterTemplates() で template を登録します。
    // データを X-FILE に出力する。
    void  SaveXfile()
    {
            ・・・
        IDirectXFile *pDXFile = NULL;
    
        DirectXFileCreate( &pDXFile );
        if(FAILED(pDXFile->RegisterTemplates(str,(DWORD)strlen(str))))  goto error;
    
  12. CreateSaveObject() で IDirectXFileSaveObject を生成します。
        IDirectXFileSaveObject *pDXSave = NULL;
    
        if(FAILED(pDXFile->CreateSaveObject("polygon.x", DXFILEFORMAT_TEXT, &pDXSave )))
            goto error;
    
  13. CreateDataObject() で pDXData に構造体(Header)のデータを設定します。
    このときユニークIDを使って定義した GUID を指定します。
    SaveData() で pDXData を保存します。
        const GUID Header= { 0x3D82AB43,0x62DA,0x11cf, 0xAB, 0x39, 0x00, 0x20, 0xAF, 0x71, 0xE4, 0x33 };
        IDirectXFileData *pDXData = NULL;
    
        if(FAILED(pDXSave->CreateDataObject( Header, NULL, NULL, sizeof(hed), &hed, &pDXData)))
            goto error;
        if(FAILED(pDXSave->SaveData(pDXData)))  goto error;
        SAFE_RELEASE(pDXData);
    
  14. Mesh を書き出すのですが、Mesh は階層構造になっています。
    CreateDataObject() で pDXData に構造体(Mesh)のデータを設定します。
    続いて pDXChildData に構造体(MeshMaterialList)のデータを設定します。
    続いて pDXChildData2 に構造体(Material)のデータを設定します。
    Material を MeshMaterialList に加えます。
    MeshMaterialList を Mesh に加えます。
        IDirectXFileData *pDXData = NULL;
        IDirectXFileData *pDXChildData = NULL;
        IDirectXFileData *pDXChildData2 = NULL;
    
        if(FAILED(pDXSave->CreateDataObject( Mesh, NULL, NULL, sizeof(mesh), &mesh, &pDXData)))
            goto error;
        if(FAILED(pDXSave->CreateDataObject( MeshMaterialList, NULL, NULL, sizeof(matlist), &matlist, &pDXChildData)))
            goto error;
        if(FAILED(pDXSave->CreateDataObject( Material, NULL, NULL, sizeof(mat), &mat, &pDXChildData2)))
            goto error;
        pDXChildData->AddDataObject(pDXChildData2); 
        pDXData->AddDataObject(pDXChildData); 
        SAFE_RELEASE(pDXChildData2);
        SAFE_RELEASE(pDXChildData);
    
  15. 続いて pDXChildData に構造体(MeshNormals)のデータを設定します。
    MeshNormals を Mesh に加えます。
    これで pDXData が完成したので SaveData() で pDXData を保存します。
        if(FAILED(pDXSave->CreateDataObject( MeshNormals, NULL, NULL, sizeof(normal), &normal, &pDXChildData)))
            goto error;
        pDXData->AddDataObject(pDXChildData); 
        if(FAILED(pDXSave->SaveData(pDXData)))  goto error;
    
  16. X-FILE に保存するプログラムを DirectX9 の メッシュを生成して X-FILE に保存する で作成しています。
    併せて参照して下さい。

超初心者のプログラム入門(DirectX10 game program)