[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
あまりにも長いのでクラスを2分割しました。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 unsafe D3DBuffer CreateVertexBuffer(D3DDevice device, Vector3F[] vertices){fixed (Vector3F* fixedVertices = vertices){return device.CreateBuffer(new BufferDescription{ByteWidth = (uint)(Marshal.SizeOf(typeof(Vector3F)) * vertices.Length),BindingOptions = BindingOptions.VertexBuffer,},new SubresourceData{SystemMemory = new System.IntPtr(fixedVertices)});}}}class MyGame : Game{protected override void Draw(){this.DeviceContext.ClearRenderTargetView(RenderTargetView, new ColorRgba(0, 0, 1, 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(new[] {new InputElementDescription{SemanticName = "SV_Position",Format = Format.R32G32B32Float,}},vertexShaderBinary);}private void initTriangleToDraw(D3DDevice device){Vector3F[] vertices = new Vector3F[]{new Vector3F(0, 0.5f, 0),new Vector3F(0.5f, 0, 0),new Vector3F(-0.5f, 0, 0)};D3DBuffer vertexBuffer = CreateVertexBuffer(device, vertices);this.DeviceContext.IA.SetVertexBuffers(0,new D3DBuffer[] { vertexBuffer },new uint[] { (uint)Marshal.SizeOf(typeof(Vector3F)) },new uint[] { 0 });this.DeviceContext.IA.PrimitiveTopology = PrimitiveTopology.TriangleList;}}
説明 | XNAで言うと | |
シェーダー(頂点シェーダとピクセルシェーダ) | 頂点データがどのような処理をされて描画されるかを制御します。このコードではMyShader.vsとMyShader.psというファイルから読み込んでいます。 | Effect |
インプットレイアウト | 頂点データの意味を表します。(何バイト目が色のデータだ、など) | VertexDeclaration |
頂点バッファ | 描画する図形の頂点データを保持します。 | VertexBuffer |
ビューポート | 描画先の領域です。 | Viewport |
この意味は、ポリゴンの「頂点はそのままなにも動かさず、色は白にせよ」float4 MyVertexShader(float4 position : SV_Position) : SV_Position{return position;}float4 MyPixelShader() : SV_Target{return float4(1, 1, 1, 1);}
意味は"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\fxc.exe" /T vs_4_0 /E MyVertexShader /Fo MyShader.vs MyShader.fx@pause"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\fxc.exe" /T ps_4_0 /E MyPixelShader /Fo MyShader.ps MyShader.fx@pause
/T | 対象とするプロファイル。例えばvs_4_0やps_4_0です。これを入れ違えたり間違ってもfx_4_0などにしないでください。C#側からArgumentExceptionがスローされます。 |
/E | エントリーポイント。頂点シェーダなら頂点シェーダのメソッド名、ピクセルシェーダならピクセルシェーダのメソッド名です。 |
/Fo | 出力ファイル名 |
これは背景を青でクリアしています。using Microsoft.WindowsAPICodePack.DirectX.Direct3D11;using Microsoft.WindowsAPICodePack.DirectX.Graphics;class Program{static void Main(){using (Game game = new Game()){game.Run();}}}class Game : System.Windows.Forms.Form{SwapChain swapChain;DeviceContext deviceContext;RenderTargetView renderTargetView;public void Run(){initDevice();Show();while (Created){Draw();System.Windows.Forms.Application.DoEvents();}}private void Draw(){deviceContext.ClearRenderTargetView(renderTargetView, new ColorRgba(0, 0, 1, 1));swapChain.Present(0, PresentOptions.None);}private void 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);this.deviceContext.OM.RenderTargets = new OutputMergerRenderTargets(new[] { renderTargetView });}}}
クラス名 | 説明 | XNAで言うと |
SwapChain |
これはダブルバッファリングを行うための2つのバッファを持っています。
(片方が描画対象、もう片方はディスプレイに表示されるバッファ)
この2つのバッファは、描画が終わって実際にディスプレイに表示するときに
役割が交代(スワップ)します
|
GraphicsDeviceがこれの機能を持っています |
DeviceContext |
描画を行うオブジェクトです。
これを使ってポリゴンとかいろいろなものを描画します。
|
GraphicsDeviceがこれに近いです。 |
RenderTargetView | 描画する対象です。 | RenderTarget2Dでしょうか |
<?xml version="1.0" encoding="utf-8" ?><configuration><startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0"/></startup></configuration>
class Program{static void Main(){using (Game game = new Game()){game.Run();}}}class Game : System.Windows.Forms.Form{public void Run(){Show();while (Created){System.Windows.Forms.Application.DoEvents();}}}
5.times { |i| puts i }Rubyを使ったことのない方のために言うと、
0 1 2 3 4
class Program { static void Main(string[] args) { for (int i = 0; i < 5; i++) { System.Console.WriteLine(i); } } }
static class Int32Extension { public static void Times(this int loopCount, System.Action<int> loop) { for (int i = 0; i < loopCount; i++) { loop(i); } } }
class Program { static void Main(string[] args) { 5.Times(i => System.Console.WriteLine(i)); } }
public enum FigureType { Ellipse, Rectangle, Triangle }3つの値はそれぞれ図形のタイプを表しています。
using System.Windows; namespace DataTemplateSelectorDemo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); figuresView.ItemsSource = System.Enum.GetValues(typeof(FigureType)); } } public enum FigureType { Ellipse, Rectangle, Triangle } }
<Window x:Class="DataTemplateSelectorDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <ListBox x:Name="figuresView"/> </Window>
using System.Windows; using System.Windows.Controls; namespace DataTemplateSelectorDemo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); figuresView.ItemsSource = System.Enum.GetValues(typeof(FigureType)); } } public enum FigureType { Ellipse, Rectangle, Triangle } public class FigureTypeDataTemplateSelector : DataTemplateSelector {
public DataTemplate EllipseDataTemplate { get; set; }
public DataTemplate RectangleDataTemplate { get; set; }
public DataTemplate TriangleDataTemplate { get; set; }
public override DataTemplate SelectTemplate(
object item,
DependencyObject container
)
{
if (!(item is FigureType)) return null;
switch ((FigureType)item)
{
case FigureType.Ellipse:
return EllipseDataTemplate;
case FigureType.Rectangle:
return RectangleDataTemplate;
case FigureType.Triangle:
return TriangleDataTemplate;
default: return null;
}
}
}
}
<Window x:Class="DataTemplateSelectorDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:model="clr-namespace:DataTemplateSelectorDemo" Title="MainWindow" Height="350" Width="525"> <ListBox x:Name="figuresView" ItemTemplateSelector="{DynamicResource templateSelector}"/> <Window.Resources>
<DataTemplate x:Key="MyEllipseDataTemplate">
<Ellipse Stroke="Black" Width="100" Height="100"/>
</DataTemplate>
<DataTemplate x:Key="MyRectangleDataTemplate">
<Rectangle Stroke="Black" Width="150" Height="100"/>
</DataTemplate>
<DataTemplate x:Key="MyTriangleDataTemplate">
<Polygon Stroke="Black" Points="100,0 0,100 200,100"/>
</DataTemplate>
<model:FigureTypeDataTemplateSelector
x:Key="templateSelector"
EllipseDataTemplate="{StaticResource MyEllipseDataTemplate}"
RectangleDataTemplate="{StaticResource MyRectangleDataTemplate}"
TriangleDataTemplate="{StaticResource MyTriangleDataTemplate}"
/> </Window.Resources>
</Window>