開発環境 Microsoft Visual C# 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 空のプロジェクト
プロジェクト名 MdxMesh

プロジェクト


プロジェクトの保存
[ソリューションのディレクトリを作成]はチェックを付けなくてもいい。

プロジェクトのプロパティ
[アプリケーション]タブ
出力の種類:Windows アプリケーション

プロジェクトにクラスを追加。
テンプレート:クラス
名前:MdxMesh.cs

プロジェクトに新しい項目を追加。
テンプレート:アプリケーション構成ファイル
名前:App.config

プロジェクトの参照設定に追加。(.NETタブ)
System.Drawing
System.Windows.Forms

プロジェクトの参照設定に追加。(参照タブ) ※Ctrlで複数選択可
C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0
Microsoft.DirectX.dll
Microsoft.DirectX.Direct3D.dll
Microsoft.DirectX.Direct3DX.dll

注意
MdxMesh.exeと同じディレクトリにMdxMesh.exe.configがないと動作が不安定になる。

参考



LoaderLockエラーの対処
メニューから[ツール]-[設定]-[上級者設定]を選択する。
メニューから[デバッグ]-[例外]を選択する。
Managed Debugging Assistants/LoaderLockの[スローされるとき]のチェックを外す。

App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0"/>
  </startup>
</configuration>
 

MdxMesh.cs
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
 
namespace MdxMesh
{
    class MdxMesh : Form
    {
        Device dev;
        PresentParameters pp;
        Mesh meshSphere;
        Mesh meshBox;
        GraphicsStream adj;
        ExtendedMaterial[] mtrl;
        float fDist = 5.0f; // 原点との距離
        int nLat = 30;      // 緯度
        int nLong = 210;    // 経度
 
        public MdxMesh()
        {
            Text = "MdxMesh";
            ClientSize = new Size(800, 600);
            MinimumSize = new Size(80, 60);
            KeyDown += new KeyEventHandler(MdxMesh_KeyDown);
        }
 
        public bool DXInitialize()
        {
            try
            {
                pp = new PresentParameters();
                pp.Windowed = true;
                pp.SwapEffect = SwapEffect.Discard;
                pp.AutoDepthStencilFormat = DepthFormat.D16;
                pp.EnableAutoDepthStencil = true;
                dev = new Device(0, DeviceType.Hardware, this,
                    CreateFlags.HardwareVertexProcessing, pp);
                CreateMesh();
                return true;
            }
            catch
            {
                return false;
            }
        }
 
        public void Render()
        {
            if (WindowState == FormWindowState.Minimized) return;
            dev.RenderState.ZBufferEnable = true;
            dev.RenderState.ZBufferWriteEnable = true;
 
            // 視点の設定
            float fRad = ToRadian(nLat);    // 緯度
            float fY = (float)Math.Sin(fRad) * fDist;
            float fR = (float)Math.Cos(fRad) * fDist;
            fRad = ToRadian(nLong);         // 経度
            float fX = (float)Math.Sin(fRad) * fR;
            float fZ = (float)Math.Cos(fRad) * fR;
            dev.Transform.View = Matrix.LookAtLH(
                new Vector3(fX, fY, fZ),
                new Vector3(0.0f, 0.0f, 0.0f),
                new Vector3(0.0f, 1.0f, 0.0f));
            dev.Transform.Projection = Matrix.PerspectiveFovLH(ToRadian(45.0f),
                (float)ClientSize.Width / ClientSize.Height, 0.1f, 100.0f);
 
            // ライトの設定
            //dev.RenderState.Lighting = false;
            dev.RenderState.Ambient = Color.FromArgb(0x7f, 0x7f, 0x7f);
            dev.Lights[0].Type = LightType.Directional;
            dev.Lights[0].Direction = Vector3.Normalize(new Vector3(1, -2, 3));
            dev.Lights[0].Diffuse = Color.FromArgb(0xff, 0xff, 0xff);
            dev.Lights[0].Ambient = Color.FromArgb(0x7f, 0x7f, 0x7f);
            dev.Lights[0].Enabled = true;
            dev.Lights[0].Update();
 
            // バックバッファのクリア
            dev.Clear(ClearFlags.Target | ClearFlags.ZBuffer, 0x7f7fff, 1.0f, 0);
            dev.BeginScene();
 
            // メッシュ描画
            Material mat = new Material();
 
            dev.Transform.World = Matrix.Translation(-1.0f, 0.0f, 0.0f);
            mat.DiffuseColor = new ColorValue(0.0f, 0.8f, 0.0f);
            mat.AmbientColor = new ColorValue(0.0f, 0.3f, 0.0f);
            dev.Material = mat;
            meshBox.DrawSubset(0);
 
            dev.Transform.World = Matrix.Translation(1.0f, 0.0f, 0.0f);
            mat.DiffuseColor = new ColorValue(0.8f, 0.0f, 0.0f);
            mat.AmbientColor = new ColorValue(0.3f, 0.0f, 0.0f);
            dev.Material = mat;
            meshSphere.DrawSubset(0);
 
            // バックバッファを表画面に反映
            dev.EndScene();
            try
            {
                dev.Present();
            }
            catch (DeviceLostException)
            {
                ResetDevice();
            }
        }
 
        float ToRadian(float degree)
        {
            return degree * (float)Math.PI / 180.0f;
        }
 
        void CreateMesh()
        {
            meshSphere = Mesh.Sphere(dev, 0.5f, 16, 8);
            meshBox = Mesh.Box(dev, 1.0f, 1.0f, 1.0f, out adj);
            mtrl = new ExtendedMaterial[0];
 
            //meshBox = Mesh.FromFile(@"C:\tmp\Cube2.x", MeshFlags.Managed, dev, out adj, out mtrl);
            //meshBox.Validate(adj);
        }
 
        void ResetDevice()
        {
            int nResult;
            if (!dev.CheckCooperativeLevel(out nResult))
            {
                switch (nResult)
                {
                    case (int)ResultCode.DeviceLost:
                        Thread.Sleep(10);
                        break;
                    case (int)ResultCode.DeviceNotReset:
                        dev.Reset(pp);
                        break;
                }
            }
        }
 
        void MdxMesh_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left:
                    nLong += 2;
                    break;
                case Keys.Right:
                    nLong -= 2;
                    break;
                case Keys.Up:
                    nLat += 2;
                    break;
                case Keys.Down:
                    nLat -= 2;
                    break;
                case Keys.PageUp:
                    fDist -= 0.5f;
                    break;
                case Keys.PageDown:
                    fDist += 0.5f;
                    break;
                case Keys.S:
                    if ((e.Modifiers & Keys.Control) == Keys.Control)
                    {
                        if (SaveMesh())
                        {
                            MessageBox.Show("保存しました。", "MdxMesh");
                        }
                    }
                    break;
                case Keys.Escape:
                    Close();
                    break;
            }
        }
 
        bool SaveMesh()
        {
            try
            {
                meshBox.Save(@"C:\tmp\box_2.x", adj, mtrl, XFileFormat.Text);
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "エラー");
                return false;
            }
        }
    }
 
    static class Program
    {
        [STAThread]
        static void Main()
        {
            using (MdxMesh form = new MdxMesh())
            {
                if (!form.DXInitialize())
                {
                    MessageBox.Show("Direct3Dの初期化に失敗しました。", "MdxMesh");
                    return;
                }
                form.Show();
                while (form.Created)
                {
                    form.Render();
                    Application.DoEvents();
                }
            }
        }
    }
}
 
最終更新:2012年11月27日 12:31