[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
前回からの変更点はusing Microsoft.WindowsAPICodePack.DirectX.Direct3D;using Microsoft.WindowsAPICodePack.DirectX.Direct3D11;using Microsoft.WindowsAPICodePack.DirectX.Graphics;using System.IO;using System.Runtime.InteropServices;class Program{static void Main(){using (Game game = new MyGame()){game.Run();}}}class Game : System.Windows.Forms.Form{protected DeviceContext DeviceContext;protected SwapChain SwapChain;protected RenderTargetView RenderTargetView;public void Run(){D3DDevice device = initDevice();LoadGraphicsContent(device);Show();while (Created){Draw();System.Windows.Forms.Application.DoEvents();}}private D3DDevice initDevice(){D3DDevice device = D3DDevice.CreateDeviceAndSwapChain(this.Handle);this.SwapChain = device.SwapChain;this.DeviceContext = device.ImmediateContext;using (Texture2D texture2D = SwapChain.GetBuffer<Texture2D>(0)){this.RenderTargetView = device.CreateRenderTargetView(texture2D);DeviceContext.OM.RenderTargets = new OutputMergerRenderTargets(new[] { RenderTargetView });}DeviceContext.RS.Viewports = new[]{new Viewport{Width = ClientSize.Width,Height = ClientSize.Height,MaxDepth = 1}};return device;}protected virtual void LoadGraphicsContent(D3DDevice device) { }protected virtual void Draw() { }//ジェネリクスな型Tをネイティブに変換するのは骨が折れます。//XNAでは別の方法を使っているようですが…protected D3DBuffer CreateVertexBuffer<T>(D3DDevice device, T[] vertices) where T : struct{int vertexSize = Marshal.SizeOf(typeof(T));System.IntPtr verticesPointer = Marshal.AllocCoTaskMem(vertices.Length * vertexSize);for (int i = 0; i < vertices.Length; i++){Marshal.StructureToPtr(vertices[i], verticesPointer + vertexSize * i, false);}D3DBuffer result = device.CreateBuffer(new BufferDescription{ByteWidth = (uint)(vertexSize * vertices.Length),BindingOptions = BindingOptions.VertexBuffer,},new SubresourceData{SystemMemory = verticesPointer});Marshal.FreeCoTaskMem(verticesPointer);return result;}}struct VertexPositionColor{public Vector3F Position;public Vector3F Color;public static readonly InputElementDescription[] VertexElements = new[]{new InputElementDescription{SemanticName = "SV_Position",Format = Format.R32G32B32Float,},new InputElementDescription{SemanticName = "COLOR",Format = Format.R32G32B32Float,AlignedByteOffset = uint.MaxValue //MaxValueにするとオフセットを自動的に決定}};}class MyGame : Game{protected override void Draw(){this.DeviceContext.ClearRenderTargetView(RenderTargetView, new ColorRgba(0.39f, 0.58f, 0.93f, 1));this.DeviceContext.Draw(3, 0);this.SwapChain.Present(0, PresentOptions.None);}protected override void LoadGraphicsContent(D3DDevice device){initShadersAndInputLayout(device);initTriangleToDraw(device);}private void initShadersAndInputLayout(D3DDevice device){using (Stream vertexShaderBinary = File.Open("MyShader.vs", FileMode.Open)){this.DeviceContext.VS.Shader = device.CreateVertexShader(vertexShaderBinary);vertexShaderBinary.Position = 0;this.DeviceContext.IA.InputLayout = createInputLayout(device, vertexShaderBinary);}using (Stream pixelShaderBinary = System.IO.File.Open("MyShader.ps", FileMode.Open)){this.DeviceContext.PS.Shader = device.CreatePixelShader(pixelShaderBinary);}}private InputLayout createInputLayout(D3DDevice device, Stream vertexShaderBinary){return device.CreateInputLayout(VertexPositionColor.VertexElements,vertexShaderBinary);}private void initTriangleToDraw(D3DDevice device){VertexPositionColor[] vertices = new []{new VertexPositionColor{ Position = new Vector3F(0, 0.5f, 0), Color = new Vector3F(1, 1, 1) },new VertexPositionColor{ Position = new Vector3F(0.5f, 0, 0), Color = new Vector3F(0, 0, 1) },new VertexPositionColor{ Position = new Vector3F(-0.5f, 0, 0), Color = new Vector3F(1, 0, 0) },};D3DBuffer vertexBuffer = CreateVertexBuffer(device, vertices);this.DeviceContext.IA.SetVertexBuffers(0,new D3DBuffer[] { vertexBuffer },new uint[] { (uint)Marshal.SizeOf(typeof(VertexPositionColor)) },new uint[] { 0 });this.DeviceContext.IA.PrimitiveTopology = PrimitiveTopology.TriangleList;}}
例によってこのファイルはfxc.exeを使ってコンパイルしてください。struct VertexPositionColor{float4 Position : SV_Position;float4 Color : COLOR;};VertexPositionColor MyVertexShader(VertexPositionColor input){return input;}float4 MyPixelShader(VertexPositionColor input) : SV_Target{return input.Color;}