Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
using System.Windows.Forms;
using SlimDX.DXGI;
using SlimDX.Windows;
using SlimDX.Direct3D11;
using Device = SlimDX.Direct3D11.Device;
using SlimDX;
using SlimDX.D3DCompiler;
using System.Diagnostics;
using System.Threading;
public class FpsLoopFull:Form
{
Device device;
SwapChain swapChain;
RenderTargetView renderTarget;
InputLayout vertexLayout;
Effect effect;
SlimDX.Direct3D11.Buffer vertexBuffer;
Stopwatch sw = new Stopwatch();
int fps = 30;
public void Run()
{
Test.CreateDeviceWithSwapChain(this, out device, out swapChain);
// 描画対象の初期化
using (var backBuffer = SlimDX.Direct3D11.Resource.FromSwapChain<Texture2D>(swapChain, 0))
{
renderTarget = new RenderTargetView(device, backBuffer);
device.ImmediateContext.OutputMerger.SetTargets(renderTarget);
}
// シェーダのコンパイル
effect = CompileShader("myEffect2.fx");
vertexLayout = new InputLayout(
device,
effect.GetTechniqueByIndex(0)
.GetPassByIndex(0).Description.Signature,
new []
{
new InputElement
{
SemanticName = "SV_Position",
Format = Format.R32G32B32_Float
}
}
);
// 頂点バッファの作成
vertexBuffer = CreateVertexBuffer(
device,
new Vector3[]{
new Vector3(0f, 0.5f, 0),
new Vector3(0.5f, -0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
}
);
// ViewPort設定
device.ImmediateContext.Rasterizer.SetViewports(
new Viewport
{
Width = ClientSize.Width,
Height = ClientSize.Height
}
);
MessagePump.Run(this, Loop);
vertexBuffer.Dispose();
effect.Dispose();
vertexLayout.Dispose();
}
private Effect CompileShader(string path)
{
using (var shader = ShaderBytecode.CompileFromFile(
path,
"fx_5_0",
ShaderFlags.None,
EffectFlags.None))
{
return new Effect(device, shader);
}
}
void Loop()
{
sw.Restart();
Draw();
// 経過ミリ秒
var elapsedMilliSec = sw.ElapsedMilliseconds;
var sleepTime = 1000 / fps - elapsedMilliSec;
if (sleepTime > 0)
{
Thread.Sleep((int)sleepTime);
}
}
void Draw()
{
// 背景クリア
device.ImmediateContext.ClearRenderTargetView(
renderTarget,
new Color4(1,1,0,0)
);
// 三角形描画初期化
device.ImmediateContext.InputAssembler.InputLayout = vertexLayout;
device.ImmediateContext.InputAssembler.SetVertexBuffers(
0, new VertexBufferBinding(
vertexBuffer, sizeof(float) * 3, 0)
);
device.ImmediateContext.InputAssembler.PrimitiveTopology
= PrimitiveTopology.TriangleList;
// 三角形描画
effect.GetTechniqueByIndex(0).GetPassByIndex(0).Apply(device.ImmediateContext);
device.ImmediateContext.Draw(3, 0);
swapChain.Present(0, PresentFlags.None);
}
SlimDX.Direct3D11.Buffer CreateVertexBuffer(Device device, System.Array vertices)
{
using (DataStream vertexStream
= new DataStream(vertices, true, true))
{
return new SlimDX.Direct3D11.Buffer(
device,
vertexStream,
new BufferDescription()
{
// バッファのサイズ
SizeInBytes = (int)vertexStream.Length,
// バッファの種類
BindFlags = BindFlags.VertexBuffer
});
}
}
/// <summary>
/// デバイスとSwapChainを作成
/// </summary>
static public SlimDX.Result CreateDeviceWithSwapChain(
Form form,
out SlimDX.Direct3D11.Device device,
out SwapChain swapChain
)
{
return Device.CreateWithSwapChain(
// Direct3Dの機能を持つデバイス(GPU)を使用する
DriverType.Hardware,
// デバイスに特別なふるまいをさせるときは設定するが、基本はNone
DeviceCreationFlags.None,
// SwapChainの詳細設定
new SwapChainDescription()
{
// 2:ダブルバッファでティアリングを回避
BufferCount = 1,
// 表示するウィンドウ
OutputHandle = form.Handle,
// falseにするとフルスクリーン
IsWindowed = true,
// SwapChainのマルチサンプル方法設定
SampleDescription = new SampleDescription()
{
Count = 1,
Quality = 0
},
// ウィンドウの大きさやリフレッシュレートに関する設定
ModeDescription = new ModeDescription()
{
// ウィンドウの幅
Width = form.ClientSize.Width,
// ウィンドウの高さ
Height = form.ClientSize.Height,
// リフレッシュレート60Hz
RefreshRate = new SlimDX.Rational(60, 1),
// ウィンドウのフォーマット
// https://msdn.microsoft.com/ja-jp/library/ee416140(v=vs.85).aspx
Format = Format.R8G8B8A8_UNorm
},
// 描画対象の使用方法
// ウィンドウにただ表示するだけなので、RenderTargetOutputをセット
Usage = Usage.RenderTargetOutput
},
out device,
out swapChain
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment