[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
public int AlignedByteOffset { get; set; }これは要素のバイトオフセットを表します。
public static int AppendAligned { get; }
struct VertexName { Type MemberName : Semantics ... };
using SlimDX;using SlimDX.Direct3D11;using SlimDX.DXGI;using SlimDX.D3DCompiler;class Program{static void Main(){using (Game game = new MyGame()){game.Run();}}}class MyGame : Game{Effect effect;InputLayout vertexLayout;Buffer vertexBuffer;protected override void Draw(){GraphicsDevice.ImmediateContext.ClearRenderTargetView(RenderTarget,new SlimDX.Color4(1, 0.39f, 0.58f, 0.93f));initTriangleInputAssembler();drawTriangle();SwapChain.Present(0, PresentFlags.None);}private void initTriangleInputAssembler(){GraphicsDevice.ImmediateContext.InputAssembler.InputLayout = vertexLayout;GraphicsDevice.ImmediateContext.InputAssembler.SetVertexBuffers(0,new VertexBufferBinding(vertexBuffer, VertexPositionColor.SizeInBytes, 0));GraphicsDevice.ImmediateContext.InputAssembler.PrimitiveTopology= PrimitiveTopology.TriangleList;}private void drawTriangle(){effect.GetTechniqueByIndex(0).GetPassByIndex(0).Apply(GraphicsDevice.ImmediateContext);GraphicsDevice.ImmediateContext.Draw(3, 0);}protected override void LoadContent(){initEffect();initVertexLayout();initVertexBuffer();}private void initEffect(){using (ShaderBytecode shaderBytecode = ShaderBytecode.CompileFromFile("myEffect.fx", "fx_5_0",ShaderFlags.None,EffectFlags.None)){effect = new Effect(GraphicsDevice, shaderBytecode);}}private void initVertexLayout(){vertexLayout = new InputLayout(GraphicsDevice,effect.GetTechniqueByIndex(0).GetPassByIndex(0).Description.Signature,VertexPositionColor.VertexElements);}private void initVertexBuffer(){vertexBuffer = MyDirectXHelper.CreateVertexBuffer(GraphicsDevice,new[] {new VertexPositionColor{Position = new Vector3(0, 0.5f, 0),Color = new Vector3(1, 1, 1)},new VertexPositionColor{Position = new Vector3(0.5f, 0, 0),Color = new Vector3(0, 0, 1)},new VertexPositionColor{Position = new Vector3(-0.5f, 0, 0),Color = new Vector3(1, 0, 0)},});}protected override void UnloadContent(){effect.Dispose();vertexLayout.Dispose();vertexBuffer.Dispose();}}struct VertexPositionColor{public Vector3 Position;public Vector3 Color;public static readonly InputElement[] VertexElements = new[]{new InputElement{SemanticName = "SV_Position",Format = Format.R32G32B32_Float},new InputElement{SemanticName = "COLOR",Format = Format.R32G32B32_Float,AlignedByteOffset = InputElement.AppendAligned//自動的にオフセット決定}};public static int SizeInBytes{get{return System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertexPositionColor));}}}class Game : System.Windows.Forms.Form{public SlimDX.Direct3D11.Device GraphicsDevice;public SwapChain SwapChain;public RenderTargetView RenderTarget;public void Run(){initDevice();SlimDX.Windows.MessagePump.Run(this, Draw);disposeDevice();}private void initDevice(){MyDirectXHelper.CreateDeviceAndSwapChain(this, out GraphicsDevice, out SwapChain);initRenderTarget();initViewport();LoadContent();}private void initRenderTarget(){using (Texture2D backBuffer= SlimDX.Direct3D11.Resource.FromSwapChain<Texture2D>(SwapChain, 0)){RenderTarget = new RenderTargetView(GraphicsDevice, backBuffer);GraphicsDevice.ImmediateContext.OutputMerger.SetTargets(RenderTarget);}}private void initViewport(){GraphicsDevice.ImmediateContext.Rasterizer.SetViewports(new Viewport{Width = ClientSize.Width,Height = ClientSize.Height,});}private void disposeDevice(){UnloadContent();RenderTarget.Dispose();GraphicsDevice.Dispose();SwapChain.Dispose();}protected virtual void Draw() { }protected virtual void LoadContent() { }protected virtual void UnloadContent() { }}class MyDirectXHelper{public static void CreateDeviceAndSwapChain(System.Windows.Forms.Form form,out SlimDX.Direct3D11.Device device,out SlimDX.DXGI.SwapChain swapChain){SlimDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware,DeviceCreationFlags.None,new SwapChainDescription{BufferCount = 1,OutputHandle = form.Handle,IsWindowed = true,SampleDescription = new SampleDescription{Count = 1,Quality = 0},ModeDescription = new ModeDescription{Width = form.ClientSize.Width,Height = form.ClientSize.Height,RefreshRate = new SlimDX.Rational(60, 1),Format = Format.R8G8B8A8_UNorm},Usage = Usage.RenderTargetOutput},out device,out swapChain);}public static Buffer CreateVertexBuffer(SlimDX.Direct3D11.Device graphicsDevice,System.Array vertices){using (SlimDX.DataStream vertexStream= new SlimDX.DataStream(vertices, true, true)){return new Buffer(graphicsDevice,vertexStream,new BufferDescription{SizeInBytes= (int)vertexStream.Length,BindFlags = BindFlags.VertexBuffer,});}}}
struct VertexPositionColor{float4 Position : SV_Position;float4 Color : COLOR;};VertexPositionColor MyVertexShader(VertexPositionColor input){return input;}float4 MyPixelShader(VertexPositionColor input) : SV_Target{return input.Color;}technique10 MyTechnique{pass MyPass{SetVertexShader( CompileShader( vs_5_0, MyVertexShader() ) );SetPixelShader( CompileShader( ps_5_0, MyPixelShader() ) );}}
public class Buffer : Resource
public Buffer(Device device, DataStream data, BufferDescription description);
public class DataStream : Stream, IDisposableコンストラクタは3種類用意されていますが、
public DataStream(Array userBuffer, bool canRead, bool canWrite);
プロパティ名 | 型 | 説明 |
BindFlags | BindFlags | バッファがどういう役割を持っているかを表します。 たとえば頂点バッファとして使われるか(VertexBuffer)?インデックスバッファとして使われるか(IndexBuffer)?定数バッファとして使われるのか(ConstantBuffer)?シェーダーのリソースとして使われるのか(ShaderResource)?ストリームの出力として使われるのか(StreamOutput)?レンダーターゲットとして使われるのか(RenderTarget)?デプスステンシルバッファとして使われるのか(DepthStencil)?アンオーダードアクセス(複数のスレッドから同時に読み書き可能な)リソースとして使われるのか(UnorderedAccess)? ・・・・・・などです |
CpuAccessFlags | CpuAccessFlags | このバッファにCPUがいかほどのアクセス権限を持っているかを表します。None, Write, Readの3種類があります。 |
OptionFlags | ResourceOptionFlags | その他のオプションです。 たとえば、MipMapを生成するか?複数のデバイス間で共有されるか?TextureCubeか?インスタンシングを有効にするか?RawBufferか?StructuredBufferか?深度バイアスはどうするか?KeyedMutexか?GDIと互換性があるか? ・・・・・・などです。 |
SizeInBytes | int | バッファが何バイトか、を表します。 |
StructureByteStride | int | StructuredBufferとして使用する場合(OptionFlagsでそのように指定しなければいけません)に使います。ひとつの構造体のサイズが何バイトかを表します。 |
Usage | ResourceUsage | バッファの使われ方を表します。GPUが読み書きのできるDefault、GPUで読み取りのみ可能なImmutable、GPUからは読み取りのみCPUからは書き込みのみのDynamic、GPUからCPUへデータを転送できるStagingの4つです。 |
public class Effect : ComObject
public Effect(Device device, ShaderBytecode data);
public static ShaderBytecode CompileFromFile( string fileName, string profile, ShaderFlags shaderFlags, EffectFlags effectFlags );fileNameはエフェクトを記述したHLSLファイルの名前。 profileはシェーダーのバージョン(シェーダープロファイル)です。この値によってシェーダー中で使える機能が変わってきます。Direct3D11では5.0です。
public EffectTechnique GetTechniqueByIndex(int index);
public EffectPass GetPassByIndex(int index);
public Result Apply(DeviceContext context);
public EffectPassDescription Description { get; }
public ShaderSignature Signature { get; }おそらくインプットレイアウトは、シグネイチャのなかの、頂点情報が必要なのだと思われます。
public class InputLayout : DeviceChild
public InputLayout(Device device, ShaderSignature shaderSignature, InputElement[] elements);
public struct InputElement : IEquatable<InputElement>
public string SemanticName { get; set; }この文字列はなんでもいいというわけではありません。
public Format Format { get; set; }SlimDX.DXGI.Format列挙型はフォーマットを表します。
public class InputAssemblerWrapper
public InputAssemblerWrapper InputAssembler { get; }
public InputLayout InputLayout { get; set; }BufferをセットするのはInputAssemberWrapper.SetVertexBuffers()メソッドです。
public void SetVertexBuffers(int slot, VertexBufferBinding vertexBufferBinding);
プロパティ名 | 型 | 説明 |
Buffer | Buffer | セットするバッファです |
Offset | int | バッファの中の最初の頂点のインデックスです。普通0でいいでしょう。 |
Stride | int | ひとつの頂点のバイトサイズです |
public PrimitiveTopology PrimitiveTopology { get; set; }
public void Draw(int vertexCount, int startVertexLocation);
technique10 TechniqueName < Annotations > { pass PassName { [ SetStateGroup; ] [ SetStateGroup; ] ... [ SetStateGroup; ] } }
SetXXXShader( CompileShader( shader_profile, ShaderFunction( args ) ) );
float4 MyVertexShader(float4 position : SV_Position) : SV_Position { return position; }
float4 MyPixelShader() : SV_Target { return float4(1, 1, 1, 1); }
using SlimDX.Direct3D11;using SlimDX.DXGI;using SlimDX.D3DCompiler;class Program{static void Main(){using (Game game = new MyGame()){game.Run();}}}class MyGame : Game{Effect effect;InputLayout vertexLayout;Buffer vertexBuffer;protected override void Draw(){GraphicsDevice.ImmediateContext.ClearRenderTargetView(RenderTarget,new SlimDX.Color4(1, 0, 0, 1));initTriangleInputAssembler();drawTriangle();SwapChain.Present(0, PresentFlags.None);}private void drawTriangle(){effect.GetTechniqueByIndex(0).GetPassByIndex(0).Apply(GraphicsDevice.ImmediateContext);GraphicsDevice.ImmediateContext.Draw(3, 0);}private void initTriangleInputAssembler(){GraphicsDevice.ImmediateContext.InputAssembler.InputLayout = vertexLayout;GraphicsDevice.ImmediateContext.InputAssembler.SetVertexBuffers(0,new VertexBufferBinding(vertexBuffer, sizeof(float) * 3, 0));GraphicsDevice.ImmediateContext.InputAssembler.PrimitiveTopology= PrimitiveTopology.TriangleList;}protected override void LoadContent(){initEffect();initVertexLayout();initVertexBuffer();}private void initEffect(){using (ShaderBytecode shaderBytecode = ShaderBytecode.CompileFromFile("myEffect.fx", "fx_5_0",ShaderFlags.None,EffectFlags.None)){effect = new Effect(GraphicsDevice, shaderBytecode);}}private void initVertexLayout(){vertexLayout = new InputLayout(GraphicsDevice,effect.GetTechniqueByIndex(0).GetPassByIndex(0).Description.Signature,new[] {new InputElement{SemanticName = "SV_Position",Format = Format.R32G32B32_Float}});}private void initVertexBuffer(){vertexBuffer = MyDirectXHelper.CreateVertexBuffer(GraphicsDevice,new[] {new SlimDX.Vector3(0, 0.5f, 0),new SlimDX.Vector3(0.5f, 0, 0),new SlimDX.Vector3(-0.5f, 0, 0),});}protected override void UnloadContent(){effect.Dispose();vertexLayout.Dispose();vertexBuffer.Dispose();}}class Game : System.Windows.Forms.Form{public SlimDX.Direct3D11.Device GraphicsDevice;public SwapChain SwapChain;public RenderTargetView RenderTarget;public void Run(){initDevice();SlimDX.Windows.MessagePump.Run(this, Draw);disposeDevice();}private void initDevice(){MyDirectXHelper.CreateDeviceAndSwapChain(this, out GraphicsDevice, out SwapChain);initRenderTarget();initViewport();LoadContent();}private void initRenderTarget(){using (Texture2D backBuffer= SlimDX.Direct3D11.Resource.FromSwapChain<Texture2D>(SwapChain, 0)){RenderTarget = new RenderTargetView(GraphicsDevice, backBuffer);GraphicsDevice.ImmediateContext.OutputMerger.SetTargets(RenderTarget);}}private void initViewport(){GraphicsDevice.ImmediateContext.Rasterizer.SetViewports(new Viewport{Width = ClientSize.Width,Height = ClientSize.Height,});}private void disposeDevice(){UnloadContent();RenderTarget.Dispose();GraphicsDevice.Dispose();SwapChain.Dispose();}protected virtual void Draw() { }protected virtual void LoadContent() { }protected virtual void UnloadContent() { }}class MyDirectXHelper{public static void CreateDeviceAndSwapChain(System.Windows.Forms.Form form,out SlimDX.Direct3D11.Device device,out SlimDX.DXGI.SwapChain swapChain){SlimDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware,DeviceCreationFlags.None,new SwapChainDescription{BufferCount = 1,OutputHandle = form.Handle,IsWindowed = true,SampleDescription = new SampleDescription{Count = 1,Quality = 0},ModeDescription = new ModeDescription{Width = form.ClientSize.Width,Height = form.ClientSize.Height,RefreshRate = new SlimDX.Rational(60, 1),Format = Format.R8G8B8A8_UNorm},Usage = Usage.RenderTargetOutput},out device,out swapChain);}public static Buffer CreateVertexBuffer(SlimDX.Direct3D11.Device graphicsDevice,System.Array vertices){using (SlimDX.DataStream vertexStream= new SlimDX.DataStream(vertices, true, true)){return new Buffer(graphicsDevice,vertexStream,new BufferDescription{SizeInBytes= (int)vertexStream.Length,BindFlags = BindFlags.VertexBuffer,});}}}
float4 MyVertexShader(float4 position : SV_Position) : SV_Position{return position;}float4 MyPixelShader() : SV_Target{return float4(1, 1, 1, 1);}technique10 MyTechnique{pass MyPass{SetVertexShader( CompileShader( vs_5_0, MyVertexShader() ) );SetPixelShader( CompileShader( ps_5_0, MyPixelShader() ) );}}
public void ClearRenderTargetView(RenderTargetView view, Color4 color);viewはクリアする対象。レンダーターゲットといいます。
public DeviceContext ImmediateContext { get; }
public RenderTargetView(Device device, Resource resource);
public static T FromSwapChain(SwapChain swapChain, int index) where T : class, Resource;
public Result Present(int syncInterval, PresentFlags flags);syncIntervalは垂直同期とフレーム表示の同期方法を表します。0ならば同期せずに即座にプレゼントします。その他の値ならその分の垂直同期の後に表示を同期します。0でいいでしょう。
数値 | ||
None | 0 | |
Test | 1 | |
DoNotSequence | 2 |
public class Device : ComObjectこのクラスの初期化にはいくつかメソッドがあるのですが、
public static Result CreateWithSwapChain( DriverType driverType, DeviceCreationFlags flags, SwapChainDescription swapChainDescription, out Device device, out SwapChain swapChain );
引数名 | 説明 |
driverType | 生成するデバイスの種類です。 |
flags | 有効にするランタイムレイヤーのリストです。 |
swapChainDescription | スワップチェーンの生成用設定です。 |
device | 生成されたデバイスが格納されます。 |
swapChain | 生成されたスワップチェーンが格納されます。 |
DeviceTypeの値 | 説明 |
Unknown | タイプが不明 |
Hardware | Direct3Dの機能を持つハードウェアです。まずほとんどのばあいこれを使ってDeviceクラスを初期化することになります。ハードウェアを使うためかなり速いです。というかこれ以外では遅すぎてまず通常目的では使えません。これを使いましょう。 |
Reference | リファレンスドライバです。リファレンスドライバはソフトウェアで動いているため遅いです。遅いです―が正確で、デバッグ時やDirectXの機能をテストするというようなときには悪くはないのかもしれません。ただ、実際のアプリケーションで使う為のものではありません。 |
Null | Nullドライバです。これはリファレンスドライバから描画機能がなくなったようなものです。これもデバッグ用で、まず普通のアプリケーションで使うためのものではありません。 |
Software | Softwareドライバです。これは完全にソフトウェアで実装されています。やはり遅いため普通のアプリケーションで使うためのものではありません。 |
Warp | WARPドライバです。これもソフトウェアで動きますが、パフォーマンスは高いです。 |
DeviceCreationFlagsの値 | 数値 | 説明 |
None | 0 | デバイスに特別な振る舞いはもたせません。 |
SingleThreaded | 1 | アプリケーションがシングルスレッドでのみDirect3D11を呼ぶときに使います。もしこのフラグを使わなければ、Direct3D11のAPIを呼んでいる間ロックします。これは複数のスレッドが内部状態を変更しないようにするためです。このフラグを使えばロックは全くされず、パフォーマンスも落ちないでしょう。しかし複数のスレッドから呼ばれたときの振る舞いは未定義となります。 |
Debug | 2 | デバイスがDebugレイヤーをサポートするようになります。 |
SwitchToRef | 4 | デバイスをソフトウェア(REF)とハードウェア(HAL)両方のバージョンで生成します。これによってアプリケーションはリファレンスデバイスへと変わりデバッグを有効にすることができます。 |
PreventThreadingOptimization | 8 | 複数のスレッドが生成されないようにします。普通の用途では非推奨です。 |
BgraSupport | 32 | Direct3Dリソースとの相互運用をDirect2Dで実現するために必要です。 |
public class SwapChain : DeviceChild
それぞれのメンバの意味を以下に記します。public struct SwapChainDescription : IEquatable<SwapChainDescription>{public int BufferCount { get; set; }public SwapChainFlags Flags { get; set; }public bool IsWindowed { get; set; }public ModeDescription ModeDescription { get; set; }public IntPtr OutputHandle { get; set; }public SampleDescription SampleDescription { get; set; }public SwapEffect SwapEffect { get; set; }public Usage Usage { get; set; }..}
メンバ名 | 型 | 説明 |
BufferCount | int | バッファの数です。なぜこんなモノが存在するのかというと、スワップチェーンはダブルバッファリングを行えるので、そういったときにここに2を指定することになります。これが1だとティアリングが起きて画像が変なことになったりもあるようですが、別に気にならない人は気にならないでしょう。 |
Flags | SwapChainFlags | スワップチェーンのオプションフラグです。普通は指定しなくていいでしょう。 |
IsWindowed | bool | trueだとウィンドウモード、falseだとフルスクリーンモードです。 |
ModeDescription | ModeDescription | ウィンドウの大きさやリフレッシュレート、画像のフォーマットといった情報を表す構造体です。 |
OutputHandle | IntPtr | 表示するウィンドウのハンドルです。 |
SampleDescription | SampleDescription | スワップチェーンのマルチサンプルの方法をあらわす構造体です。 |
SwapEffect | SwapEffect | 表示した後に表示バッファをどうするかを指定する列挙型です。Discard とSequentialの2つがあります。明示的に指定しなくても大丈夫です。 |
Usage | Usage | 表示する画像の使われ方を表すフラグです。ShaderInput = 16, RenderTargetOutput = 32, BackBuffer = 64, Shared = 128, ReadOnly = 256, UnorderedAccess = 1024があります。今回は描画を行う対象なので、RenderTargetOutputです。 |
値 | 数値 | |
None | 0 | 特別な動作はしません。 |
NonPrerotated | 1 | イメージの自動回転をオフにします。前画面モードの時にのみ有効です。 |
AllowModeSwitch | 2 | これを指定するとSwapChain.ResizeTarget()メソッドを呼び出してモードを切り替えられるようになります。 |
Width | int | 表示する画像の横幅です。 |
Height | int | 表示する画像の縦幅です。 |
RefreshRate | Rational | 一秒間に画像を更新する頻度です。これは60でいいでしょう。このRationalは分数を表す構造体で、Numerator(分子)とDenominator(分母)プロパティがあります。 |
Format | Format | 表示する画像バッファのフォーマットです。ひとつのピクセルが具体的にどのようなデータなのか、ということを表します。たとえばR8G8B8A8_UNormは赤8bit緑8bit青8bitアルファ8bitといった具合です。 |
ScanlineOrdering | DisplayModeScanlineOrdering | 走査線描画モードです。指定しなくても問題ありません。 |
Scaling | DisplayModeScaling | スケーリングモードです。指定しなくても問題ありません。 |
class Program{static void Main(){using (Game game = new Game()){game.Run();}}}class Game : System.Windows.Forms.Form{SlimDX.Direct3D11.Device device;SlimDX.DXGI.SwapChain swapChain;public void Run(){initDevice();SlimDX.Windows.MessagePump.Run(this, Draw);disposeDevice();}private void initDevice(){SlimDX.Direct3D11.Device.CreateWithSwapChain(SlimDX.Direct3D11.DriverType.Hardware,SlimDX.Direct3D11.DeviceCreationFlags.None,new SlimDX.DXGI.SwapChainDescription{BufferCount = 1,OutputHandle = this.Handle,IsWindowed = true,SampleDescription = new SlimDX.DXGI.SampleDescription{Count = 1,Quality = 0},ModeDescription = new SlimDX.DXGI.ModeDescription{Width = ClientSize.Width,Height = ClientSize.Height,RefreshRate = new SlimDX.Rational(60, 1),Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm},Usage = SlimDX.DXGI.Usage.RenderTargetOutput},out device,out swapChain);}private void disposeDevice(){device.Dispose();swapChain.Dispose();}protected virtual void Draw() { }}