2 using System.Collections.Generic;
3 using System.Diagnostics;
10 public SharpDX.Size2F 設計画面サイズdpx = new SharpDX.Size2F( 640f, 480f );
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 ビュー変換行列
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(); // 転置
26 public SharpDX.Matrix 射影変換行列
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, // アスペクト比
36 mat.Transpose(); // 転置
40 public SharpDX.Direct3D11.Device D3DDevice => this.bs_D3DDevice;
41 public SharpDX.DXGI.SwapChain SwapChain => this.bs_SwapChain;
42 public SharpDX.Direct3D11.RenderTargetView RenderTargetView => this.bs_RenderTargetView;
43 public SharpDX.Mathematics.Interop.RawViewportF[] ViewPort => this.bs_ViewPort;
44 public SharpDX.Direct3D11.Texture2D DepthStencil => this.bs_DepthStencil;
45 public SharpDX.Direct3D11.DepthStencilView DepthStencilView => this.bs_DepthStencilView;
46 public SharpDX.Direct3D11.DepthStencilState DepthStencilState => this.bs_DepthStencilState;
48 public void すべてのリソースを作成する( System.Drawing.Size バックバッファサイズ, IntPtr ウィンドウハンドル )
50 this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズ.Width, バックバッファサイズ.Height );
51 this.ウィンドウハンドル = ウィンドウハンドル;
55 protected void すべてのリソースを作成する()
57 // これらが呼び出し前に設定されていること。
58 Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
59 Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
61 #region " デバイス、スワップチェーンを作成する。"
64 var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() {
66 ModeDescription = new SharpDX.DXGI.ModeDescription(
67 (int) this.物理画面サイズpx.Width,
68 (int) this.物理画面サイズpx.Height,
69 new SharpDX.DXGI.Rational( 60, 1 ),
70 SharpDX.DXGI.Format.B8G8R8A8_UNorm
73 OutputHandle = ウィンドウハンドル,
74 SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ),
75 SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
76 Usage = SharpDX.DXGI.Usage.RenderTargetOutput,
79 var featureLevels = new SharpDX.Direct3D.FeatureLevel[] {
80 SharpDX.Direct3D.FeatureLevel.Level_11_0,
81 SharpDX.Direct3D.FeatureLevel.Level_10_1,
82 SharpDX.Direct3D.FeatureLevel.Level_10_0,
84 // デバイスとスワップチェーンを作成する。
85 SharpDX.Direct3D11.Device.CreateWithSwapChain(
86 SharpDX.Direct3D.DriverType.Hardware,
87 SharpDX.Direct3D11.DeviceCreationFlags.None,
90 out this.bs_D3DDevice,
91 out this.bs_SwapChain );
93 Trace.WriteLine( "D3Dデバイスとスワップチェーンを生成しました。" );
94 Trace.WriteLine( $"機能レベル: {this.bs_D3DDevice.FeatureLevel.ToString()}" );
97 #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
99 using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
101 factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
105 #region " 深度ステンシルステート "
107 var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
108 IsDepthEnabled = true, // 深度テストあり
109 DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All, // 書き込む
110 DepthComparison = SharpDX.Direct3D11.Comparison.Less, // 手前の物体を描画
111 IsStencilEnabled = false, // ステンシルテストなし。
112 StencilReadMask = 0, // ステンシル読み込みマスク。
113 StencilWriteMask = 0, // ステンシル書き込みマスク。
115 // 面が表を向いている場合のステンシル・テストの設定
116 FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
117 FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
118 DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
119 PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
120 Comparison = SharpDX.Direct3D11.Comparison.Never, // 常に失敗
123 // 面が裏を向いている場合のステンシル・テストの設定
124 BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
125 FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
126 DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
127 PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
128 Comparison = SharpDX.Direct3D11.Comparison.Always, // 常に成功
131 this.bs_DepthStencilState = new SharpDX.Direct3D11.DepthStencilState( this.bs_D3DDevice, DepthSencil );
135 this.サイズに依存するリソースを作成する();
137 public void すべてのリソースを解放する()
140 this.bs_D3DDevice?.ImmediateContext?.ClearState();
142 // スワップチェインをウインドウモードにする。
143 this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null );
145 this.サイズに依存するリソースを解放する();
148 this.bs_DepthStencilState?.Dispose();
149 this.bs_SwapChain?.Dispose();
150 this.bs_D3DDevice?.Dispose();
152 public void サイズに依存するリソースを作成する()
154 #region " スワップチェーンのサイズを変更する。"
156 Debug.Assert( null != this.SwapChain ); // スワップチェーンは、デバイスとともに、すでに生成される。
157 this.SwapChain.ResizeBuffers(
159 width: (int) this.物理画面サイズpx.Width,
160 height: (int) this.物理画面サイズpx.Height,
161 newFormat: SharpDX.DXGI.Format.R8G8B8A8_UNorm,
162 swapChainFlags: SharpDX.DXGI.SwapChainFlags.AllowModeSwitch );
166 // 新しいサイズになったバックバッファを取得して、リソースを作成する。
167 using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain, 0 ) )
169 #region " RenderTargetView の作成 "
171 this.bs_RenderTargetView = new SharpDX.Direct3D11.RenderTargetView( this.bs_D3DDevice, backBuffer );
174 #region " 深度ステンシルテクスチャの作成 "
176 var descDepth = backBuffer.Description;
177 //descDepth.Width = backBuffer.Description.Width; → backBuffer に同じ
178 //descDepth.Height = backBuffer.Description.Height; → 同上
179 descDepth.MipLevels = 1; // ミップマップレベル数
180 descDepth.ArraySize = 1; // 配列サイズ
181 descDepth.Format = SharpDX.DXGI.Format.D32_Float; // フォーマット(深度のみ)
182 descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
183 descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil; // 深度ステンシル
184 descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; // CPUからはアクセスしない
185 descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; // その他の設定なし
187 this.bs_DepthStencil = new SharpDX.Direct3D11.Texture2D( this.bs_D3DDevice, descDepth );
190 #region " 深度ステンシルビューの作成 "
192 var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
193 Format = descDepth.Format,
194 Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
195 Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
197 descDSV.Texture2D.MipSlice = 0;
198 this.bs_DepthStencilView = new SharpDX.Direct3D11.DepthStencilView(
200 this.bs_DepthStencil,
204 #region " ビューポートの設定 "
206 this.bs_ViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
209 Width = (float) backBuffer.Description.Width,
210 Height = (float) backBuffer.Description.Height,
216 #region " テクスチャの共有リソースの作成 "
218 FDK.メディア.テクスチャ.共有リソースを作成する( this );
223 public void サイズに依存するリソースを解放する()
226 this.D3DDevice.ImmediateContext.OutputMerger.ResetTargets();
228 FDK.メディア.テクスチャ.共有リソースを解放する();
229 this.bs_DepthStencilView?.Dispose();
230 this.bs_DepthStencil?.Dispose();
231 this.bs_RenderTargetView?.Dispose();
232 //this.bs_SwapChain?.Dispose(); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
234 // (0,0)は、サイズ依存リソース無効の印。
235 this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
237 public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ )
239 異常状態なのでアプリを終了せよ = false;
241 var 削除理由 = this.bs_D3DDevice.DeviceRemovedReason;
246 new { Code = SharpDX.DXGI.ResultCode.DeviceHung.Code, Info = SharpDX.DXGI.ResultCode.DeviceHung.ApiCode, Rebuild = true },
247 new { Code = SharpDX.DXGI.ResultCode.DeviceReset.Code, Info = SharpDX.DXGI.ResultCode.DeviceReset.ApiCode, Rebuild = true },
248 new { Code = SharpDX.DXGI.ResultCode.DeviceRemoved.Code, Info = SharpDX.DXGI.ResultCode.DeviceRemoved.ApiCode, Rebuild = false },
249 new { Code = SharpDX.DXGI.ResultCode.DriverInternalError.Code, Info = SharpDX.DXGI.ResultCode.DriverInternalError.ApiCode, Rebuild = false },
250 new { Code = SharpDX.DXGI.ResultCode.InvalidCall.Code, Info = SharpDX.DXGI.ResultCode.InvalidCall.ApiCode, Rebuild = false },
251 }.First( ( エラー ) => エラー.Code == 削除理由.Code ); // 見つからないなら System.InvalidOperationException 。
253 Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
257 this.すべてのリソースを解放する();
258 this.すべてのリソースを作成する();
262 異常状態なのでアプリを終了せよ = true;
266 private float dz( float 高さdpx, float 視野角deg )
268 return (float) ( 高さdpx / ( 4.0 * Math.Tan( SharpDX.MathUtil.DegreesToRadians( 視野角deg / 2.0f ) ) ) );
273 private SharpDX.Direct3D11.Device bs_D3DDevice = null;
274 private SharpDX.DXGI.SwapChain bs_SwapChain = null;
275 private SharpDX.Mathematics.Interop.RawViewportF[] bs_ViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
276 private SharpDX.Direct3D11.DepthStencilState bs_DepthStencilState = null;
277 private SharpDX.Direct3D11.RenderTargetView bs_RenderTargetView = null;
278 private SharpDX.Direct3D11.Texture2D bs_DepthStencil = null;
279 private SharpDX.Direct3D11.DepthStencilView bs_DepthStencilView = null;