Created
November 14, 2018 12:18
-
-
Save baobao/7e6e2564ab6ae1f5ce9c0bdd0f8a1ec8 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
matrix RotateMatrix; | |
struct VertexData | |
{ | |
float4 position : SV_Position; | |
float4 color : COLOR; | |
}; | |
// 頂点シェーダ | |
VertexData MyVertexShader(VertexData input) | |
{ | |
// 頂点座標に回転行列を反映する | |
input.position = mul(input.position, RotateMatrix); | |
return input; | |
} | |
// ピクセルシェーダ | |
float4 MyPixelShader(VertexData input) : SV_Target | |
{ | |
// インプットのカラーで描画 | |
return input.color; | |
} | |
technique10 MyTechnique | |
{ | |
pass MyPass | |
{ | |
SetVertexShader( CompileShader( vs_5_0, MyVertexShader() ) ); | |
SetPixelShader( CompileShader( ps_5_0, MyPixelShader() ) ); | |
} | |
} |
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 RotationTriangle: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("rotation.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 | |
} | |
); | |
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) | |
); | |
// 1フレームにおける回転するオイラー角 | |
var eulerAnglePerFrame = 40f / (float)fps; | |
float radian = eulerAnglePerFrame * (float)frameCount * (float)System.Math.PI / 180f; | |
// Z軸回転行列生成 | |
var axis = new Vector3(0.5f, 0, 1f); | |
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