2 using System.Collections.Generic;
3 using System.Diagnostics;
9 /// Direct3D の D3DTexture を使って描画する画像。
11 public class テクスチャ : FDK.Activity
18 public float 不透明度 { get; set; } = 1f;
20 public bool 加算合成する { get; set; } = false;
22 public SharpDX.Size2F サイズdpx => ( this._ShaderResourceViewSize );
24 public テクスチャ( string 画像ファイルパス, SharpDX.Direct3D11.BindFlags bindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource )
26 this._bindFlags = bindFlags;
29 this._画像ファイルパス = 画像ファイルパス;
30 this.ユーザ指定サイズdpx = SharpDX.Size2.Empty;
33 public テクスチャ( SharpDX.Size2 サイズdpx, SharpDX.Direct3D11.BindFlags bindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource )
35 this._bindFlags = bindFlags;
38 this._画像ファイルパス = null;
39 this.ユーザ指定サイズdpx = サイズdpx;
42 protected override void Onデバイス依存リソースの作成( デバイスリソース dr )
44 var d3dDevice = (SharpDX.Direct3D11.Device) null;
45 using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
50 var cBufferDesc = new SharpDX.Direct3D11.BufferDescription() {
51 Usage = SharpDX.Direct3D11.ResourceUsage.Dynamic, // 動的使用法
52 BindFlags = SharpDX.Direct3D11.BindFlags.ConstantBuffer, // 定数バッファ
53 CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Write, // CPUから書き込む
54 OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
55 SizeInBytes = SharpDX.Utilities.SizeOf<ST定数バッファの転送元データ>(), // バッファサイズ
56 StructureByteStride = 0,
58 this._ConstantBuffer = new SharpDX.Direct3D11.Buffer( d3dDevice, cBufferDesc );
61 #region " テクスチャとシェーダーリソースビュー "
63 if( this._画像ファイルパス.Nullでも空でもない() )
65 // (A) 画像ファイルから生成する場合。
66 this._ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
69 FDK.フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this._画像ファイルパス ),
70 out this._ShaderResourceViewSize,
73 else if( this.ユーザ指定サイズdpx != SharpDX.Size2.Empty )
75 // (B) サイズを指定して生成する場合。
76 this._ShaderResourceView = FDK.Utilities.CreateShaderResourceView(
82 this._ShaderResourceViewSize = new SharpDX.Size2F( this.ユーザ指定サイズdpx.Width, this.ユーザ指定サイズdpx.Height );
86 throw new InvalidOperationException();
93 protected override void Onデバイス依存リソースの解放( デバイスリソース dr )
95 FDK.Utilities.解放する( ref this._ShaderResourceView );
96 FDK.Utilities.解放する( ref this.Texture );
97 FDK.Utilities.解放する( ref this._ConstantBuffer );
103 /// <param name="ワールド行列変換">
104 /// テクスチャは1×1のモデルサイズで表現されており、それにこのワールド行列を適用する。
106 /// <param name="転送元矩形">
107 /// テクスチャ座標(値域0~1)で指定する。
109 public void 描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null )
111 var d3dDevice = (SharpDX.Direct3D11.Device) null;
112 using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
114 using( var d3dContext = d3dDevice.ImmediateContext )
116 #region " 定数バッファを更新する。"
120 ワールド行列変換.Transpose(); // 転置
121 this._定数バッファの転送元データ.World = ワールド行列変換;
124 this._定数バッファの転送元データ.View = dr.ビュー変換行列; // 転置済み
127 this._定数バッファの転送元データ.Projection = dr.射影変換行列; // 転置済み
131 転送元矩形 = new SharpDX.RectangleF( 0f, 0f, 1f, 1f );
132 this._定数バッファの転送元データ.TexLeft = 転送元矩形.Value.Left;
133 this._定数バッファの転送元データ.TexTop = 転送元矩形.Value.Top;
134 this._定数バッファの転送元データ.TexRight = 転送元矩形.Value.Right;
135 this._定数バッファの転送元データ.TexBottom = 転送元矩形.Value.Bottom;
138 this._定数バッファの転送元データ.TexAlpha = this.不透明度;
139 this._定数バッファの転送元データ.dummy1 = 0f;
140 this._定数バッファの転送元データ.dummy2 = 0f;
141 this._定数バッファの転送元データ.dummy3 = 0f;
144 var dataBox = d3dContext.MapSubresource(
145 resourceRef: this._ConstantBuffer,
147 mapType: SharpDX.Direct3D11.MapMode.WriteDiscard,
148 mapFlags: SharpDX.Direct3D11.MapFlags.None );
149 SharpDX.Utilities.Write( dataBox.DataPointer, ref this._定数バッファの転送元データ );
150 d3dContext.UnmapSubresource( this._ConstantBuffer, 0 );
154 #region " 3Dパイプラインを設定する。"
157 using( var IA = d3dContext.InputAssembler )
159 IA.InputLayout = null;
160 IA.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
163 using( var VS = d3dContext.VertexShader )
165 VS.Set( テクスチャ._VertexShader );
166 VS.SetConstantBuffers( 0, this._ConstantBuffer );
169 using( var GS = d3dContext.GeometryShader )
171 d3dContext.GeometryShader.Set( null );
174 using( var RS = d3dContext.Rasterizer )
176 RS.SetViewports( dr.D3DViewPort );
177 RS.State = テクスチャ._RasterizerState;
180 using( var PS = d3dContext.PixelShader )
182 PS.Set( テクスチャ._PixelShader );
183 PS.SetConstantBuffers( 0, this._ConstantBuffer );
184 PS.SetShaderResources( 0, 1, this._ShaderResourceView );
185 PS.SetSamplers( 0, 1, テクスチャ._SamplerState );
188 using( var OM = d3dContext.OutputMerger )
190 OM.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
192 ( this.加算合成する ) ? テクスチャ._BlendState加算合成 : テクスチャ._BlendState通常合成,
193 new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
195 OM.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
200 // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
201 d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
205 protected SharpDX.Size2 ユーザ指定サイズdpx;
207 protected SharpDX.Direct3D11.Texture2D Texture = null;
209 private string _画像ファイルパス = null;
211 private SharpDX.Direct3D11.Buffer _ConstantBuffer = null;
213 private SharpDX.Direct3D11.ShaderResourceView _ShaderResourceView = null;
215 private SharpDX.Size2F _ShaderResourceViewSize;
217 private SharpDX.Direct3D11.BindFlags _bindFlags;
219 private struct ST定数バッファの転送元データ
221 public SharpDX.Matrix World; // ワールド変換行列
222 public SharpDX.Matrix View; // ビュー変換行列
223 public SharpDX.Matrix Projection; // 透視変換行列
225 public float TexLeft; // 描画元矩形の左u座標(0~1)
226 public float TexTop; // 描画元矩形の上v座標(0~1)
227 public float TexRight; // 描画元矩形の右u座標(0~1)
228 public float TexBottom; // 描画元矩形の下v座標(0~1)
230 public float TexAlpha; // テクスチャに乗じるアルファ値(0~1)
231 public float dummy1; // float4境界に合わせるためのダミー
232 public float dummy2; // float4境界に合わせるためのダミー
233 public float dummy3; // float4境界に合わせるためのダミー
236 private ST定数バッファの転送元データ _定数バッファの転送元データ;
239 // (2) 全インスタンス共通項目(static)
241 public static void 全インスタンスで共有するリソースを作成する( FDK.メディア.デバイスリソース dr )
243 var d3dDevice = (SharpDX.Direct3D11.Device) null;
244 using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
249 var シェーダコンパイルのオプション =
250 SharpDX.D3DCompiler.ShaderFlags.Debug |
251 SharpDX.D3DCompiler.ShaderFlags.SkipOptimization |
252 SharpDX.D3DCompiler.ShaderFlags.EnableStrictness |
253 SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor;
256 using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
257 FDK.Properties.Resources.テクスチャ用シェーダコード,
258 "VS", "vs_4_0", シェーダコンパイルのオプション ) )
261 テクスチャ._VertexShader = new SharpDX.Direct3D11.VertexShader( d3dDevice, code );
268 using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
269 FDK.Properties.Resources.テクスチャ用シェーダコード,
270 "PS", "ps_4_0", シェーダコンパイルのオプション ) )
273 テクスチャ._PixelShader = new SharpDX.Direct3D11.PixelShader( d3dDevice, code );
277 #region " ブレンドステート(通常)"
279 var BlendStateNorm = new SharpDX.Direct3D11.BlendStateDescription() {
280 AlphaToCoverageEnable = false, // アルファマスクで透過する(するならZバッファ必須)
281 IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
283 BlendStateNorm.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
284 BlendStateNorm.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All; // RGBA の書き込みマスク。
286 // アルファ値のブレンディング設定 ... 特になし
287 BlendStateNorm.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
288 BlendStateNorm.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
289 BlendStateNorm.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
291 // 色値のブレンディング設定 ... アルファ強度に応じた透明合成(テクスチャのアルファ値は、テクスチャのアルファ×ピクセルシェーダでの全体アルファとする(HLSL参照))
292 BlendStateNorm.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
293 BlendStateNorm.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.InverseSourceAlpha;
294 BlendStateNorm.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
297 テクスチャ._BlendState通常合成 = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendStateNorm );
300 #region " ブレンドステート(加算合成)"
302 var BlendStateAdd = new SharpDX.Direct3D11.BlendStateDescription() {
303 AlphaToCoverageEnable = false, // アルファマスクで透過する(するならZバッファ必須)
304 IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
306 BlendStateAdd.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
307 BlendStateAdd.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All; // RGBA の書き込みマスク。
309 // アルファ値のブレンディング設定 ... 特になし
310 BlendStateAdd.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
311 BlendStateAdd.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
312 BlendStateAdd.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
314 // 色値のブレンディング設定 ... 加算合成
315 BlendStateAdd.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
316 BlendStateAdd.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.One;
317 BlendStateAdd.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
320 テクスチャ._BlendState加算合成 = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendStateNorm );
323 #region " ラスタライザステート "
325 var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
326 FillMode = SharpDX.Direct3D11.FillMode.Solid, // 普通に描画する
327 CullMode = SharpDX.Direct3D11.CullMode.None, // 両面を描画する
328 IsFrontCounterClockwise = false, // 時計回りが表面
331 SlopeScaledDepthBias = 0,
332 IsDepthClipEnabled = true,
333 IsScissorEnabled = false,
334 IsMultisampleEnabled = false,
335 IsAntialiasedLineEnabled = false,
337 テクスチャ._RasterizerState = new SharpDX.Direct3D11.RasterizerState( d3dDevice, RSDesc );
340 #region " サンプラーステート "
342 var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
343 Filter = SharpDX.Direct3D11.Filter.Anisotropic,
344 AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
345 AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
346 AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
348 MaximumAnisotropy = 2,
349 ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
350 BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
351 MinimumLod = float.MinValue,
352 MaximumLod = float.MaxValue,
354 テクスチャ._SamplerState = new SharpDX.Direct3D11.SamplerState( d3dDevice, descSampler );
360 public static void 全インスタンスで共有するリソースを解放する()
362 FDK.Utilities.解放する( ref テクスチャ._SamplerState );
363 FDK.Utilities.解放する( ref テクスチャ._RasterizerState );
364 FDK.Utilities.解放する( ref テクスチャ._BlendState加算合成 );
365 FDK.Utilities.解放する( ref テクスチャ._BlendState通常合成 );
366 FDK.Utilities.解放する( ref テクスチャ._PixelShader );
367 FDK.Utilities.解放する( ref テクスチャ._VertexShader );
370 private static SharpDX.Direct3D11.VertexShader _VertexShader = null;
372 private static SharpDX.Direct3D11.PixelShader _PixelShader = null;
374 private static SharpDX.Direct3D11.BlendState _BlendState通常合成 = null;
376 private static SharpDX.Direct3D11.BlendState _BlendState加算合成 = null;
378 private static SharpDX.Direct3D11.RasterizerState _RasterizerState = null;
380 private static SharpDX.Direct3D11.SamplerState _SamplerState = null;