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;
47 public SharpDX.Direct3D11.ShaderResourceView ShaderResourceView => this.bs_ShaderResourceView;
48 public SharpDX.Direct3D11.SamplerState SamplerState => this.bs_SamplerState;
49 protected SharpDX.Size2F ShaderResourceViewSize;
51 public void すべてのリソースを作成する( System.Drawing.Size バックバッファサイズ, IntPtr ウィンドウハンドル )
53 this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズ.Width, バックバッファサイズ.Height );
54 this.ウィンドウハンドル = ウィンドウハンドル;
58 protected void すべてのリソースを作成する()
60 // これらが呼び出し前に設定されていること。
61 Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
62 Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
64 #region " デバイス、スワップチェーンを作成する。"
67 var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() {
69 ModeDescription = new SharpDX.DXGI.ModeDescription(
70 (int) this.物理画面サイズpx.Width,
71 (int) this.物理画面サイズpx.Height,
72 new SharpDX.DXGI.Rational( 60, 1 ),
73 SharpDX.DXGI.Format.B8G8R8A8_UNorm
76 OutputHandle = ウィンドウハンドル,
77 SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ),
78 SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
79 Usage = SharpDX.DXGI.Usage.RenderTargetOutput,
82 var featureLevels = new SharpDX.Direct3D.FeatureLevel[] {
83 SharpDX.Direct3D.FeatureLevel.Level_11_0,
84 SharpDX.Direct3D.FeatureLevel.Level_10_1,
85 SharpDX.Direct3D.FeatureLevel.Level_10_0,
87 // デバイスとスワップチェーンを作成する。
88 SharpDX.Direct3D11.Device.CreateWithSwapChain(
89 SharpDX.Direct3D.DriverType.Hardware,
90 SharpDX.Direct3D11.DeviceCreationFlags.None,
93 out this.bs_D3DDevice,
94 out this.bs_SwapChain );
96 Trace.WriteLine( "D3Dデバイスとスワップチェーンを生成しました。" );
97 Trace.WriteLine( $"機能レベル: {this.bs_D3DDevice.FeatureLevel.ToString()}" );
100 #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
102 using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
104 factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
108 #region " 深度ステンシルステート "
110 var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
111 IsDepthEnabled = true, // 深度テストあり
112 DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All, // 書き込む
113 DepthComparison = SharpDX.Direct3D11.Comparison.Less, // 手前の物体を描画
114 IsStencilEnabled = false, // ステンシルテストなし。
115 StencilReadMask = 0, // ステンシル読み込みマスク。
116 StencilWriteMask = 0, // ステンシル書き込みマスク。
118 // 面が表を向いている場合のステンシル・テストの設定
119 FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
120 FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
121 DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
122 PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
123 Comparison = SharpDX.Direct3D11.Comparison.Never, // 常に失敗
126 // 面が裏を向いている場合のステンシル・テストの設定
127 BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
128 FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
129 DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
130 PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
131 Comparison = SharpDX.Direct3D11.Comparison.Always, // 常に成功
134 this.bs_DepthStencilState = new SharpDX.Direct3D11.DepthStencilState( this.bs_D3DDevice, DepthSencil );
137 #region " シェーダーリソースビュー "
139 this.bs_ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
140 this.D3DDevice, "テスト用テクスチャ画像.jpg", out this.ShaderResourceViewSize );
141 //D3DX11CreateShaderResourceViewFromFile( g_pD3DDevice, L"texture.png", NULL, NULL, &g_pTextureSRV, &hr );
146 var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
147 Filter = SharpDX.Direct3D11.Filter.Anisotropic,
148 AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
149 AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
150 AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
152 MaximumAnisotropy = 2,
153 ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
154 BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
155 MinimumLod = float.MinValue,
156 MaximumLod = float.MaxValue,
158 this.bs_SamplerState = new SharpDX.Direct3D11.SamplerState( this.bs_D3DDevice, descSampler );
162 this.サイズに依存するリソースを作成する();
164 public void すべてのリソースを解放する()
167 this.bs_D3DDevice?.ImmediateContext?.ClearState();
169 // スワップチェインをウインドウモードにする。
170 this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null );
172 this.サイズに依存するリソースを解放する();
175 this.bs_DepthStencilState?.Dispose();
176 this.bs_SamplerState?.Dispose();
177 this.bs_ShaderResourceView?.Dispose();
178 this.bs_SwapChain?.Dispose();
179 this.bs_D3DDevice?.Dispose();
181 public void サイズに依存するリソースを作成する()
183 #region " スワップチェーンのサイズを変更する。"
185 Debug.Assert( null != this.SwapChain ); // スワップチェーンは、デバイスとともに、すでに生成される。
186 this.SwapChain.ResizeBuffers(
188 width: (int) this.物理画面サイズpx.Width,
189 height: (int) this.物理画面サイズpx.Height,
190 newFormat: SharpDX.DXGI.Format.R8G8B8A8_UNorm,
191 swapChainFlags: SharpDX.DXGI.SwapChainFlags.AllowModeSwitch );
195 // 新しいサイズになったバックバッファを取得して、リソースを作成する。
196 using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain, 0 ) )
198 #region " RenderTargetView の作成 "
200 this.bs_RenderTargetView = new SharpDX.Direct3D11.RenderTargetView( this.bs_D3DDevice, backBuffer );
203 #region " 深度ステンシルテクスチャの作成 "
205 var descDepth = backBuffer.Description;
206 //descDepth.Width = backBuffer.Description.Width; → backBuffer に同じ
207 //descDepth.Height = backBuffer.Description.Height; → 同上
208 descDepth.MipLevels = 1; // ミップマップレベル数
209 descDepth.ArraySize = 1; // 配列サイズ
210 descDepth.Format = SharpDX.DXGI.Format.D32_Float; // フォーマット(深度のみ)
211 descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
212 descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil; // 深度ステンシル
213 descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; // CPUからはアクセスしない
214 descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; // その他の設定なし
216 this.bs_DepthStencil = new SharpDX.Direct3D11.Texture2D( this.bs_D3DDevice, descDepth );
219 #region " 深度ステンシルビューの作成 "
221 var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
222 Format = descDepth.Format,
223 Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
224 Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
226 descDSV.Texture2D.MipSlice = 0;
227 this.bs_DepthStencilView = new SharpDX.Direct3D11.DepthStencilView(
229 this.bs_DepthStencil,
233 #region " ビューポートの設定 "
235 this.bs_ViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
238 Width = (float) backBuffer.Description.Width,
239 Height = (float) backBuffer.Description.Height,
245 #region " テクスチャの共有リソースの作成 "
247 FDK.メディア.テクスチャ.共有リソースを作成する( this );
252 public void サイズに依存するリソースを解放する()
255 this.D3DDevice.ImmediateContext.OutputMerger.ResetTargets();
257 FDK.メディア.テクスチャ.共有リソースを解放する();
258 this.bs_DepthStencilView?.Dispose();
259 this.bs_DepthStencil?.Dispose();
260 this.bs_RenderTargetView?.Dispose();
261 //this.bs_SwapChain?.Dispose(); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
263 // (0,0)は、サイズ依存リソース無効の印。
264 this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
266 public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ )
268 異常状態なのでアプリを終了せよ = false;
270 var 削除理由 = this.bs_D3DDevice.DeviceRemovedReason;
275 new { Code = SharpDX.DXGI.ResultCode.DeviceHung.Code, Info = SharpDX.DXGI.ResultCode.DeviceHung.ApiCode, Rebuild = true },
276 new { Code = SharpDX.DXGI.ResultCode.DeviceReset.Code, Info = SharpDX.DXGI.ResultCode.DeviceReset.ApiCode, Rebuild = true },
277 new { Code = SharpDX.DXGI.ResultCode.DeviceRemoved.Code, Info = SharpDX.DXGI.ResultCode.DeviceRemoved.ApiCode, Rebuild = false },
278 new { Code = SharpDX.DXGI.ResultCode.DriverInternalError.Code, Info = SharpDX.DXGI.ResultCode.DriverInternalError.ApiCode, Rebuild = false },
279 new { Code = SharpDX.DXGI.ResultCode.InvalidCall.Code, Info = SharpDX.DXGI.ResultCode.InvalidCall.ApiCode, Rebuild = false },
280 }.First( ( エラー ) => エラー.Code == 削除理由.Code ); // 見つからないなら System.InvalidOperationException 。
282 Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
286 this.すべてのリソースを解放する();
287 this.すべてのリソースを作成する();
291 異常状態なのでアプリを終了せよ = true;
295 private float dz( float 高さdpx, float 視野角deg )
297 return (float) ( 高さdpx / ( 4.0 * Math.Tan( SharpDX.MathUtil.DegreesToRadians( 視野角deg / 2.0f ) ) ) );
302 private SharpDX.Direct3D11.Device bs_D3DDevice = null;
303 private SharpDX.DXGI.SwapChain bs_SwapChain = null;
304 private SharpDX.Mathematics.Interop.RawViewportF[] bs_ViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
305 private SharpDX.Direct3D11.DepthStencilState bs_DepthStencilState = null;
306 private SharpDX.Direct3D11.ShaderResourceView bs_ShaderResourceView = null;
307 private SharpDX.Direct3D11.SamplerState bs_SamplerState = null;
308 private SharpDX.Direct3D11.RenderTargetView bs_RenderTargetView = null;
309 private SharpDX.Direct3D11.Texture2D bs_DepthStencil = null;
310 private SharpDX.Direct3D11.DepthStencilView bs_DepthStencilView = null;