Created
November 15, 2018 05:52
-
-
Save baobao/ffd77b2d6a6585503a33263f689f24b4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 Test:Form | |
{ | |
struct VertexData | |
{ | |
public Vector3 position; | |
public Vector3 color; | |
public static int SizeInBytes => System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertexData)); | |
public static InputElement[] VertexInputElements = new[] | |
{ | |
new InputElement | |
{ | |
SemanticName = "SV_Position", | |
Format = Format.R32G32B32_Float | |
}, | |
new InputElement | |
{ | |
SemanticName = "COLOR", | |
Format = Format.R32G32B32_Float, | |
// アドレスの自動配置 | |
AlignedByteOffset = InputElement.AppendAligned | |
} | |
}; | |
} | |
Device device; | |
SwapChain swapChain; | |
RenderTargetView renderTarget; | |
InputLayout vertexLayout; | |
Effect effect; | |
SlimDX.Direct3D11.Buffer vertexBuffer; | |
Stopwatch sw = new Stopwatch(); | |
int fps = 30; | |
long frameCount = 0; | |
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, | |
VertexData.VertexInputElements | |
); | |
var vertexDatas = new VertexData[] | |
{ | |
new VertexData | |
{ | |
position = new Vector3(0f, 0.5f, 0), | |
color = new Vector3(1,0,0) | |
}, | |
new VertexData | |
{ | |
position =new Vector3(0.5f, -0.5f, 0), | |
color = new Vector3(0,1,0) | |
}, | |
new VertexData | |
{ | |
position = new Vector3(-0.5f, -0.5f, 0), | |
color = new Vector3(1, 1, 1) | |
} | |
}; | |
// 頂点バッファの作成 | |
vertexBuffer = CreateVertexBuffer( | |
device, | |
vertexDatas | |
); | |
// ViewPort設定 | |
device.ImmediateContext.Rasterizer.SetViewports( | |
new Viewport | |
{ | |
Width = ClientSize.Width, | |
Height = ClientSize.Height | |
} | |
); | |
device.ImmediateContext.Rasterizer.State = RasterizerState.FromDescription(device, new RasterizerStateDescription | |
{ | |
// カリングOFF | |
CullMode = CullMode.None, | |
FillMode = FillMode.Solid | |
}); | |
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); | |
} | |
frameCount++; | |
} | |
void Draw() | |
{ | |
// 背景クリア | |
device.ImmediateContext.ClearRenderTargetView( | |
renderTarget, | |
new Color4(1,0.5f, 0.5f, 0.5f) | |
); | |
// ビュー変換行列 | |
var vMatrix = Matrix.LookAtRH( | |
new Vector3(0, 0, 1.3f), | |
new Vector3(0, 0, 0), | |
new Vector3(0, 1f, 0) | |
); | |
// プロジェクション変換行列 | |
var pMatrix = Matrix.PerspectiveFovRH( | |
(float)System.Math.PI / 2, | |
(float)ClientSize.Width / (float)ClientSize.Height, | |
// マイナス値ダメ!! | |
0f, | |
100f | |
); | |
// シェーダへVPMatrixを渡す | |
var vpMatrix = vMatrix * pMatrix; | |
effect.GetVariableByName("VPMatrix").AsMatrix().SetMatrix(vpMatrix); | |
// 1フレームにおける回転するオイラー角 | |
var eulerAnglePerFrame = 75f / (float)fps; | |
float radian = eulerAnglePerFrame * (float)frameCount * (float)System.Math.PI / 180f; | |
// Z軸回転行列生成 | |
var axis = new Vector3(0f, 1f, 0f); | |
Matrix rotateMatrix = Matrix.RotationAxis(axis, radian); | |
var matrix = effect.GetVariableByName("RotateMatrix"); | |
matrix.AsMatrix().SetMatrix(rotateMatrix); | |
// 三角形描画初期化 | |
device.ImmediateContext.InputAssembler.InputLayout = vertexLayout; | |
device.ImmediateContext.InputAssembler.SetVertexBuffers( | |
0, new VertexBufferBinding( | |
vertexBuffer, VertexData.SizeInBytes, 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