Sample Brower で cone.x を描画



Sample Brower で生成したプロジェクトで X-FILE(cone.x) を描画します。

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

プログラムの説明

  1. DirectX のプロジェクトは Sample Brower を使って生成する方法がお勧めです。
    Sample Brower から提供されるサンプルは、何も手を加えなくてもそのまま実行できます。
    Tiny のアニメーション などはその例です。
    ここでは Sample Brower を使って XFILE(cone.x) を描画する方法を説明します。
  2. [スタート] から [プログラム] [Microsoft DirectX] を選択して [DirectX Sample Browser] を実行して下さい。
    Managed から「EmptyProject」の「Install Project」をクリックすると、自動的に空のプロジェクトが構築されます。

    DirectX のバージョンによっては Sample Browser に Managed Mode が含まれていない場合があります。
    詳細は「Tiny のアニメーション」を参照して下さい。
  3. 生成された EmptyProject から、次のファイルを残して削除して下さい。
    ・Common のフォルダー
    ・EmptyProject_2005.csproj
    プロジェクトのフォルダーに下記のファイルを格納して下さい。
    /****************************************/
    /*★ X-FILE(cone.x) を描画    前田 稔 ★*/
    /****************************************/
    using System;
    using Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    using Microsoft.Samples.DirectX.UtilityToolkit;
    
    namespace EmptyProjectSample
    {
        public class EmptyProject : IFrameworkCallback, IDeviceCreation
        {
            // Variables
            private Framework sampleFramework = null;
            private Mesh    mesh = null;
            private float   aspectRatio = 1.0f;
    
            Microsoft.DirectX.Direct3D.Material[] meshMaterials;    // Materials for our mesh
            Texture[] meshTextures;                                 // Textures for our mesh
            private string XFilePath = "C:\\DATA\\XFILE\\";
            private string XFileName = "cone.x";
            //private string XFileName = "tiger.x";
    
            public EmptyProject(Framework f) 
            {   sampleFramework = f;  }
    
            public bool IsDeviceAcceptable(Caps caps, Format adapterFormat, Format backBufferFormat, bool windowed)
            {
                if (!Manager.CheckDeviceFormat(caps.AdapterOrdinal, caps.DeviceType, adapterFormat, 
                    Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backBufferFormat))
                    return false;
                return true;
            }
    
            public void ModifyDeviceSettings(DeviceSettings settings, Caps caps)
            {
                if ( (!caps.DeviceCaps.SupportsHardwareTransformAndLight) ||
                    (caps.VertexShaderVersion < new Version(1,1)) )
                {   settings.BehaviorFlags = CreateFlags.SoftwareVertexProcessing;  }
                else
                {   settings.BehaviorFlags = CreateFlags.HardwareVertexProcessing;  }
    
                if ( (caps.DeviceCaps.SupportsPureDevice) && 
                    ((settings.BehaviorFlags & CreateFlags.HardwareVertexProcessing) != 0 ) )
                    settings.BehaviorFlags |= CreateFlags.PureDevice;
    
                if (settings.DeviceType == DeviceType.Reference)
                {
                    Utility.DisplaySwitchingToRefWarning(sampleFramework, "EmptyProject");
                }
            }
    
            private void OnCreateDevice(object sender, DeviceEventArgs e)
            {
                // X-FILE を入力
                ExtendedMaterial[] materials = null;
                System.IO.Directory.SetCurrentDirectory(XFilePath);
                mesh = Mesh.FromFile(XFileName, MeshFlags.SystemMemory, e.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))
                    {
                        meshTextures[i] = TextureLoader.FromFile(e.Device, materials[i].TextureFilename);
                    }
                }
    
                // 法線情報がなければ計算して作成
                if ((mesh.VertexFormat & VertexFormats.Normal) == 0)
                {
                    Mesh temporaryMesh = mesh.Clone(mesh.Options.Value,
                        mesh.VertexFormat | VertexFormats.Normal, e.Device);
                    // 法線を計算
                    temporaryMesh.ComputeNormals();
                    // 古いメッシュを破棄し、置き換える
                    mesh.Dispose();
                    mesh = temporaryMesh;
                }
            }
            
            private void OnResetDevice(object sender, DeviceEventArgs e)
            {
                SurfaceDescription desc = e.BackBufferDescription;
                aspectRatio = (float)desc.Width / (float)desc.Height;
    
                //☆ マテリアルとライトを設定する
                System.Drawing.Color col = System.Drawing.Color.White;
                Microsoft.DirectX.Direct3D.Material mtrl = new Microsoft.DirectX.Direct3D.Material();
                mtrl.Diffuse = col;
                mtrl.Ambient = col;
                e.Device.Material = mtrl;
    
                e.Device.Lights[0].Type = LightType.Directional;
                e.Device.Lights[0].Diffuse = System.Drawing.Color.White;
    
                e.Device.Lights[0].Direction = new Vector3(50.0f, -40.0f, 100.0f);
                e.Device.Lights[0].Enabled = true;
                e.Device.RenderState.Ambient = System.Drawing.Color.FromArgb(0x202020);
            }
    
            private void OnDestroyDevice(object sender, EventArgs e)
            {
            }
    
            public void OnFrameMove(Device device, double appTime, float elapsedTime)
            {
                device.Transform.World = Matrix.RotationY(Environment.TickCount / 1000.0f);
                device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 2.0f, -5.0f),
                    new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
                device.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4), aspectRatio, 1.0f, 500.0f);
           }
    
            public void OnFrameRender(Device device, double appTime, float elapsedTime)
            {
                bool beginSceneCalled = false;
    
                // Clear the render target and the zbuffer 
                device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x002D32AA, 1.0f, 0);
                //device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, System.Drawing.Color.Gray, 1.0f, 0);
                try
                {
                    device.BeginScene();
                    beginSceneCalled = true;
    
                    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);
                    }
                }
                finally
                {   if (beginSceneCalled)   device.EndScene();  }
            }
    
            static int Main() 
            {
                System.Windows.Forms.Application.EnableVisualStyles();
                using(Framework sampleFramework = new Framework())
                {
                    EmptyProject sample = new EmptyProject(sampleFramework);
    
                    sampleFramework.Disposing += new EventHandler(sample.OnDestroyDevice);
                    sampleFramework.DeviceCreated += new DeviceEventHandler(sample.OnCreateDevice);
                    sampleFramework.DeviceReset += new DeviceEventHandler(sample.OnResetDevice);
    
                    sampleFramework.SetCallbackInterface(sample);
                    try
                    {
                        // Show the cursor and clip it when in full screen
                        sampleFramework.SetCursorSettings(true, true);
    
                        sampleFramework.Initialize( true, true, true );
                        sampleFramework.CreateWindow("EmptyProject");
                        sampleFramework.CreateDevice( 0, true, Framework.DefaultSizeWidth,
                            Framework.DefaultSizeHeight, sample);
    
                        sampleFramework.MainLoop();
                    }
                    catch
                    {
                        // Ignore any exceptions here, they would have been handled by other areas
                        return (sampleFramework.ExitCode == 0) ? 1 : sampleFramework.ExitCode;
                    }
    
                    return sampleFramework.ExitCode;
                }
            }
        }
    }
    
  4. cone.x を "C:\DATA\XFILE\" のフォルダーに格納して下さい。
    cone.x は「初心者のプログラム(DirectX10)/X-FILE(Cone.x) の頂点データを定義する」からダウンロード出来ます。
    cone.x 以外を使うときや別のフォルダーに格納するときは、次の行を修正して下さい。
        private string XFilePath = "C:\\DATA\\XFILE\\";
        private string XFileName = "cone.x";
        
  5. EmptyProject_2005.csproj から起動して下さい。
    x86 に設定してコンパイル&実行をするとコーンのメッシュが描画されます。
  6. Cone.x を入力するソースコードです。
    詳細は コーンのメッシュ(cone.x)を描画する を参照して下さい。
    tiger.x も描画できるので、試してみて下さい。
            private void OnCreateDevice(object sender, DeviceEventArgs e)
            {
                // X-FILE を入力
                ExtendedMaterial[] materials = null;
                System.IO.Directory.SetCurrentDirectory(XFilePath);
                mesh = Mesh.FromFile(XFileName, MeshFlags.SystemMemory, e.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))
                    {
                        meshTextures[i] = TextureLoader.FromFile(e.Device, materials[i].TextureFilename);
                    }
                }
    
                // 法線情報がなければ計算して作成
                if ((mesh.VertexFormat & VertexFormats.Normal) == 0)
                {
                    Mesh temporaryMesh = mesh.Clone(mesh.Options.Value,
                        mesh.VertexFormat | VertexFormats.Normal, e.Device);
                    // 法線を計算
                    temporaryMesh.ComputeNormals();
                    // 古いメッシュを破棄し、置き換える
                    mesh.Dispose();
                    mesh = temporaryMesh;
                }
            }
        
  7. DirectX9 でも同様のプログラムを作成しています。
    超初心者のプログラム入門(DirectX9)から Sample Brower で X-FILE を描画 を参照して下さい。
    リンクがエラーになるときは「前田稔の超初心者のプログラム入門」から辿って下さい。

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