コーンのメッシュ(cone.x)を描画する



コーンに色を設定した3Dモデル(Cone.x)を描画します。

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

プログラムの説明

  1. 3Dモデルのファイルを入力して、WORLD 座標を回転しながら描画します。
    DirectX 3D で Form を表示する に習って、空のプロジェクトから作成します。
    プログラムファイル(DXCone.cs)をダウンロードして、プロジェクトに取り込んで下さい。
    ファイル名 説明
    DXCone.cs コーンのメッシュ(cone.x)を描画する
    cone.x は「初心者のプログラム(DirectX10)/X-FILE(Cone.x) の頂点データを定義する」からダウンロード出来ます。
  2. mesh がメッシュ(cone.x)の領域です。
    meshMaterials は3Dモデルのマテリアルを格納する領域です。
    meshTextures は3Dモデルのテクスチャを格納する領域です。
        public class Meshes : Form
        {
            Device device = null;                   // Our rendering device
            Mesh mesh = null;                       // Our mesh object in sysmem
            Direct3D.Material[] meshMaterials;      // Materials for our mesh
            Texture[] meshTextures;                 // Textures for our mesh
            PresentParameters presentParams = new PresentParameters();
            bool pause = false;
        
  3. Cone.x を入力する OnResetDevice() です。
    Cone.x を c:\data\xfile\ のフォルダーに格納して下さい。
    Mesh.FromFile() が3Dモデル(Cone.x)を入力するメソッドです。
    new Material[] で Cone.x に設定されているマテリアルを格納する領域を生成します。
    new Texture[] で Cone.x に設定されているテクスチャを格納する領域を生成します。
    materials.Length は X-File に格納されている「属性テーブル」のエントリ数です。
    生成した領域にマテリアルとテクスチャを設定します。
        public void OnResetDevice(object sender, EventArgs e)
        {
            Device dev = (Device)sender;
            // Turn on the zbuffer
            dev.RenderState.ZBufferEnable = true;
    
            // Load the mesh from the specified file
            ExtendedMaterial[] materials = null;
            Directory.SetCurrentDirectory("c:\\data\\xfile\\");
            mesh = Mesh.FromFile("cone.x", MeshFlags.SystemMemory, device, out materials);
    
            // Allocate a material/texture arrays
            meshMaterials = new Material[materials.Length];
            meshTextures = new Texture[materials.Length];
    
            // Copy the materials and load the textures
            for(int i = 0; i < meshMaterials.Length; i++)
            {
                meshMaterials[i] = materials[i].Material3D;
                meshMaterials[i].AmbientColor = meshMaterials[i].DiffuseColor;
    
                if ( (materials[i].TextureFilename != null) && (materials[i].TextureFilename.Length > 0) )
                {
                    // Create the texture
                    meshTextures[i] = TextureLoader.FromFile(dev, materials[i].TextureFilename);
                }
            }
        }
        
  4. メッシュを描画する関数です。
    Clear() で画面をクリアします。
    SetupLights() でライトを設定します。
    SetupMatrices() は描画環境を設定する関数です。
    device.Material と device.SetTexture に X-File から取得した属性を設定します。
    mesh.DrawSubset(i) でメッシュを描画します。
        private void Render()
        {
            if (device == null) return;
            if (pause)          return;
    
            //Clear the backbuffer to a blue color 
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.LightGray, 1.0f, 0);
            //Begin the scene
            device.BeginScene();
            SetupLights();
            // Setup the world, view, and projection matrices
            SetupMatrices();
    
            // Meshes are divided into subsets, one for each material. Render them in
            for( int i=0; i<meshMaterials.Length; i++ )
            {
                // Set the material and texture for this subset
                device.Material = meshMaterials[i];
                device.SetTexture(0, meshTextures[i]);
                // Draw the mesh subset
                mesh.DrawSubset(i);
            }
    
            //End the scene
            device.EndScene();
            device.Present();
        }
        
  5. C/C++ でも同様のプログラムを作成しています。
    超初心者のプログラム入門(C/C/C++)から コーンのメッシュを描画する を参照して下さい。
    リンクがエラーになるときは「前田稔の超初心者のプログラム入門」から辿って下さい。

【課題】

  1. コーンのメッシュが正常に描画できたら、他のモデルも描画してみて下さい。
  2. DirectX に添付されている「虎のモデル」を描画して下さい。
    虎のモデルが真っ黒にならなかったでしょうか。 (;_;)
    その原因は「法線ベクトルが設定されていない」ことにあります。
  3. ヒントが次のフォルダーに格納されているプログラムに書かれています。
    DirectX の3Dプログラムは難題の連続で、次から次へと難題が持ち上がります。 (^_^;)
    あなたはこの問題を解決できるでしょうか? (^◇^;)
    C:\Program Files\Microsoft DirectX SDK (December 2006)\Samples\Managed\Direct3D\EnhancedMesh

【NOTE】

作成したときは確かに動いていたのですが 2011/10/01 に確認した所、実行することが出来ません。
  1. 次のエラーが出ます。
    BadImageFormatException はハンドルされませんでした。
    原因と対策は Direct Draw でウインドウを表示 を参照して下さい。
  2. また X86 でコンパイルすると X-FILE を入力出来なくなりました。
    プロジェクトのフォルダに cone.x を置いて、相対的に参照しているときに発生します。
    原因は実行ファイルと X-FILE が置かれているパスの相対関係が崩れたからでした。
    作成当初の設定です。
    Directory.SetCurrentDirectory(Application.StartupPath + @"\..\..\");
    次のように設定して下さい。フォルダが一段深くなっています。
    Directory.SetCurrentDirectory(Application.StartupPath + @"\..\..\..\");
  3. X-FILE が置かれているパスを絶対パスで設定する方法もあります。
    例えば "cone.x" をフルパスで設定と次のようになります。
    フルパスで設定すると、テクスチャファイルが読めないことがあるので要注意です。
    mesh = Mesh.FromFile("c:\\data\\xfile\\cone.x", MeshFlags.SystemMemory, device, out materials);
  4. X-FILE が置かれているパスを SetCurrentDirectory() でカレントディレクトリに設定する方法がお勧めです。
        Directory.SetCurrentDirectory("c:\\data\\xfile\\");
        mesh = Mesh.FromFile("cone.x", MeshFlags.SystemMemory, device, out materials);
        
  5. 完成したプログラムは DX.BAT でコンパイルすることも出来るので試して下さい。
    そのときは、X-FILE が置かれているフォルダーと SetCurrentDirectory() の関係に注意して下さい。

超初心者のプログラム入門(C# Frame Work)