OSDN Git Service

インストーラでインストールした SSTFEditor を起動するとメッセージが規定(英語)になるミスを修正。
[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         /// <summary>
9         ///             Direct3D の D3DTexture を使って描画する画像。
10         /// </summary>
11         public class テクスチャ : FDK.Activity
12         {
13                 // (1) 個別項目
14
15                 /// <summary>
16                 ///             0:透明~1:不透明
17                 /// </summary>
18                 public float 不透明度 { get; set; } = 1f;
19
20                 public bool 加算合成する { get; set; } = false;
21
22                 public SharpDX.Size2F サイズdpx => ( this._ShaderResourceViewSize );
23
24                 public テクスチャ( string 画像ファイルパス, SharpDX.Direct3D11.BindFlags bindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource )
25                 {
26                         this._bindFlags = bindFlags;
27
28                         // ↓ どちらかを選択的に指定すること。
29                         this._画像ファイルパス = 画像ファイルパス;
30                         this.ユーザ指定サイズdpx = SharpDX.Size2.Empty;
31                 }
32
33                 public テクスチャ( SharpDX.Size2 サイズdpx, SharpDX.Direct3D11.BindFlags bindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource )
34                 {
35                         this._bindFlags = bindFlags;
36
37                         // ↓ どちらかを選択的に指定すること。
38                         this._画像ファイルパス = null;
39                         this.ユーザ指定サイズdpx = サイズdpx;
40                 }
41
42                 protected override void Onデバイス依存リソースの作成( デバイスリソース dr )
43                 {
44                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
45                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
46                         using( d3dDevice )
47                         {
48                                 #region " 定数バッファ "
49                                 //----------------
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,
57                                 };
58                                 this._ConstantBuffer = new SharpDX.Direct3D11.Buffer( d3dDevice, cBufferDesc );
59                                 //----------------
60                                 #endregion
61                                 #region " テクスチャとシェーダーリソースビュー "
62                                 //----------------
63                                 if( this._画像ファイルパス.Nullでも空でもない() )
64                                 {
65                                         // (A) 画像ファイルから生成する場合。
66                                         this._ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
67                                                 d3dDevice,
68                                                 this._bindFlags,
69                                                 FDK.フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this._画像ファイルパス ),
70                                                 out this._ShaderResourceViewSize,
71                                                 out this.Texture );
72                                 }
73                                 else if( this.ユーザ指定サイズdpx != SharpDX.Size2.Empty )
74                                 {
75                                         // (B) サイズを指定して生成する場合。
76                                         this._ShaderResourceView = FDK.Utilities.CreateShaderResourceView(
77                                                 d3dDevice,
78                                                 this._bindFlags,
79                                                 this.ユーザ指定サイズdpx,
80                                                 out this.Texture );
81
82                                         this._ShaderResourceViewSize = new SharpDX.Size2F( this.ユーザ指定サイズdpx.Width, this.ユーザ指定サイズdpx.Height );
83                                 }
84                                 else
85                                 {
86                                         throw new InvalidOperationException();
87                                 }
88                                 //----------------
89                                 #endregion
90                         }
91                 }
92
93                 protected override void Onデバイス依存リソースの解放( デバイスリソース dr )
94                 {
95                         FDK.Utilities.解放する( ref this._ShaderResourceView );
96                         FDK.Utilities.解放する( ref this.Texture );
97                         FDK.Utilities.解放する( ref this._ConstantBuffer );
98                 }
99
100                 /// <summary>
101                 ///             テクスチャを描画する。
102                 ///     </summary>
103                 /// <param name="ワールド行列変換">
104                 ///             テクスチャは1×1のモデルサイズで表現されており、それにこのワールド行列を適用する。
105                 ///     </param>
106                 /// <param name="転送元矩形">
107                 ///             テクスチャ座標(値域0~1)で指定する。
108                 ///     </param>
109                 public void 描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null )
110                 {
111                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
112                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
113                         using( d3dDevice )
114                         using( var d3dContext = d3dDevice.ImmediateContext )
115                         {
116                                 #region " 定数バッファを更新する。"
117                                 //----------------
118                                 {
119                                         // ワールド変換行列
120                                         ワールド行列変換.Transpose();    // 転置
121                                         this._定数バッファの転送元データ.World = ワールド行列変換;
122
123                                         // ビュー変換行列
124                                         this._定数バッファの転送元データ.View = dr.ビュー変換行列;  // 転置済み
125
126                                         // 射影変換行列
127                                         this._定数バッファの転送元データ.Projection = dr.射影変換行列;       // 転置済み
128
129                                         // 描画元矩形
130                                         if( null == 転送元矩形 )
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;
136
137                                         // アルファ
138                                         this._定数バッファの転送元データ.TexAlpha = this.不透明度;
139                                         this._定数バッファの転送元データ.dummy1 = 0f;
140                                         this._定数バッファの転送元データ.dummy2 = 0f;
141                                         this._定数バッファの転送元データ.dummy3 = 0f;
142
143                                         // 定数バッファへ書き込む。
144                                         var dataBox = d3dContext.MapSubresource(
145                                                 resourceRef: this._ConstantBuffer,
146                                                 subresource: 0,
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 );
151                                 }
152                                 //----------------
153                                 #endregion
154                                 #region " 3Dパイプラインを設定する。"
155                                 //----------------
156                                 // 入力アセンブラ
157                                 using( var IA = d3dContext.InputAssembler )
158                                 {
159                                         IA.InputLayout = null;
160                                         IA.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
161                                 }
162                                 // 頂点シェーダ
163                                 using( var VS = d3dContext.VertexShader )
164                                 {
165                                         VS.Set( テクスチャ._VertexShader );
166                                         VS.SetConstantBuffers( 0, this._ConstantBuffer );
167                                 }
168                                 // ジオメトリシェーダ
169                                 using( var GS = d3dContext.GeometryShader )
170                                 {
171                                         d3dContext.GeometryShader.Set( null );
172                                 }
173                                 // ラスタライザ
174                                 using( var RS = d3dContext.Rasterizer )
175                                 {
176                                         RS.SetViewports( dr.D3DViewPort );
177                                         RS.State = テクスチャ._RasterizerState;
178                                 }
179                                 // ピクセルシェーダ
180                                 using( var PS = d3dContext.PixelShader )
181                                 {
182                                         PS.Set( テクスチャ._PixelShader );
183                                         PS.SetConstantBuffers( 0, this._ConstantBuffer );
184                                         PS.SetShaderResources( 0, 1, this._ShaderResourceView );
185                                         PS.SetSamplers( 0, 1, テクスチャ._SamplerState );
186                                 }
187                                 // 出力マージャ
188                                 using( var OM = d3dContext.OutputMerger )
189                                 {
190                                         OM.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
191                                         OM.SetBlendState(
192                                                 ( this.加算合成する ) ? テクスチャ._BlendState加算合成 : テクスチャ._BlendState通常合成,
193                                                 new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
194                                                 -1 );
195                                         OM.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
196                                 }
197                                 //----------------
198                                 #endregion
199
200                                 // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
201                                 d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
202                         }
203                 }
204
205                 protected SharpDX.Size2 ユーザ指定サイズdpx;
206
207                 protected SharpDX.Direct3D11.Texture2D Texture = null;
208
209                 private string _画像ファイルパス = null;
210
211                 private SharpDX.Direct3D11.Buffer _ConstantBuffer = null;
212
213                 private SharpDX.Direct3D11.ShaderResourceView _ShaderResourceView = null;
214
215                 private SharpDX.Size2F _ShaderResourceViewSize;
216
217                 private SharpDX.Direct3D11.BindFlags _bindFlags;
218
219                 private struct ST定数バッファの転送元データ
220                 {
221                         public SharpDX.Matrix World;      // ワールド変換行列
222                         public SharpDX.Matrix View;       // ビュー変換行列
223                         public SharpDX.Matrix Projection; // 透視変換行列
224
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)
229
230                         public float TexAlpha;  // テクスチャに乗じるアルファ値(0~1)
231                         public float dummy1;    // float4境界に合わせるためのダミー
232                         public float dummy2;    // float4境界に合わせるためのダミー
233                         public float dummy3;    // float4境界に合わせるためのダミー
234                 };
235
236                 private ST定数バッファの転送元データ _定数バッファの転送元データ;
237
238
239                 // (2) 全インスタンス共通項目(static)
240
241                 public static void 全インスタンスで共有するリソースを作成する( FDK.メディア.デバイスリソース dr )
242                 {
243                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
244                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
245                         using( d3dDevice )
246                         {
247                                 #region " 頂点シェーダ "
248                                 //----------------
249                                 var シェーダコンパイルのオプション =
250                                         SharpDX.D3DCompiler.ShaderFlags.Debug |
251                                         SharpDX.D3DCompiler.ShaderFlags.SkipOptimization |
252                                         SharpDX.D3DCompiler.ShaderFlags.EnableStrictness |
253                                         SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor;
254
255                                 // シェーダコードをコンパイルする。
256                                 using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
257                                         FDK.Properties.Resources.テクスチャ用シェーダコード,
258                                         "VS", "vs_4_0", シェーダコンパイルのオプション ) )
259                                 {
260                                         // 頂点シェーダを生成する。
261                                         テクスチャ._VertexShader = new SharpDX.Direct3D11.VertexShader( d3dDevice, code );
262                                 }
263                                 //----------------
264                                 #endregion
265                                 #region " ピクセルシェーダ "
266                                 //----------------
267                                 // シェーダコードをコンパイルする。
268                                 using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
269                                         FDK.Properties.Resources.テクスチャ用シェーダコード,
270                                         "PS", "ps_4_0", シェーダコンパイルのオプション ) )
271                                 {
272                                         // ピクセルシェーダを作成する。
273                                         テクスチャ._PixelShader = new SharpDX.Direct3D11.PixelShader( d3dDevice, code );
274                                 }
275                                 //----------------
276                                 #endregion
277                                 #region " ブレンドステート(通常)"
278                                 //----------------
279                                 var BlendStateNorm = new SharpDX.Direct3D11.BlendStateDescription() {
280                                         AlphaToCoverageEnable = false,  // アルファマスクで透過する(するならZバッファ必須)
281                                         IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
282                                 };
283                                 BlendStateNorm.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
284                                 BlendStateNorm.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All;        // RGBA の書き込みマスク。
285
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;
290
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;
295
296                                 // ブレンドステートを作成する。
297                                 テクスチャ._BlendState通常合成 = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendStateNorm );
298                                 //----------------
299                                 #endregion
300                                 #region " ブレンドステート(加算合成)"
301                                 //----------------
302                                 var BlendStateAdd = new SharpDX.Direct3D11.BlendStateDescription() {
303                                         AlphaToCoverageEnable = false,  // アルファマスクで透過する(するならZバッファ必須)
304                                         IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
305                                 };
306                                 BlendStateAdd.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
307                                 BlendStateAdd.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All;        // RGBA の書き込みマスク。
308
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;
313
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;
318
319                                 // ブレンドステートを作成する。
320                                 テクスチャ._BlendState加算合成 = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendStateNorm );
321                                 //----------------
322                                 #endregion
323                                 #region " ラスタライザステート "
324                                 //----------------
325                                 var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
326                                         FillMode = SharpDX.Direct3D11.FillMode.Solid,   // 普通に描画する
327                                         CullMode = SharpDX.Direct3D11.CullMode.None,    // 両面を描画する
328                                         IsFrontCounterClockwise = false,    // 時計回りが表面
329                                         DepthBias = 0,
330                                         DepthBiasClamp = 0,
331                                         SlopeScaledDepthBias = 0,
332                                         IsDepthClipEnabled = true,
333                                         IsScissorEnabled = false,
334                                         IsMultisampleEnabled = false,
335                                         IsAntialiasedLineEnabled = false,
336                                 };
337                                 テクスチャ._RasterizerState = new SharpDX.Direct3D11.RasterizerState( d3dDevice, RSDesc );
338                                 //----------------
339                                 #endregion
340                                 #region " サンプラーステート "
341                                 //----------------
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,
347                                         MipLodBias = 0.0f,
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,
353                                 };
354                                 テクスチャ._SamplerState = new SharpDX.Direct3D11.SamplerState( d3dDevice, descSampler );
355                                 //----------------
356                                 #endregion
357                         }
358                 }
359
360                 public static void 全インスタンスで共有するリソースを解放する()
361                 {
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 );
368                 }
369
370                 private static SharpDX.Direct3D11.VertexShader _VertexShader = null;
371
372                 private static SharpDX.Direct3D11.PixelShader _PixelShader = null;
373
374                 private static SharpDX.Direct3D11.BlendState _BlendState通常合成 = null;
375
376                 private static SharpDX.Direct3D11.BlendState _BlendState加算合成 = null;
377
378                 private static SharpDX.Direct3D11.RasterizerState _RasterizerState = null;
379
380                 private static SharpDX.Direct3D11.SamplerState _SamplerState = null;
381         }
382 }