開発環境 |
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