開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
空のプロジェクト |
プロジェクト名 |
MdxSample |
プロジェクト
プロジェクトの保存
[ソリューションのディレクトリを作成]はチェックを付けなくてもいい。
プロジェクトのプロパティ
[アプリケーション]タブ
出力の種類:Windows アプリケーション
プロジェクトにクラスを追加。
テンプレート:クラス
名前:Program.cs
名前:Form1.cs
名前:MdxSample.cs
プロジェクトに新しい項目を追加。
テンプレート:アプリケーション構成ファイル
名前:App.config
プロジェクトの参照設定に追加。(.NETタブ) ※Ctrlキーで複数選択可
System
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
Microsoft.DirectX.DirectInput.dll
注意
MdxSample.exeと同じディレクトリにMdxSample.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>
Program.cs
using System;
using System.Threading;
using System.Windows.Forms;
namespace MdxSample
{
static class Program
{
[STAThread]
static void Main()
{
using (Form1 form = new Form1())
using (MdxSample main = new MdxSample())
{
if (!main.DXInitialize(form))
{
MessageBox.Show("Direct3Dの初期化に失敗しました。", "MdxSample");
return;
}
form.Show();
while (form.Created)
{
main.Render();
Thread.Sleep(1);
Application.DoEvents();
}
}
}
}
}
Form1.cs
using System.Drawing;
using System.Windows.Forms;
namespace MdxSample
{
class Form1 : Form
{
public Form1()
{
Text = "MdxSample";
ClientSize = new Size(1280, 720);
MaximizeBox = false;
FormBorderStyle = FormBorderStyle.FixedSingle;
}
}
}
MdxSample.cs
using System;
using System.Drawing;
using System.Threading;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectInput;
namespace MdxSample
{
class MdxSample : IDisposable
{
Form1 form;
PresentParameters pp;
Microsoft.DirectX.Direct3D.Device dev;
Microsoft.DirectX.Direct3D.Font font;
Microsoft.DirectX.DirectInput.Device keyboard;
VertexBuffer vertexBuffer;
// fps
int fpsSec;
int fpsDraw = 0;
int fpsCount = 0;
// カメラ
float camDist = 3;
int camLat = 0;
int camLon = 180;
public bool DXInitialize(Form1 topLevelForm)
{
try
{
form = topLevelForm;
// キーボードデバイスの初期化
keyboard = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
keyboard.SetCooperativeLevel(form,
CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Background);
keyboard.Acquire();
// Direct3Dデバイス作成
pp = new PresentParameters();
pp.Windowed = true;
pp.SwapEffect = SwapEffect.Discard;
pp.EnableAutoDepthStencil = true;
pp.AutoDepthStencilFormat = DepthFormat.D16;
dev = new Microsoft.DirectX.Direct3D.Device(0,
Microsoft.DirectX.Direct3D.DeviceType.Hardware, form.Handle,
CreateFlags.HardwareVertexProcessing, pp);
// フォントの作成
FontDescription fd = new FontDescription();
fd.Height = 24;
fd.FaceName = "MS ゴシック";
font = new Microsoft.DirectX.Direct3D.Font(dev, fd);
// 頂点バッファ
CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[3];
vertices[0] = new CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb());
vertices[1] = new CustomVertex.PositionColored(1, -1, 0, Color.Green.ToArgb());
vertices[2] = new CustomVertex.PositionColored(-1, -1, 0, Color.Blue.ToArgb());
vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored),
3, dev, Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Managed);
using (GraphicsStream data = vertexBuffer.Lock(0, 0, LockFlags.None))
{
data.Write(vertices);
vertexBuffer.Unlock();
}
dev.Transform.Projection = Matrix.PerspectiveFovLH(Geometry.DegreeToRadian(45),
(float)dev.Viewport.Width / (float)dev.Viewport.Height, 1, 100);
dev.RenderState.Lighting = false;
return true;
}
catch
{
return false;
}
}
public void Render()
{
KeyboardState state;
state = keyboard.GetCurrentKeyboardState();
if (state[Key.Escape])
{
form.Close();
return;
}
if (state[Key.Up]) camLat = Math.Min(camLat + 1, 89);
if (state[Key.Down]) camLat = Math.Max(camLat - 1, -89);
if (state[Key.Left]) camLon = (camLon + 1) % 360;
if (state[Key.Right]) camLon = (camLon + 359) % 360;
if (state[Key.PageUp]) camDist -= 0.1f;
if (state[Key.PageDown]) camDist += 0.1f;
// fps
fpsDraw++;
int sec = DateTime.Now.Second;
if (fpsSec != sec)
{
fpsCount = fpsDraw;
fpsDraw = 0;
fpsSec = sec;
}
// カメラ位置
Vector3 pos;
float rad = Geometry.DegreeToRadian(camLat);
pos.Y = (float)Math.Sin(rad) * camDist;
float r = (float)Math.Cos(rad) * camDist;
rad = Geometry.DegreeToRadian(camLon);
pos.X = (float)Math.Sin(rad) * r;
pos.Z = (float)Math.Cos(rad) * r;
dev.Transform.View = Matrix.LookAtLH(pos, new Vector3(), new Vector3(0, 1, 0));
// バックバッファのクリア
dev.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
dev.BeginScene();
dev.SetStreamSource(0, vertexBuffer, 0);
dev.VertexFormat = CustomVertex.PositionColored.Format;
dev.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
string text = string.Format("fps={0} lat={1} lon={2} dist={3:f1}",
fpsCount, camLat, camLon, camDist);
font.DrawText(null, text, 0, 0, Color.White);
// バックバッファを表画面に反映
dev.EndScene();
try
{
dev.Present();
}
catch (DeviceLostException)
{
ResetDevice();
}
}
void ResetDevice()
{
int result;
if (!dev.CheckCooperativeLevel(out result))
{
switch ((ResultCode)result)
{
case ResultCode.DeviceLost:
Thread.Sleep(10);
break;
case ResultCode.DeviceNotReset:
dev.Reset(pp);
break;
default:
form.Close();
break;
}
}
}
public void Dispose()
{
if (font != null)
{
font.Dispose();
}
}
}
}
最終更新:2012年12月24日 21:25