[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() { }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;}protected void ToNative(object structure, System.Action<System.IntPtr> nativeAction){System.IntPtr nativeConstantBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyCamera)));Marshal.StructureToPtr(structure, nativeConstantBuffer, false);nativeAction(nativeConstantBuffer);Marshal.FreeHGlobal(nativeConstantBuffer);}}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にするとオフセットを自動的に決定}};}struct MyCamera{public Matrix4x4F View;public Matrix4x4F Projection;public static int SizeInBytes{get{return Marshal.SizeOf(typeof(MyCamera));}}}class MyGame : Game{D3DBuffer cameraConstantBuffer;protected override void Draw(){this.DeviceContext.ClearRenderTargetView(RenderTargetView, new ColorRgba(0.39f, 0.58f, 0.93f, 1));updateCamera();this.DeviceContext.Draw(3, 0);this.SwapChain.Present(0, PresentOptions.None);}private void updateCamera(){double time = System.Environment.TickCount / 100d;Matrix4x4F view = MatrixHelper.CreateLookAt(new Vector3F((float)System.Math.Cos(time), 0, (float)System.Math.Sin(time)),new Vector3F(0, 0, 0),new Vector3F(0, 1, 0));Matrix4x4F projection = MatrixHelper.CreatePerspectiveFieldOfView((float)System.Math.PI / 2,(float)ClientSize.Width / ClientSize.Height,0.1f, 1000);ToNative(new MyCamera{View = MatrixHelper.Transpose(view),Projection = MatrixHelper.Transpose(projection)},nativeCamera =>{DeviceContext.UpdateSubresource(cameraConstantBuffer,0,nativeCamera,0,0);});DeviceContext.VS.SetConstantBuffers(0, new[] { cameraConstantBuffer });}protected override void LoadGraphicsContent(D3DDevice device){initShadersAndInputLayout(device);initTriangleToDraw(device);initCamera(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;}private void initCamera(D3DDevice device){ToNative(new MyCamera {},nativeCamera =>{this.cameraConstantBuffer = device.CreateBuffer(new BufferDescription{ByteWidth = (uint)MyCamera.SizeInBytes,BindingOptions = BindingOptions.ConstantBuffer},//nativeCameraの中身はカラなので//これはいらないように一見見えますが、//これがないと何故か例外をスローします。//今後改善なりなんなりがあるのでしょうか?new SubresourceData{SystemMemory = nativeCamera});});}}
using Microsoft.WindowsAPICodePack.DirectX.Direct3D;class MatrixHelper{public static Matrix4x4F CreateLookAt(Vector3F cameraPosition, Vector3F cameraTarget, Vector3F cameraUpVector){Vector3F newZ = (cameraPosition - cameraTarget).Normalize();Vector3F newX = Vector3F.Cross(cameraUpVector, newZ).Normalize();Vector3F newY = Vector3F.Cross(newZ, newX);return new Matrix4x4F(newX.X,newY.X,newZ.X,0,newX.Y,newY.Y,newZ.Y,0,newX.Z,newY.Z,newZ.Z,0,-Vector3F.Dot(newX, cameraPosition),-Vector3F.Dot(newY, cameraPosition),-Vector3F.Dot(newZ, cameraPosition),1f);}public static Matrix4x4F CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio,float nearPlaneDistance, float farPlaneDistance){return new Matrix4x4F{M11 = (float)(1 / (aspectRatio * System.Math.Tan(fieldOfView / 2))),M22 = (float)(1 / System.Math.Tan(fieldOfView / 2)),M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance),M34 = -1,M43 = (nearPlaneDistance * farPlaneDistance) / (nearPlaneDistance - farPlaneDistance),};}public static Matrix4x4F Transpose(Matrix4x4F matrix){return new Matrix4x4F(matrix.M11, matrix.M21, matrix.M31, matrix.M41,matrix.M12, matrix.M22, matrix.M32, matrix.M42,matrix.M13, matrix.M23, matrix.M33, matrix.M43,matrix.M14, matrix.M24, matrix.M34, matrix.M44);}}
cbuffer MyCamera{matrix View;matrix Projection;}struct VertexPositionColor{float4 Position : SV_Position;float4 Color : COLOR;};VertexPositionColor MyVertexShader(VertexPositionColor input){VertexPositionColor output = input;output.Position = mul(output.Position, View);output.Position = mul(output.Position, Projection);return output;}float4 MyPixelShader(VertexPositionColor input) : SV_Target{return input.Color;}