Xファイルの読み込み

public static Mesh FromFile(
    string filename,                // ファイル名
    MeshFlags options,              // メッシュ作成オプション
    Device device,                  // デバイス
    out ExtendedMaterial materials  // 拡張マテリアル
    );
Mesh.FromFile | MSDN
MeshFlags列挙型 (一部)
  列挙子  
  Managed VbManagedとIbManagedを指定するのと同等。
SystemMemory VbSystemMemとIbSystemMemを指定するのと同等。
頂点バッファ※1 VbManaged デバイスからアクセスできるメモリを使用する。
VbSystemMem システムRAMを使用する。
インデックス バッファ※1 IbManaged デバイスからアクセスできるメモリを使用する。
IbSystemMem システムRAMを使用する。
※1 使用メモリの指定はPool列挙型の内容と同一。
MeshFlags 列挙型 | MSDN

ストリームからの読み込み

ファイルから読み込む場合と、基本的に同一です。

public static Mesh FromStream(
    Stream stream,                  // ストリーム
    int readBytes,                  // ファイルサイズ
    MeshFlags options,              // メッシュ作成オプション
    Device device,                  // デバイス
    out ExtendedMaterial materials  // 拡張マテリアル
    );

サンプルコード

おおまかに次の工程でXファイルからメッシュを作成します。

  1. Xファイルを読み込む。
  2. 法線情報を持たなければ、それを作成する。
  3. マテリアル情報を持つならば、それを取得する。
  4. テクスチャを持つならば、それを読み込む。
ExtendedMaterial[] materials = null;

// Step1 指定のファイルからメッシュを読み込む
mesh = Mesh.FromFile( "LeftArm1.x", MeshFlags.Managed, device, out materials );

// Step2 メッシュが法線情報を持たなければ、法線情報を加えたメッシュを生成する
if( ( mesh.VertexFormat & VertexFormats.Normal ) != VertexFormats.Normal )
{
    Mesh tempMesh = mesh.Clone(
        mesh.Options.Value,
        mesh.VertexFormat | VertexFormats.Normal,
        device
        );

    // 法線を求める
    tempMesh.ComputeNormals();

    // 新しいメッシュと置き換える
    mesh.Dispose();
    mesh = tempMesh;
}

// Step3 マテリアルの情報が含まれているならば、それを取得する
if( materials != null && 0 < materials.Length )
{
    meshTextures = new Texture[ materials.Length ];
    meshMaterials = new Material[ materials.Length ];

    for( int i = 0; i < materials.Length; i++ )
    {
        // マテリアルの情報を取得する
        meshMaterials[ i ] = materials[ i ].Material3D;

        // 環境光に対する反射係数を拡散反射係数から設定する
        meshMaterials[ i ].Ambient = meshMaterials[ i ].Diffuse;


        // Step4 テクスチャの情報が含まれているならば、それを読み込む
        if( !string.IsNullOrEmpty( materials[ i ].TextureFilename ) )
        {
            try
            {
                meshTextures[ i ] = TextureLoader.FromFile(
                    device,
                    materials[ i ].TextureFilename
                    );
            }
            catch( Microsoft.DirectX.Direct3D.InvalidDataException )
            {
                meshTextures[ i ] = null;
            }
        }
    }
}

描画

基本的にストック オブジェクトを描画する場合と同一です。

ただしメッシュはマテリアルごとに複数の部分に分割されているため、それぞれを分けて描画します。

for( int i = 0; i < meshMaterials.Length; i++ )
{
    // マテリアルを設定する
    device.Material = meshMaterials[ i ];

    // テクスチャを設定する
    device.SetTexture( 0, meshTextures[ i ] );

    // メッシュを描画する
    mesh.DrawSubset( i );
}