OSDN Git Service

AutoD3DDeviceLock で IntPtr が解放されていなかったミスを修正。
[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 デバイスリソース : IDisposable
9         {
10                 public SharpDX.Size2F 設計画面サイズdpx = new SharpDX.Size2F( 1920f, 1080f );    // 設計サイズ。
11                 public SharpDX.Size2F 物理画面サイズpx = new SharpDX.Size2F( 0, 0 );   // (0, 0) は、サイズ依存リソース無効の印。
12                 public IntPtr ウィンドウハンドル = IntPtr.Zero;
13                 public float 視野角deg { get; set; } = 45f;
14                 public SharpDX.Matrix ビュー変換行列
15                 {
16                         get
17                         {
18                                 var カメラの位置 = new SharpDX.Vector3( 0f, 0f, ( -2f * this.dz( this.設計画面サイズdpx.Height, this.視野角deg ) ) );
19                                 var カメラの注視点 = new SharpDX.Vector3( 0f, 0f, 0f );
20                                 var カメラの上方向 = new SharpDX.Vector3( 0f, 1f, 0f );
21                                 var mat = SharpDX.Matrix.LookAtLH( カメラの位置, カメラの注視点, カメラの上方向 );
22                                 mat.Transpose();  // 転置
23                                 return mat;
24                         }
25                 }
26                 public SharpDX.Matrix 射影変換行列
27                 {
28                         get
29                         {
30                                 float dz = this.dz( this.設計画面サイズdpx.Height, this.視野角deg );
31                                 var mat = SharpDX.Matrix.PerspectiveFovLH(
32                                         SharpDX.MathUtil.DegreesToRadians( 視野角deg ),
33                                         設計画面サイズdpx.Width / 設計画面サイズdpx.Height,  // アスペクト比
34                                         -dz,  // 前方投影面までの距離
35                                         dz ); // 後方投影面までの距離
36                                 mat.Transpose();  // 転置
37                                 return mat;
38                         }
39                 }
40                 public SharpDX.MediaFoundation.DXGIDeviceManager DXGIDeviceManager => this.bs_DXGIDeviceManager;
41                 public SharpDX.DXGI.SwapChain SwapChain => this.bs_SwapChain;
42                 public SharpDX.Direct3D11.RenderTargetView D3DRenderTargetView => this.bs_D3DRenderTargetView;
43                 public SharpDX.Mathematics.Interop.RawViewportF[] D3DViewPort => this.bs_D3DViewPort;
44                 public SharpDX.Direct3D11.Texture2D D3DDepthStencil => this.bs_D3DDepthStencil;
45                 public SharpDX.Direct3D11.DepthStencilView D3DDepthStencilView => this.bs_D3DDepthStencilView;
46                 public SharpDX.Direct3D11.DepthStencilState D3DDepthStencilState => this.bs_D3DDepthStencilState;
47                 public SharpDX.Direct3D11.DeviceDebug D3DDeviceDebug => this.bs_D3DDeviceDebug;
48                 public SharpDX.Direct2D1.Factory2 D2DFactory2 => this.bs_D2DFactory2;
49                 public SharpDX.DirectWrite.Factory DWriteFactory => this.bs_DWriteFactory;
50                 public SharpDX.WIC.ImagingFactory2 WicImagingFactory2 => this.bs_WicImagingFactory2;
51                 public SharpDX.Direct2D1.Device1 D2DDevice1 => this.bs_D2DDevice1;
52                 public SharpDX.Direct2D1.DeviceContext1 D2DContext1 => this.bs_D2DContext1;
53                 public SharpDX.Direct2D1.Bitmap1 D2DRenderTargetBitmap => this.bs_D2DRenderTargetBitmap;
54
55                 public float 拡大率DPXtoPX横方法 => ( this.物理画面サイズpx.Width / this.設計画面サイズdpx.Width );
56                 public float 拡大率DPXtoPX縦方向 => ( this.物理画面サイズpx.Height / this.設計画面サイズdpx.Height );
57                 public float 拡大率PXtoDPX横方法 => ( 1f / this.拡大率DPXtoPX横方法 );
58                 public float 拡大率PXtoDPX縦方法 => ( 1f / this.拡大率DPXtoPX縦方向 );
59                 public SharpDX.Matrix3x2 拡大行列DPXtoPX => SharpDX.Matrix3x2.Scaling( this.拡大率DPXtoPX横方法, this.拡大率DPXtoPX縦方向 );
60                 public SharpDX.Matrix3x2 拡大行列PXtoDPX => SharpDX.Matrix3x2.Scaling( this.拡大率PXtoDPX横方法, this.拡大率PXtoDPX縦方法 );
61                 public SharpDX.Matrix3x2 行列を単位変換するDPXtoPX( SharpDX.Matrix3x2 行列dpx ) => 行列dpx * 拡大行列DPXtoPX;
62                 public SharpDX.Matrix3x2 行列を単位変換するPXtoDPX( SharpDX.Matrix3x2 行列px ) => 行列px * 拡大行列PXtoDPX;
63
64                 public void すべてのリソースを作成する( System.Drawing.Size バックバッファサイズ, IntPtr ウィンドウハンドル )
65                 {
66                         this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズ.Width, バックバッファサイズ.Height );
67                         this.ウィンドウハンドル = ウィンドウハンドル;
68
69                         this.すべてのリソースを作成する();
70                 }
71                 protected void すべてのリソースを作成する()
72                 {
73                         // これらが呼び出し前に設定されていること。
74                         Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
75                         Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
76
77                         #region " D2DFactory2 を作成する。"
78                         //-----------------
79                         {
80                                 var デバッグレベル = SharpDX.Direct2D1.DebugLevel.None;
81 #if DEBUG
82                                 // プロジェクトがデバッグビルドに含まれている場合は、Direct2D デバッグレイヤーを SDK レイヤーを介して有効にする。
83                                 デバッグレベル = SharpDX.Direct2D1.DebugLevel.Information;
84 #endif
85                                 this.bs_D2DFactory2 = new SharpDX.Direct2D1.Factory2(
86                                         SharpDX.Direct2D1.FactoryType.SingleThreaded,
87                                         デバッグレベル );
88                         }
89                         //-----------------
90                         #endregion
91                         #region " DWriteFactory を作成する。"
92                         //-----------------
93                         this.bs_DWriteFactory = new SharpDX.DirectWrite.Factory(
94                                 SharpDX.DirectWrite.FactoryType.Shared );
95                         //-----------------
96                         #endregion
97                         #region " WicImagingFactory2 を作成する。"
98                         //-----------------
99                         this.bs_WicImagingFactory2 = new SharpDX.WIC.ImagingFactory2();
100                         //-----------------
101                         #endregion
102
103                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
104
105                         #region " DXGIDeviceManager を作成する。"
106                         //-----------------
107                         this.bs_DXGIDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager();
108                         //-----------------
109                         #endregion
110                         #region " D3Dデバイス、スワップチェーンを作成する。"
111                         //----------------
112                         // スワップチェーン desc
113                         var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() {
114                                 BufferCount = 2,
115                                 ModeDescription = new SharpDX.DXGI.ModeDescription() {
116                                         Width = (int) this.物理画面サイズpx.Width,
117                                         Height = (int) this.物理画面サイズpx.Height,
118                                         RefreshRate = new SharpDX.DXGI.Rational( 60, 1 ),
119                                         Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,  // D2D をサポートするなら B8G8R8A8 で。
120                                         Scaling = SharpDX.DXGI.DisplayModeScaling.Stretched,
121                                         ScanlineOrdering = SharpDX.DXGI.DisplayModeScanlineOrder.Progressive,
122                                 },
123                                 IsWindowed = true,
124                                 OutputHandle = ウィンドウハンドル,
125                                 SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ),
126                                 SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
127                                 Usage = SharpDX.DXGI.Usage.RenderTargetOutput,
128                                 Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch,
129                         };
130                         // 機能レベル
131                         var featureLevels = new SharpDX.Direct3D.FeatureLevel[] {
132                                 SharpDX.Direct3D.FeatureLevel.Level_11_0,
133                                 SharpDX.Direct3D.FeatureLevel.Level_10_1,
134                                 SharpDX.Direct3D.FeatureLevel.Level_10_0,
135                         };
136                         var creationFlags = SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport; // D2Dをサポートするなら必須。
137 #if DEBUG
138                         // D3D11 Debugメッセージは、プロジェクトプロパティで「ネイティブコードのデバッグを有効にする」を ON にしないと表示されないので注意。
139                         creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.Debug;
140 #endif
141                         // デバイスとスワップチェーンを作成する。
142                         SharpDX.Direct3D11.Device.CreateWithSwapChain(
143                                 SharpDX.Direct3D.DriverType.Hardware,
144                                 creationFlags,
145                                 featureLevels,
146                                 swapChainDesc,
147                                 out d3dDevice,
148                                 out this.bs_SwapChain );
149
150                         FDK.Log.Info( "D3Dデバイスとスワップチェーンを生成しました。" );
151                         FDK.Log.Info( $"機能レベル: {d3dDevice.FeatureLevel.ToString()}" );
152                         //----------------
153                         #endregion
154
155                         using( d3dDevice )
156                         {
157                                 // D3D 関連
158
159                                 #region " デバイスからデバッグオブジェクトを取得する。"
160                                 //----------------
161                                 this.bs_D3DDeviceDebug = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.DeviceDebug>();
162                                 //----------------
163                                 #endregion
164                                 #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) "
165                                 //-----------------
166                                 using( var videoDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.VideoDevice>() )
167                                 {
168                                         if( null == videoDevice )
169                                                 throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" );
170                                 }
171                                 //-----------------
172                                 #endregion
173                                 #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。"
174                                 //-----------------
175                                 using( var multithread = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D.DeviceMultithread>() )
176                                 {
177                                         if( null == multithread )
178                                                 throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" );
179
180                                         multithread.SetMultithreadProtected( true );
181                                 }
182                                 //-----------------
183                                 #endregion
184                                 #region " DXGIデバイスマネージャに D3Dデバイスを登録する。"
185                                 //-----------------
186                                 this.DXGIDeviceManager.ResetDevice( d3dDevice );
187                                 //-----------------
188                                 #endregion
189                                 #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
190                                 //----------------
191                                 using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
192                                 {
193                                         factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
194                                 }
195                                 //----------------
196                                 #endregion
197                         }
198
199                         this.サイズに依存するリソースを作成する();
200                 }
201                 public void すべてのリソースを解放する()
202                 {
203                         // D3D 関連
204                         this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null );    // スワップチェインをウインドウモードにする。
205                         this.サイズに依存するリソースを解放する();
206
207                         FDK.Utilities.解放する( ref this.bs_SwapChain );
208                         FDK.Utilities.解放する( ref this.bs_DXGIDeviceManager );
209
210                         // その他
211                         FDK.Utilities.解放する( ref this.bs_WicImagingFactory2 );
212                         FDK.Utilities.解放する( ref this.bs_DWriteFactory );
213                         FDK.Utilities.解放する( ref this.bs_D2DFactory2 );
214
215                         this.bs_D3DDeviceDebug?.ReportLiveDeviceObjects( SharpDX.Direct3D11.ReportingLevel.Detail );
216                         FDK.Utilities.解放する( ref this.bs_D3DDeviceDebug );
217                 }
218                 public void Dispose() => this.すべてのリソースを解放する();
219                 public void サイズに依存するリソースを作成する()
220                 {
221                         #region " スワップチェーンのサイズを変更する。"
222                         //----------------
223                         Debug.Assert( null != this.SwapChain ); // スワップチェーンは(デバイスとともに)すでに生成されていること。
224                         this.SwapChain.ResizeBuffers(
225                                 bufferCount: 2,
226                                 width: (int) this.物理画面サイズpx.Width,
227                                 height: (int) this.物理画面サイズpx.Height,
228                                 newFormat: SharpDX.DXGI.Format.B8G8R8A8_UNorm,
229                                 swapChainFlags: SharpDX.DXGI.SwapChainFlags.AllowModeSwitch );
230                         //----------------
231                         #endregion
232
233                         using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain, 0 ) )
234                         {
235                                 var d3dDevice = (SharpDX.Direct3D11.Device) null;
236                                 using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
237                                 using( d3dDevice )
238                                 {
239                                         // D3D 関連
240                                         #region " RenderTargetView の作成 "
241                                         //----------------
242                                         this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( d3dDevice, backBuffer );
243                                         //----------------
244                                         #endregion
245                                         #region " 深度ステンシルテクスチャの作成 "
246                                         //----------------
247                                         var descDepth = backBuffer.Description;
248                                         //descDepth.Width = backBuffer.Description.Width;       → backBuffer に同じ
249                                         //descDepth.Height = backBuffer.Description.Height;     → 同上
250                                         descDepth.MipLevels = 1;    // ミップマップレベル数
251                                         descDepth.ArraySize = 1;    // 配列サイズ
252                                         descDepth.Format = SharpDX.DXGI.Format.D32_Float;   // フォーマット(深度のみ)
253                                         descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
254                                         descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil;    // 深度ステンシル
255                                         descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;  // CPUからはアクセスしない
256                                         descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;    // その他の設定なし
257                                         this.bs_D3DDepthStencil = new SharpDX.Direct3D11.Texture2D( d3dDevice, descDepth );
258                                         //----------------
259                                         #endregion
260                                         #region " 深度ステンシルビューの作成 "
261                                         //----------------
262                                         var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
263                                                 Format = descDepth.Format,
264                                                 Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
265                                                 Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
266                                                 Texture2D = new SharpDX.Direct3D11.DepthStencilViewDescription.Texture2DResource() {
267                                                         MipSlice = 0,
268                                                 },
269                                         };
270                                         this.bs_D3DDepthStencilView = new SharpDX.Direct3D11.DepthStencilView( d3dDevice, this.bs_D3DDepthStencil, descDSV );
271                                         //----------------
272                                         #endregion
273                                         #region " 深度ステンシルステートを作成する。"
274                                         //----------------
275                                         var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
276                                                 IsDepthEnabled = true,  // 深度テストあり
277                                                 DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,     // 書き込む
278                                                 DepthComparison = SharpDX.Direct3D11.Comparison.Less,   // 手前の物体を描画
279                                                 IsStencilEnabled = false,   // ステンシルテストなし。
280                                                 StencilReadMask = 0,    // ステンシル読み込みマスク。
281                                                 StencilWriteMask = 0,   // ステンシル書き込みマスク。
282
283                                                 // 面が表を向いている場合のステンシル・テストの設定
284                                                 FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
285                                                         FailOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
286                                                         DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep,  // 維持
287                                                         PassOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
288                                                         Comparison = SharpDX.Direct3D11.Comparison.Never,   // 常に失敗
289                                                 },
290
291                                                 // 面が裏を向いている場合のステンシル・テストの設定
292                                                 BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
293                                                         FailOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
294                                                         DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep,  // 維持
295                                                         PassOperation = SharpDX.Direct3D11.StencilOperation.Keep,   // 維持
296                                                         Comparison = SharpDX.Direct3D11.Comparison.Always,  // 常に成功
297                                                 },
298                                         };
299                                         this.bs_D3DDepthStencilState = new SharpDX.Direct3D11.DepthStencilState( d3dDevice, DepthSencil );
300                                         //----------------
301                                         #endregion
302                                         #region " ビューポートの設定 "
303                                         //----------------
304                                         this.bs_D3DViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
305                                                 X = 0.0f,
306                                                 Y = 0.0f,
307                                                 Width = (float) backBuffer.Description.Width,
308                                                 Height = (float) backBuffer.Description.Height,
309                                                 MinDepth = 0.0f,
310                                                 MaxDepth = 1.0f,
311                                         };
312                                         //----------------
313                                         #endregion
314                                         #region " テクスチャの共有リソースの作成 "
315                                         //----------------
316                                         FDK.メディア.テクスチャ.共有リソースを作成する( this );
317                                         //----------------
318                                         #endregion
319
320                                         // D2D 関連
321                                         using( var backsurface = SharpDX.DXGI.Surface.FromSwapChain( this.bs_SwapChain, 0 ) )
322                                         {
323                                                 #region " D2DDevice を作成する。"
324                                                 //-----------------
325                                                 using( var dxgiDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.DXGI.Device>() )
326                                                 {
327                                                         if( null == dxgiDevice )
328                                                                 throw new FDKException( "Direct3D11デバイスが、IDXGIDevice3 をサポートしていません。" );
329
330                                                         this.bs_D2DDevice1 = new SharpDX.Direct2D1.Device1( this.D2DFactory2, dxgiDevice );
331                                                 }
332                                                 //-----------------
333                                                 #endregion
334                                                 #region " D2Dの既定のコンテキスト D2DContext1 を作成する。"
335                                                 //-----------------
336                                                 this.bs_D2DContext1 = new SharpDX.Direct2D1.DeviceContext1( this.D2DDevice1, SharpDX.Direct2D1.DeviceContextOptions.None );
337
338                                                 // 現在のディスプレイDPI を取得し、D2DContext に設定する。
339                                                 this.D2DContext1.DotsPerInch = this.D2DFactory2.DesktopDpi;
340                                                 //-----------------
341                                                 #endregion
342                                                 #region " D2Dの既定のレンダーターゲットビットマップを作成する。"
343                                                 //-----------------
344                                                 var dpi = this.D2DContext1.DotsPerInch;
345
346                                                 // DXGIスワップチェーンのバックバッファとデータを共有するD2Dターゲットビットマップを作成する。ビューではなく共有リソース。
347                                                 this.bs_D2DRenderTargetBitmap = new SharpDX.Direct2D1.Bitmap1(
348                                                         this.D2DContext1,   // このコンテキストを通じて、
349                                                         backsurface, // バックバッファとデータを共有する。
350                                                         new SharpDX.Direct2D1.BitmapProperties1(
351                                                                 new SharpDX.Direct2D1.PixelFormat( backsurface.Description.Format, SharpDX.Direct2D1.AlphaMode.Premultiplied ),
352                                                                 dpi.Width,
353                                                                 dpi.Height,
354                                                                 SharpDX.Direct2D1.BitmapOptions.Target | SharpDX.Direct2D1.BitmapOptions.CannotDraw ) );
355
356                                                 // ここで設定する。
357                                                 this.D2DContext1.Target = this.bs_D2DRenderTargetBitmap;
358                                                 //-----------------
359                                                 #endregion
360                                                 #region " テキストのアンチエイリアシングを設定する。Grayscale が、すべての Windows ストアアプリで推奨される。"
361                                                 //-----------------
362                                                 this.D2DContext1.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale;
363                                                 //-----------------
364                                                 #endregion
365                                         }
366                                 }
367                         }
368                 }
369                 public void サイズに依存するリソースを解放する()
370                 {
371                         // D2D 関連
372                         if( null != this.bs_D2DContext1 )
373                                 this.bs_D2DContext1.Target = null;
374                         FDK.Utilities.解放する( ref this.bs_D2DRenderTargetBitmap );
375                         FDK.Utilities.解放する( ref this.bs_D2DContext1 );
376                         FDK.Utilities.解放する( ref this.bs_D2DDevice1 );
377
378                         // D3D 関連
379                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
380                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
381                         using( d3dDevice )
382                         using( var d3dContext = d3dDevice.ImmediateContext )
383                         {
384                                 d3dContext.ClearState();
385                                 d3dContext.OutputMerger.ResetTargets();
386
387                                 FDK.メディア.テクスチャ.共有リソースを解放する();
388
389                                 FDK.Utilities.解放する( ref this.bs_D3DDepthStencilState );
390                                 FDK.Utilities.解放する( ref this.bs_D3DDepthStencilView );
391                                 FDK.Utilities.解放する( ref this.bs_D3DDepthStencil );
392                                 FDK.Utilities.解放する( ref this.bs_D3DRenderTargetView );
393                                 //FDK.Utilities.解放する( ref this.bs_SwapChain ); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
394
395                                 // (0,0)は、サイズ依存リソース無効の印。
396                                 this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
397                         }
398                 }
399                 public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ )
400                 {
401                         異常状態なのでアプリを終了せよ = false;
402                         SharpDX.Result 削除理由;
403
404                         var d3dDevice = (SharpDX.Direct3D11.Device) null;
405                         using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
406                         using( d3dDevice )
407                         {
408                                 削除理由 = d3dDevice.DeviceRemovedReason;
409                         }
410                         if( 削除理由.Success )
411                                 return;
412
413                         var エラー詳細 = new[] {
414                                         new { Code = SharpDX.DXGI.ResultCode.DeviceHung.Code, Info = SharpDX.DXGI.ResultCode.DeviceHung.ApiCode, Rebuild = true },
415                                         new { Code = SharpDX.DXGI.ResultCode.DeviceReset.Code, Info = SharpDX.DXGI.ResultCode.DeviceReset.ApiCode, Rebuild = true },
416                                         new { Code = SharpDX.DXGI.ResultCode.DeviceRemoved.Code, Info = SharpDX.DXGI.ResultCode.DeviceRemoved.ApiCode, Rebuild = false },
417                                         new { Code = SharpDX.DXGI.ResultCode.DriverInternalError.Code, Info = SharpDX.DXGI.ResultCode.DriverInternalError.ApiCode, Rebuild = false },
418                                         new { Code = SharpDX.DXGI.ResultCode.InvalidCall.Code, Info = SharpDX.DXGI.ResultCode.InvalidCall.ApiCode, Rebuild = false },
419                                 }.First( ( エラー ) => エラー.Code == 削除理由.Code );  // 見つからないなら System.InvalidOperationException 。
420
421                         Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
422
423                         if( エラー詳細.Rebuild )
424                         {
425                                 this.すべてのリソースを解放する();
426                                 this.すべてのリソースを作成する();
427                         }
428                         else
429                         {
430                                 異常状態なのでアプリを終了せよ = true;
431                         }
432                 }
433
434                 private float dz( float 高さdpx, float 視野角deg )
435                 {
436                         return (float) ( 高さdpx / ( 4.0 * Math.Tan( SharpDX.MathUtil.DegreesToRadians( 視野角deg / 2.0f ) ) ) );
437                 }
438
439                 #region " バックストア。"
440                 //----------------
441                 private SharpDX.Direct2D1.Factory2 bs_D2DFactory2 = null;
442                 private SharpDX.DirectWrite.Factory bs_DWriteFactory = null;
443                 private SharpDX.WIC.ImagingFactory2 bs_WicImagingFactory2 = null;
444                 private SharpDX.MediaFoundation.DXGIDeviceManager bs_DXGIDeviceManager = null;
445                 private SharpDX.DXGI.SwapChain bs_SwapChain = null;
446                 private SharpDX.Mathematics.Interop.RawViewportF[] bs_D3DViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
447                 private SharpDX.Direct3D11.DepthStencilState bs_D3DDepthStencilState = null;
448                 private SharpDX.Direct3D11.RenderTargetView bs_D3DRenderTargetView = null;
449                 private SharpDX.Direct3D11.Texture2D bs_D3DDepthStencil = null;
450                 private SharpDX.Direct3D11.DepthStencilView bs_D3DDepthStencilView = null;
451                 private SharpDX.Direct3D11.DeviceDebug bs_D3DDeviceDebug = null;
452                 private SharpDX.Direct2D1.Device1 bs_D2DDevice1 = null;
453                 private SharpDX.Direct2D1.DeviceContext1 bs_D2DContext1 = null;
454                 private SharpDX.Direct2D1.Bitmap1 bs_D2DRenderTargetBitmap = null;
455                 //----------------
456                 #endregion
457         }
458 }