OSDN Git Service

FDKについて、Activity の メソッド分離を完了。
[strokestylet/CsWin10Desktop3.git] / FDK24 / メディア / テクスチャ.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5
6 namespace FDK.メディア
7 {
8         public class テクスチャ : FDK.Activity
9         {
10                 // 個別項目
11
12                 /// <summary>
13                 /// 0:透明~1:不透明
14                 /// </summary>
15                 public float 不透明度 { get; set; } = 1f;
16                 public bool 加算合成する { get; set; } = false;
17                 public SharpDX.Size2F サイズdpx => this.ShaderResourceViewSize;
18                 public SharpDX.Matrix 等倍スケーリング行列 => SharpDX.Matrix.Scaling( this.サイズdpx.Width, this.サイズdpx.Height, 1f );
19
20                 public テクスチャ( string 画像ファイルパス )
21                 {
22                         this.画像ファイルパス = 画像ファイルパス;
23                 }
24                 protected override void Onデバイス依存リソースの作成( デバイスリソース dr )
25                 {
26                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
27                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
28                         {
29                                 #region " 定数バッファ "
30                                 //----------------
31                                 var cBufferDesc = new SharpDX.Direct3D11.BufferDescription() {
32                                         Usage = SharpDX.Direct3D11.ResourceUsage.Dynamic,   // 動的使用法
33                                         BindFlags = SharpDX.Direct3D11.BindFlags.ConstantBuffer,    // 定数バッファ
34                                         CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Write,   // CPUから書き込む
35                                         OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
36                                         SizeInBytes = SharpDX.Utilities.SizeOf<ST定数バッファの転送元データ>(),   // バッファサイズ
37                                         StructureByteStride = 0,
38                                 };
39                                 this.ConstantBuffer = new SharpDX.Direct3D11.Buffer( d3dDevice, cBufferDesc );
40                                 //----------------
41                                 #endregion
42                                 #region " シェーダーリソースビュー "
43                                 //----------------
44                                 this.ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
45                                         d3dDevice, FDK.フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this.画像ファイルパス ), out this.ShaderResourceViewSize );
46                                 //----------------
47                                 #endregion
48                         }
49                 }
50                 protected override void Onデバイス依存リソースの解放( デバイスリソース dr )
51                 {
52                         FDK.Utilities.解放する( ref this.ShaderResourceView );
53                         FDK.Utilities.解放する( ref this.ConstantBuffer );
54                 }
55
56                 /// <param name="転送元矩形">テクスチャ座標(値域0~1)で指定する。</param>
57                 public void 進行描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null )
58                 {
59                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
60                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
61                         {
62                                 var d3dContext = d3dDevice.ImmediateContext;
63
64                                 #region " 定数バッファを更新する。"
65                                 //----------------
66                                 {
67                                         // ワールド変換行列
68                                         ワールド行列変換.Transpose();    // 転置
69                                         this.定数バッファの転送元データ.World = ワールド行列変換;
70
71                                         // ビュー変換行列
72                                         this.定数バッファの転送元データ.View = dr.ビュー変換行列;
73
74                                         // 射影変換行列
75                                         this.定数バッファの転送元データ.Projection = dr.射影変換行列;
76
77                                         // 描画元矩形
78                                         if( null == 転送元矩形 )
79                                                 転送元矩形 = new SharpDX.RectangleF( 0f, 0f, 1f, 1f );
80                                         this.定数バッファの転送元データ.TexLeft = 転送元矩形.Value.Left;
81                                         this.定数バッファの転送元データ.TexTop = 転送元矩形.Value.Top;
82                                         this.定数バッファの転送元データ.TexRight = 転送元矩形.Value.Right;
83                                         this.定数バッファの転送元データ.TexBottom = 転送元矩形.Value.Bottom;
84
85                                         // アルファ
86                                         this.定数バッファの転送元データ.TexAlpha = this.不透明度;
87                                         this.定数バッファの転送元データ.dummy1 = 0f;
88                                         this.定数バッファの転送元データ.dummy2 = 0f;
89                                         this.定数バッファの転送元データ.dummy3 = 0f;
90
91                                         // 定数バッファへの書き込み
92                                         var dataBox = d3dContext.MapSubresource(
93                                                 resourceRef: this.ConstantBuffer,
94                                                 subresource: 0,
95                                                 mapType: SharpDX.Direct3D11.MapMode.WriteDiscard,
96                                                 mapFlags: SharpDX.Direct3D11.MapFlags.None );
97                                         SharpDX.Utilities.Write( dataBox.DataPointer, ref this.定数バッファの転送元データ );
98                                         d3dContext.UnmapSubresource( this.ConstantBuffer, 0 );
99                                 }
100                                 //----------------
101                                 #endregion
102                                 #region " 3Dパイプラインを設定する。"
103                                 //----------------
104                                 // 入力アセンブラ
105                                 d3dContext.InputAssembler.InputLayout = null;
106                                 d3dContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
107
108                                 // 頂点シェーダ
109                                 d3dContext.VertexShader.Set( テクスチャ.VertexShader );
110                                 d3dContext.VertexShader.SetConstantBuffers( 0, this.ConstantBuffer );
111
112                                 // ジオメトリシェーダ
113                                 d3dContext.GeometryShader.Set( null );
114
115                                 // ラスタライザ
116                                 d3dContext.Rasterizer.SetViewports( dr.D3DViewPort );
117                                 d3dContext.Rasterizer.State = テクスチャ.RasterizerState;
118
119                                 // ピクセルシェーダ
120                                 d3dContext.PixelShader.Set( テクスチャ.PixelShader );
121                                 d3dContext.PixelShader.SetConstantBuffers( 0, this.ConstantBuffer );
122                                 d3dContext.PixelShader.SetShaderResources( 0, 1, this.ShaderResourceView );
123                                 d3dContext.PixelShader.SetSamplers( 0, 1, テクスチャ.SamplerState );
124
125                                 // 出力マージャ
126                                 d3dContext.OutputMerger.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
127                                 d3dContext.OutputMerger.SetBlendState(
128                                         ( this.加算合成する ) ? テクスチャ.BlendStateAdd : テクスチャ.BlendStateNormal,
129                                         new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
130                                         -1 );
131                                 d3dContext.OutputMerger.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
132                                 //----------------
133                                 #endregion
134
135                                 // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
136                                 d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
137                         }
138                 }
139
140                 protected string 画像ファイルパス = null;
141                 protected struct ST定数バッファの転送元データ
142                 {
143                         public SharpDX.Matrix World;      // ワールド変換行列
144                         public SharpDX.Matrix View;       // ビュー変換行列
145                         public SharpDX.Matrix Projection; // 透視変換行列
146
147                         public float TexLeft;   // 描画元矩形の左u座標(0~1)
148                         public float TexTop;    // 描画元矩形の上v座標(0~1)
149                         public float TexRight;  // 描画元矩形の右u座標(0~1)
150                         public float TexBottom; // 描画元矩形の下v座標(0~1)
151
152                         public float TexAlpha;  // テクスチャに乗じるアルファ値(0~1)
153                         public float dummy1;    // float4境界に合わせるためのダミー
154                         public float dummy2;    // float4境界に合わせるためのダミー
155                         public float dummy3;    // float4境界に合わせるためのダミー
156                 };
157                 protected ST定数バッファの転送元データ 定数バッファの転送元データ;
158                 protected SharpDX.Direct3D11.Buffer ConstantBuffer = null;
159                 protected SharpDX.Direct3D11.ShaderResourceView ShaderResourceView = null;
160                 protected SharpDX.Size2F ShaderResourceViewSize;
161
162                 // 全インスタンス共通項目(static)
163
164                 public static void 共有リソースを作成する( FDK.メディア.デバイスリソース dr )
165                 {
166                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
167                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
168                         {
169                                 #region " 頂点シェーダ "
170                                 //----------------
171                                 var シェーダコンパイルのオプション =
172                                 SharpDX.D3DCompiler.ShaderFlags.Debug |
173                                 SharpDX.D3DCompiler.ShaderFlags.SkipOptimization |
174                                 SharpDX.D3DCompiler.ShaderFlags.EnableStrictness |
175                                 SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor;
176
177                                 // シェーダコードをコンパイルする。
178                                 using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
179                                         FDK.Properties.Resources.テクスチャ用シェーダコード,
180                                         "VS", "vs_4_0", シェーダコンパイルのオプション ) )
181                                 {
182                                         // 頂点シェーダを生成する。
183                                         テクスチャ.VertexShader = new SharpDX.Direct3D11.VertexShader( d3dDevice, code );
184                                 }
185                                 //----------------
186                                 #endregion
187                                 #region " ピクセルシェーダ "
188                                 //----------------
189                                 // シェーダコードをコンパイルする。
190                                 using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
191                                         FDK.Properties.Resources.テクスチャ用シェーダコード,
192                                         "PS", "ps_4_0", シェーダコンパイルのオプション ) )
193                                 {
194                                         // ピクセルシェーダを作成する。
195                                         テクスチャ.PixelShader = new SharpDX.Direct3D11.PixelShader( d3dDevice, code );
196                                 }
197                                 //----------------
198                                 #endregion
199                                 #region " ブレンドステート(通常)"
200                                 //----------------
201                                 var BlendStateNorm = new SharpDX.Direct3D11.BlendStateDescription() {
202                                         AlphaToCoverageEnable = false,  // アルファマスクで透過する(するならZバッファ必須)
203                                         IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
204                                 };
205                                 BlendStateNorm.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
206                                 BlendStateNorm.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All;        // RGBA の書き込みマスク。
207
208                                 // アルファ値のブレンディング設定 ... 特になし
209                                 BlendStateNorm.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
210                                 BlendStateNorm.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
211                                 BlendStateNorm.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
212
213                                 // 色値のブレンディング設定 ... アルファ強度に応じた透明合成(テクスチャのアルファ値は、テクスチャのアルファ×ピクセルシェーダでの全体アルファとする(HLSL参照))
214                                 BlendStateNorm.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
215                                 BlendStateNorm.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.InverseSourceAlpha;
216                                 BlendStateNorm.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
217
218                                 // ブレンドステートを作成する。
219                                 テクスチャ.BlendStateNormal = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendStateNorm );
220                                 //----------------
221                                 #endregion
222                                 #region " ブレンドステート(加算合成)"
223                                 //----------------
224                                 var BlendStateAdd = new SharpDX.Direct3D11.BlendStateDescription() {
225                                         AlphaToCoverageEnable = false,  // アルファマスクで透過する(するならZバッファ必須)
226                                         IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
227                                 };
228                                 BlendStateAdd.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
229                                 BlendStateAdd.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All;        // RGBA の書き込みマスク。
230
231                                 // アルファ値のブレンディング設定 ... 特になし
232                                 BlendStateAdd.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
233                                 BlendStateAdd.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
234                                 BlendStateAdd.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
235
236                                 // 色値のブレンディング設定 ... 加算合成
237                                 BlendStateAdd.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
238                                 BlendStateAdd.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.One;
239                                 BlendStateAdd.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
240
241                                 // ブレンドステートを作成する。
242                                 テクスチャ.BlendStateAdd = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendStateNorm );
243                                 //----------------
244                                 #endregion
245                                 #region " ラスタライザステート "
246                                 //----------------
247                                 var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
248                                         FillMode = SharpDX.Direct3D11.FillMode.Solid,   // 普通に描画する
249                                         CullMode = SharpDX.Direct3D11.CullMode.None,    // 両面を描画する
250                                         IsFrontCounterClockwise = false,    // 時計回りが表面
251                                         DepthBias = 0,
252                                         DepthBiasClamp = 0,
253                                         SlopeScaledDepthBias = 0,
254                                         IsDepthClipEnabled = true,
255                                         IsScissorEnabled = false,
256                                         IsMultisampleEnabled = false,
257                                         IsAntialiasedLineEnabled = false,
258                                 };
259                                 テクスチャ.RasterizerState = new SharpDX.Direct3D11.RasterizerState( d3dDevice, RSDesc );
260                                 //----------------
261                                 #endregion
262                                 #region " サンプラーステート "
263                                 //----------------
264                                 var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
265                                         Filter = SharpDX.Direct3D11.Filter.Anisotropic,
266                                         AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
267                                         AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
268                                         AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
269                                         MipLodBias = 0.0f,
270                                         MaximumAnisotropy = 2,
271                                         ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
272                                         BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
273                                         MinimumLod = float.MinValue,
274                                         MaximumLod = float.MaxValue,
275                                 };
276                                 テクスチャ.SamplerState = new SharpDX.Direct3D11.SamplerState( d3dDevice, descSampler );
277                                 //----------------
278                                 #endregion
279                         }
280                 }
281                 public static void 共有リソースを解放する()
282                 {
283                         FDK.Utilities.解放する( ref テクスチャ.SamplerState );
284                         FDK.Utilities.解放する( ref テクスチャ.RasterizerState );
285                         FDK.Utilities.解放する( ref テクスチャ.BlendStateAdd );
286                         FDK.Utilities.解放する( ref テクスチャ.BlendStateNormal );
287                         FDK.Utilities.解放する( ref テクスチャ.PixelShader );
288                         FDK.Utilities.解放する( ref テクスチャ.VertexShader );
289                 }
290
291                 protected static SharpDX.Direct3D11.VertexShader VertexShader = null;
292                 protected static SharpDX.Direct3D11.PixelShader PixelShader = null;
293                 protected static SharpDX.Direct3D11.BlendState BlendStateNormal = null;
294                 protected static SharpDX.Direct3D11.BlendState BlendStateAdd = null;
295                 protected static SharpDX.Direct3D11.RasterizerState RasterizerState = null;
296                 protected static SharpDX.Direct3D11.SamplerState SamplerState = null;
297         }
298 }