筒にテクスチャを貼り付けて保存する

5角形の筒にテクスチャを貼り付けて X File に保存します。

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

プログラムの説明

  1. プログラムで作成した5角形の筒に、テクスチャを貼り付けて X File に保存します。
    X-FILE の基礎は メッシュを生成して X-FILE に保存する を参照して下さい。
    5角形の筒の作成は VertexBuffer で多角形の筒を描画する を参照して下さい。
    筒にテクスチャを貼り付ける方法は 円筒にテクスチャを貼り付けて描画する を参照して下さい。
    このプログラムは model.x を作成するだけで、描画は行っていません。
    作成された model.x をダブルクリックして、正常に描画されることを確認して下さい。
  2. X-FILE のインターフェイスを使うので "template.h" を取り込みます。
    template.h は 矩形ポリゴンを X-FILE に保存する から取得して下さい。
    取得した template.h は DirectX10 の仕様になっているので、DirectX9 に合わせて修正して下さい。
    またテクスチャを貼り付ける為に構造体と GUID の追加が必要です。
  3. ソースコードの先頭部分と、基本構造体の宣言です。
    KAKU は多角形の数で、5角形のときは6を、6角形のときは7を設定します。
    頂点の数は KAKU*2 に、ポリゴン(Face)の数は (KAKU-1)*2 になります。
    /*********************************************************************/
    /* 5角形の筒にテクスチャを貼り付けて X File に保存します    前田 稔 */
    /*********************************************************************/
    #define     NAME    "Save Box"
    #include    "template.h"
    #include    <stdio.h>
    #define     KAKU    6
    
    // 構造体の定義
    struct  MeshNormals
    {   DWORD               nNormals;
        struct  Vector      normals[KAKU*2];
        DWORD               nFaceNormals;
        struct  MeshFace    faceNormals[(KAKU-1)*2];
    };
    struct  Mesh
    {   DWORD               nVertices;
        struct  Vector      vertices[KAKU*2];
        DWORD               nFaces;
        struct  MeshFace    faces[(KAKU-1)*2];
    };
    struct  MeshMaterialList
    {   DWORD               nMaterials;
        DWORD               nFaceIndexes;
        DWORD               faceIndexes[1];
    };
    struct  MeshTextureCoords
    {   DWORD               nTextureCoords;
        struct  Coords2d    textureCoords[KAKU*2];
    };
    
  4. 5角形の筒(model.x)を作成するために、構造体を定義します。
    簡単なデータは、構造体の初期値として定義しています。
    "Ayu.jpg" がテクスチャとして貼り付ける画像です。
    適当な画像をプロジェクトのフォルダーに格納して下さい。
    // Model の定義
    struct  Header      hed = { 1, 0, 1 };
    struct  Mesh        mesh;
    struct  MeshNormals         meshnormal;
    struct  MeshMaterialList    meshmaterial= { 1,1,0 };
    struct  Material            material=
    { 0.7f, 0.7f, 0.7f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
    struct  MeshTextureCoords   meshtexture;
    LPSTR   filename= "Ayu.jpg";
    
  5. 多角形の筒を生成する InitGeometry() 関数です。
    5角形の筒の作成は「VertexBuffer で多角形の筒を描画する」を参照して下さい。
    筒にテクスチャを貼り付ける方法は「円筒にテクスチャを貼り付けて描画する」を参照して下さい。
    HRESULT InitGeometry()
    {   DWORD   i;
        // Mesh, MeshNormals の Vector 設定
        mesh.nVertices= KAKU*2;
        meshnormal.nNormals= KAKU*2;
        for(i=0; i<KAKU; i++)
        {   FLOAT theta = (2*D3DX_PI*i)/(KAKU-1);
            mesh.vertices[2*i+0].x= sinf(theta);
            mesh.vertices[2*i+0].y= -1.0f;
            mesh.vertices[2*i+0].z= cosf(theta);
            mesh.vertices[2*i+1].x= sinf(theta);
            mesh.vertices[2*i+1].y= 1.0f;
            mesh.vertices[2*i+1].z= cosf(theta);
    
            meshnormal.normals[2*i+0].x= sinf(theta);
            meshnormal.normals[2*i+0].y= 0.0f;
            meshnormal.normals[2*i+0].z= cosf(theta);
            meshnormal.normals[2*i+1].x= sinf(theta);
            meshnormal.normals[2*i+1].y= 0.0f;
            meshnormal.normals[2*i+1].z= cosf(theta);
        }
        // Mesh, MeshNormals の face 設定
        mesh.nFaces= (KAKU-1)*2;
        meshnormal.nFaceNormals= (KAKU-1)*2;
        for(i=0; i<mesh.nFaces; i++)
        {   mesh.faces[i].nFaceVertexIndices= 3;
            if (i%2==0)
            {   mesh.faces[i].faceVertexIndices[0]= i+2;
                mesh.faces[i].faceVertexIndices[1]= i+1;
                mesh.faces[i].faceVertexIndices[2]= i;
            }
            else
            {   mesh.faces[i].faceVertexIndices[0]= i;
                mesh.faces[i].faceVertexIndices[1]= i+1;
                mesh.faces[i].faceVertexIndices[2]= i+2;
            }
            meshnormal.faceNormals[i].nFaceVertexIndices= 3;
            meshnormal.faceNormals[i].faceVertexIndices[0]= i;
            meshnormal.faceNormals[i].faceVertexIndices[1]= i+1;
            meshnormal.faceNormals[i].faceVertexIndices[2]= i+2;
        }
        // Texture の設定
        meshtexture.nTextureCoords= KAKU*2;
        for(i=0; i<KAKU; i++)
        {   meshtexture.textureCoords[2*i+0].u= ((FLOAT)i)/(KAKU-1);
            meshtexture.textureCoords[2*i+0].v= 1.0f;
            meshtexture.textureCoords[2*i+1].u= ((FLOAT)i)/(KAKU-1);
            meshtexture.textureCoords[2*i+1].v= 0.0f;
        }
    
        return S_OK;
    }
    
  6. モデルを保存する SaveXfile() 関数です。
    X-FILE の作成は専用のインターフェイスが用意されています。
    X-FILE に保存の基礎は「メッシュを生成して X-FILE に保存する」を参照して下さい。
    X-FILE は階層構造になっているので、親・子・孫・曾孫の関係で保存します。
    void  SaveXfile()
    {
        IDirectXFile *pDXFile = NULL;
        IDirectXFileSaveObject *pDXSave = NULL;
        IDirectXFileData *pDXData = NULL;
        IDirectXFileData *pDXChildData = NULL;
        IDirectXFileData *pDXGrandChild = NULL;
        IDirectXFileData *pDXGGrandChild = NULL;
    
        // X-FILE インターフェースを取得
        DirectXFileCreate( &pDXFile );
        // template を設定
        if(FAILED(pDXFile->RegisterTemplates(str,strlen(str))))     goto error;
    
        // セーブオブジェクトを作成する
        if(FAILED(pDXFile->CreateSaveObject("model.x", DXFILEFORMAT_TEXT, &pDXSave)))
            goto exit;
    
        //※ 多角形の筒を生成する
        if(FAILED(InitGeometry()))  goto error;
    
        // Header を書き出す
        if(FAILED(pDXSave->CreateDataObject( Header, NULL, NULL, sizeof(hed), &hed, &pDXData)))
            goto error;
        if(FAILED(pDXSave->SaveData(pDXData)))  goto error;
        SAFE_RELEASE(pDXData);
    
        // Mesh(pDXData) を編集する
        if(FAILED(pDXSave->CreateDataObject(Mesh, NULL, NULL, sizeof(mesh), &mesh, &pDXData)))
            goto error;
          // MeshMaterialList(pDXChildData) を設定
          if(FAILED(pDXSave->CreateDataObject(MeshMaterialList, NULL, NULL, sizeof(meshmaterial), &meshmaterial, &pDXChildData)))
            goto error;
            // Material(pDXGrandChild) を設定
            if(FAILED(pDXSave->CreateDataObject(Material, NULL, NULL, sizeof(material), &material, &pDXGrandChild)))
                goto error;
              // TextureFilename(pDXGGrandChild) を設定
              if(FAILED(pDXSave->CreateDataObject(TextureFilename, NULL, NULL, strlen(filename), &filename, &pDXGGrandChild)))
                goto error;
              // TextureFilename を Material に加える
              pDXGrandChild->AddDataObject(pDXGGrandChild); 
            // Material を MeshMaterialList に加える
            pDXChildData->AddDataObject(pDXGrandChild); 
          // MeshMaterialList を Mesh に加える
          pDXData->AddDataObject(pDXChildData); 
          SAFE_RELEASE(pDXGGrandChild);
          SAFE_RELEASE(pDXGrandChild);
          SAFE_RELEASE(pDXChildData);
          // MeshTextureCoords(pDXChildData) を設定
          if(FAILED(pDXSave->CreateDataObject(MeshTextureCoords, NULL, NULL, sizeof(meshtexture), &meshtexture, &pDXChildData)))
            goto error;
          // MeshTextureCoords(pDXChildData) を Mesh に加える
          pDXData->AddDataObject(pDXChildData);
          SAFE_RELEASE(pDXChildData);
          // MeshNormals(pDXChildData) を設定
          if(FAILED(pDXSave->CreateDataObject( MeshNormals, NULL, NULL, sizeof(meshnormal), &meshnormal, &pDXChildData)))
            goto error;
          // MeshNormals を Mesh に加える
          pDXData->AddDataObject(pDXChildData);
        // Mesh を書き出す
        if(FAILED(pDXSave->SaveData(pDXData)))  goto error;
        goto exit;
    
    error:
        MessageBox(NULL, "失敗しました", "Error Message", MB_OK);
    
    exit:
        SAFE_RELEASE(pDXGGrandChild);
        SAFE_RELEASE(pDXGrandChild);
        SAFE_RELEASE(pDXChildData);
        SAFE_RELEASE(pDXData);
        SAFE_RELEASE(pDXSave);
        SAFE_RELEASE(pDXFile);
    }
    
  7. WinMain() は SaveXfile() 関数を呼ぶだけです。
    // WinMain()
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
    {
        SaveXfile();
        return 0;
    }
    

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

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

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