namespace FDK.メディア
{
- public class デバイスリソース
+ public class デバイスリソース : IDisposable
{
public SharpDX.Size2F 設計画面サイズdpx = new SharpDX.Size2F( 1920f, 1080f ); // 設計サイズ。
public SharpDX.Size2F 物理画面サイズpx = new SharpDX.Size2F( 0, 0 ); // (0, 0) は、サイズ依存リソース無効の印。
return mat;
}
}
- public SharpDX.MediaFoundation.DXGIDeviceManager DXGIDeviceManager => this.bs_DXGIDeviceManager;
- public SharpDX.DXGI.SwapChain SwapChain => this.bs_SwapChain;
- public SharpDX.Direct3D11.RenderTargetView D3DRenderTargetView => this.bs_D3DRenderTargetView;
- public SharpDX.Mathematics.Interop.RawViewportF[] D3DViewPort => this.bs_D3DViewPort;
- public SharpDX.Direct3D11.Texture2D D3DDepthStencil => this.bs_D3DDepthStencil;
- public SharpDX.Direct3D11.DepthStencilView D3DDepthStencilView => this.bs_D3DDepthStencilView;
- public SharpDX.Direct3D11.DepthStencilState D3DDepthStencilState => this.bs_D3DDepthStencilState;
- public SharpDX.Direct2D1.Factory2 D2DFactory2 => this.bs_D2DFactory2;
- public SharpDX.DirectWrite.Factory DWriteFactory => this.bs_DWriteFactory;
- public SharpDX.WIC.ImagingFactory2 WicImagingFactory2 => this.bs_WicImagingFactory2;
- public SharpDX.Direct2D1.Device1 D2DDevice1 => this.bs_D2DDevice1;
- public SharpDX.Direct2D1.DeviceContext1 D2DContext1 => this.bs_D2DContext1;
- public SharpDX.Direct2D1.Bitmap1 D2DRenderTargetBitmap => this.bs_D2DRenderTargetBitmap;
-
- public float 拡大率DPXtoPX横方法 => ( this.物理画面サイズpx.Width / this.設計画面サイズdpx.Width );
+ public SharpDX.MediaFoundation.DXGIDeviceManager DXGIDeviceManager => ( this.bs_DXGIDeviceManager );
+ public SharpDX.DXGI.SwapChain1 SwapChain1 => ( this.bs_SwapChain1 );
+ public SharpDX.Direct3D11.RenderTargetView D3DRenderTargetView => ( this.bs_D3DRenderTargetView );
+ public SharpDX.Mathematics.Interop.RawViewportF[] D3DViewPort => ( this.bs_D3DViewPort );
+ public SharpDX.Direct3D11.Texture2D D3DDepthStencil => ( this.bs_D3DDepthStencil );
+ public SharpDX.Direct3D11.DepthStencilView D3DDepthStencilView => ( this.bs_D3DDepthStencilView );
+ public SharpDX.Direct3D11.DepthStencilState D3DDepthStencilState => ( this.bs_D3DDepthStencilState );
+ public SharpDX.Direct3D11.DeviceDebug D3DDeviceDebug => ( this.bs_D3DDeviceDebug );
+ public SharpDX.Direct2D1.Factory2 D2DFactory2 => ( this.bs_D2DFactory2 );
+ public SharpDX.DirectWrite.Factory DWriteFactory => ( this.bs_DWriteFactory );
+ public SharpDX.WIC.ImagingFactory2 WicImagingFactory2 => ( this.bs_WicImagingFactory2 );
+ public SharpDX.Direct2D1.Device1 D2DDevice1 => ( this.bs_D2DDevice1 );
+ public SharpDX.Direct2D1.DeviceContext1 D2DContext1 => ( this.bs_D2DContext1 );
+ public SharpDX.Direct2D1.Bitmap1 D2DRenderTargetBitmap => ( this.bs_D2DRenderTargetBitmap );
+
+ public float 拡大率DPXtoPX横方向 => ( this.物理画面サイズpx.Width / this.設計画面サイズdpx.Width );
public float 拡大率DPXtoPX縦方向 => ( this.物理画面サイズpx.Height / this.設計画面サイズdpx.Height );
- public float 拡大率PXtoDPX横方法 => ( 1f / this.拡大率DPXtoPX横方法 );
- public float 拡大率PXtoDPX縦方法 => ( 1f / this.拡大率DPXtoPX縦方向 );
- public SharpDX.Matrix3x2 拡大行列DPXtoPX => SharpDX.Matrix3x2.Scaling( this.拡大率DPXtoPX横方法, this.拡大率DPXtoPX縦方向 );
- public SharpDX.Matrix3x2 拡大行列PXtoDPX => SharpDX.Matrix3x2.Scaling( this.拡大率PXtoDPX横方法, this.拡大率PXtoDPX縦方法 );
- public SharpDX.Matrix3x2 行列を単位変換するDPXtoPX( SharpDX.Matrix3x2 行列dpx ) => 行列dpx * 拡大行列DPXtoPX;
- public SharpDX.Matrix3x2 行列を単位変換するPXtoDPX( SharpDX.Matrix3x2 行列px ) => 行列px * 拡大行列PXtoDPX;
-
- public void すべてのリソースを作成する( System.Drawing.Size バックバッファサイズ, IntPtr ウィンドウハンドル )
+ public float 拡大率PXtoDPX横方向 => ( 1f / this.拡大率DPXtoPX横方向 );
+ public float 拡大率PXtoDPX縦方向 => ( 1f / this.拡大率DPXtoPX縦方向 );
+ public SharpDX.Matrix3x2 拡大行列DPXtoPX => SharpDX.Matrix3x2.Scaling( this.拡大率DPXtoPX横方向, this.拡大率DPXtoPX縦方向 );
+ public SharpDX.Matrix3x2 拡大行列PXtoDPX => SharpDX.Matrix3x2.Scaling( this.拡大率PXtoDPX横方向, this.拡大率PXtoDPX縦方向 );
+
+ public void すべてのリソースを作成する( System.Drawing.Size バックバッファサイズpx, IntPtr ウィンドウハンドル )
{
- this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズ.Width, バックバッファサイズ.Height );
- this.ウィンドウハンドル = ウィンドウハンドル;
+ try
+ {
+ FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
- this.すべてのリソースを作成する();
+ this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズpx.Width, バックバッファサイズpx.Height );
+ this.ウィンドウハンドル = ウィンドウハンドル;
+
+ this.すべてのリソースを作成する();
+ }
+ finally
+ {
+ FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
+ }
}
protected void すべてのリソースを作成する()
{
- // これらが呼び出し前に設定されていること。
- Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
- Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
-
- #region " D2DFactory2 を作成する。"
- //-----------------
+ try
{
- var デバッグレベル = SharpDX.Direct2D1.DebugLevel.None;
-#if DEBUG
- // プロジェクトがデバッグビルドに含まれている場合は、Direct2D デバッグレイヤーを SDK レイヤーを介して有効にする。
- デバッグレベル = SharpDX.Direct2D1.DebugLevel.Information;
-#endif
- this.bs_D2DFactory2 = new SharpDX.Direct2D1.Factory2(
- SharpDX.Direct2D1.FactoryType.SingleThreaded,
- デバッグレベル );
- }
- //-----------------
- #endregion
- #region " DWriteFactory を作成する。"
- //-----------------
- this.bs_DWriteFactory = new SharpDX.DirectWrite.Factory(
- SharpDX.DirectWrite.FactoryType.Shared );
- //-----------------
- #endregion
- #region " WicImagingFactory2 を作成する。"
- //-----------------
- this.bs_WicImagingFactory2 = new SharpDX.WIC.ImagingFactory2();
- //-----------------
- #endregion
+ FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
- var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ // これらが呼び出し前に設定されていること。
+ Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
+ Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
- #region " DXGIDeviceManager を作成する。"
- //-----------------
- this.bs_DXGIDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager();
- //-----------------
- #endregion
- #region " D3Dデバイス、スワップチェーンを作成する。"
- //----------------
- // スワップチェーン desc
- var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() {
- BufferCount = 2,
- ModeDescription = new SharpDX.DXGI.ModeDescription() {
- Width = (int) this.物理画面サイズpx.Width,
- Height = (int) this.物理画面サイズpx.Height,
- RefreshRate = new SharpDX.DXGI.Rational( 60, 1 ),
- Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, // D2D をサポートするなら B8G8R8A8 で。
- Scaling = SharpDX.DXGI.DisplayModeScaling.Stretched,
- ScanlineOrdering = SharpDX.DXGI.DisplayModeScanlineOrder.Progressive,
- },
- IsWindowed = true,
- OutputHandle = ウィンドウハンドル,
- SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ),
- SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
- Usage = SharpDX.DXGI.Usage.RenderTargetOutput,
- };
- // 機能レベル
- var featureLevels = new SharpDX.Direct3D.FeatureLevel[] {
- SharpDX.Direct3D.FeatureLevel.Level_11_0,
- SharpDX.Direct3D.FeatureLevel.Level_10_1,
- SharpDX.Direct3D.FeatureLevel.Level_10_0,
- };
- var creationFlags = SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport; // D2Dをサポートするなら必須。
-#if DEBUG
- creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.Debug;
-#endif
- // デバイスとスワップチェーンを作成する。
- SharpDX.Direct3D11.Device.CreateWithSwapChain(
- SharpDX.Direct3D.DriverType.Hardware,
- creationFlags,
- featureLevels,
- swapChainDesc,
- out d3dDevice,
- out this.bs_SwapChain );
-
- FDK.Log.Info( "D3Dデバイスとスワップチェーンを生成しました。" );
- FDK.Log.Info( $"機能レベル: {d3dDevice.FeatureLevel.ToString()}" );
- //----------------
- #endregion
-
- using( d3dDevice )
- {
- // D3D 関連
- #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) "
+ #region " D2DFactory2 を作成する。"
//-----------------
- using( var videoDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.VideoDevice>() )
{
- if( null == videoDevice )
- throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" );
+ var デバッグレベル = SharpDX.Direct2D1.DebugLevel.None;
+#if DEBUG
+ // プロジェクトがデバッグビルドに含まれている場合は、Direct2D デバッグレイヤーを SDK レイヤーを介して有効にする。
+ デバッグレベル = SharpDX.Direct2D1.DebugLevel.Information;
+#endif
+ this.bs_D2DFactory2 = new SharpDX.Direct2D1.Factory2( SharpDX.Direct2D1.FactoryType.MultiThreaded, デバッグレベル );
}
//-----------------
#endregion
- #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。"
+ #region " DWriteFactory を作成する。"
//-----------------
- using( var multithread = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D.DeviceMultithread>() )
- {
- if( null == multithread )
- throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" );
-
- multithread.SetMultithreadProtected( true );
- }
+ this.bs_DWriteFactory = new SharpDX.DirectWrite.Factory( SharpDX.DirectWrite.FactoryType.Shared );
//-----------------
#endregion
- #region " DXGIデバイスマネージャに D3Dデバイスを登録する。"
+ #region " WicImagingFactory2 を作成する。"
//-----------------
- this.DXGIDeviceManager.ResetDevice( d3dDevice );
+ this.bs_WicImagingFactory2 = new SharpDX.WIC.ImagingFactory2();
//-----------------
#endregion
- #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
- //----------------
- using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
- {
- factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
- }
- //----------------
+
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+
+ #region " DXGIDeviceManager を作成する。"
+ //-----------------
+ this.bs_DXGIDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager();
+ //-----------------
#endregion
- #region " 深度ステンシルステートを作成する。"
+ #region " D3Dデバイスを作成する。"
//----------------
- var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
- IsDepthEnabled = true, // 深度テストあり
- DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All, // 書き込む
- DepthComparison = SharpDX.Direct3D11.Comparison.Less, // 手前の物体を描画
- IsStencilEnabled = false, // ステンシルテストなし。
- StencilReadMask = 0, // ステンシル読み込みマスク。
- StencilWriteMask = 0, // ステンシル書き込みマスク。
-
- // 面が表を向いている場合のステンシル・テストの設定
- FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
- FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
- DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
- PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
- Comparison = SharpDX.Direct3D11.Comparison.Never, // 常に失敗
- },
-
- // 面が裏を向いている場合のステンシル・テストの設定
- BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
- FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
- DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
- PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
- Comparison = SharpDX.Direct3D11.Comparison.Always, // 常に成功
- },
- };
- this.bs_D3DDepthStencilState = new SharpDX.Direct3D11.DepthStencilState( d3dDevice, DepthSencil );
+ // 作成フラグ
+ var creationFlags = SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport; // D2Dをサポートするなら BgraSupport フラグが必須。
+#if DEBUG
+ // D3D11 Debugメッセージは、プロジェクトプロパティで「ネイティブコードのデバッグを有効にする」を ON にしないと表示されないので注意。
+ creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.Debug;
+#endif
+ d3dDevice = new SharpDX.Direct3D11.Device(
+ SharpDX.Direct3D.DriverType.Hardware,
+ creationFlags,
+ new SharpDX.Direct3D.FeatureLevel[] {
+ SharpDX.Direct3D.FeatureLevel.Level_11_1,
+ SharpDX.Direct3D.FeatureLevel.Level_11_0,
+ } );
+
+ FDK.Log.Info( "D3Dデバイスを生成しました。" );
+ FDK.Log.Info( $"機能レベル: {d3dDevice.FeatureLevel.ToString()}" );
//----------------
#endregion
- }
- this.サイズに依存するリソースを作成する();
- }
- public void すべてのリソースを解放する()
- {
- // D3D 関連
- var d3dDevice = (SharpDX.Direct3D11.Device) null;
- using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
- {
- d3dDevice.ImmediateContext?.ClearState(); // デバイスステートをクリアする。
- }
- this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null ); // スワップチェインをウインドウモードにする。
- this.サイズに依存するリソースを解放する();
- FDK.Utilities.解放する( ref this.bs_D3DDepthStencilState );
- FDK.Utilities.解放する( ref this.bs_SwapChain );
- FDK.Utilities.解放する( ref this.bs_DXGIDeviceManager );
-
- // その他
- FDK.Utilities.解放する( ref this.bs_WicImagingFactory2 );
- FDK.Utilities.解放する( ref this.bs_DWriteFactory );
- FDK.Utilities.解放する( ref this.bs_D2DFactory2 );
- }
- public void サイズに依存するリソースを作成する()
- {
- #region " スワップチェーンのサイズを変更する。"
- //----------------
- Debug.Assert( null != this.SwapChain ); // スワップチェーンは、デバイスとともに、すでに生成される。
- this.SwapChain.ResizeBuffers(
- bufferCount: 2,
- width: (int) this.物理画面サイズpx.Width,
- height: (int) this.物理画面サイズpx.Height,
- newFormat: SharpDX.DXGI.Format.B8G8R8A8_UNorm,
- swapChainFlags: SharpDX.DXGI.SwapChainFlags.None );
- //----------------
- #endregion
-
- // D3D 関連
- using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain, 0 ) )
- {
- var d3dDevice = (SharpDX.Direct3D11.Device) null;
- using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ using( d3dDevice )
{
- #region " RenderTargetView の作成 "
- //----------------
- this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( d3dDevice, backBuffer );
- //----------------
- #endregion
- #region " 深度ステンシルテクスチャの作成 "
- //----------------
- var descDepth = backBuffer.Description;
- //descDepth.Width = backBuffer.Description.Width; → backBuffer に同じ
- //descDepth.Height = backBuffer.Description.Height; → 同上
- descDepth.MipLevels = 1; // ミップマップレベル数
- descDepth.ArraySize = 1; // 配列サイズ
- descDepth.Format = SharpDX.DXGI.Format.D32_Float; // フォーマット(深度のみ)
- descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
- descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil; // 深度ステンシル
- descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; // CPUからはアクセスしない
- descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; // その他の設定なし
- this.bs_D3DDepthStencil = new SharpDX.Direct3D11.Texture2D( d3dDevice, descDepth );
- //----------------
- #endregion
- #region " 深度ステンシルビューの作成 "
- //----------------
- var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
- Format = descDepth.Format,
- Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
- Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
- };
- descDSV.Texture2D.MipSlice = 0;
- this.bs_D3DDepthStencilView = new SharpDX.Direct3D11.DepthStencilView( d3dDevice, this.bs_D3DDepthStencil, descDSV );
- //----------------
- #endregion
- #region " ビューポートの設定 "
+ // D3D 関連
+
+ #region " スワップチェーンを作成する。"
//----------------
- this.bs_D3DViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
- X = 0.0f,
- Y = 0.0f,
- Width = (float) backBuffer.Description.Width,
- Height = (float) backBuffer.Description.Height,
- MinDepth = 0.0f,
- MaxDepth = 1.0f,
- };
+ using( var dxgiDevice = d3dDevice.QueryInterface<SharpDX.DXGI.Device>() )
+ using( var dxgiAdapter = dxgiDevice.Adapter )
+ using( var dxgiFactory2 = dxgiAdapter.GetParent<SharpDX.DXGI.Factory2>() )
+ {
+ var swapChainDesc1 = new SharpDX.DXGI.SwapChainDescription1() {
+ BufferCount = 2,
+ Width = (int) this.物理画面サイズpx.Width,
+ Height = (int) this.物理画面サイズpx.Height,
+ Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, // D2D をサポートするなら B8G8R8A8 を使う必要がある。
+ Scaling = SharpDX.DXGI.Scaling.Stretch,
+ SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ),
+ SwapEffect = SharpDX.DXGI.SwapEffect.FlipDiscard, // Windowsストアアプリはこれが必須。
+ Usage = SharpDX.DXGI.Usage.RenderTargetOutput,
+ //Flags = SharpDX.DXGI.SwapChainFlags.None,
+ Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch,
+ };
+ this.bs_SwapChain1 = new SharpDX.DXGI.SwapChain1(
+ dxgiFactory2,
+ d3dDevice,
+ this.ウィンドウハンドル,
+ ref swapChainDesc1 );
+ }
//----------------
#endregion
- #region " ã\83\86ã\82¯ã\82¹ã\83\81ã\83£ã\81®å\85±æ\9c\89ã\83ªã\82½ã\83¼ã\82¹ã\81®ä½\9cæ\88\90 "
+ #region " ã\83\87ã\83\90ã\82¤ã\82¹ã\81\8bã\82\89ã\83\87ã\83\90ã\83\83ã\82°ã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\82\92å\8f\96å¾\97ã\81\99ã\82\8bã\80\82"
//----------------
- FDK.メディア.テクスチャ.共有リソースを作成する( this );
+ this.bs_D3DDeviceDebug = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.DeviceDebug>();
//----------------
#endregion
- }
-
- // D2D 関連
- using( var backbuffer = SharpDX.DXGI.Surface.FromSwapChain( this.bs_SwapChain, 0 ) )
- {
- #region " D2DDevice を作成する。"
+ #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) "
//-----------------
- using( var dxgiDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.DXGI.Device>() )
+ using( var videoDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.VideoDevice>() )
{
- if( null == dxgiDevice )
- throw new FDKException( "Direct3D11デバイスが、IDXGIDevice3 をサポートしていません。" );
-
- this.bs_D2DDevice1 = new SharpDX.Direct2D1.Device1( this.D2DFactory2, dxgiDevice );
+ if( null == videoDevice )
+ throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" );
}
//-----------------
#endregion
- #region " D2Dの既定のコンテキスト D2DContext1 を作成する。"
+ #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。"
//-----------------
- this.bs_D2DContext1 = new SharpDX.Direct2D1.DeviceContext1( this.D2DDevice1, SharpDX.Direct2D1.DeviceContextOptions.None );
+ using( var multithread = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D.DeviceMultithread>() )
+ {
+ if( null == multithread )
+ throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" );
- // 現在のディスプレイDPI を取得し、D2DContext に設定する。
- this.D2DContext1.DotsPerInch = this.D2DFactory2.DesktopDpi;
+ multithread.SetMultithreadProtected( true );
+ }
//-----------------
#endregion
- #region " D2Dの既定のレンダーターゲットビットマップを作成する。"
+ #region " DXGIデバイスマネージャに D3Dデバイスを登録する。"
//-----------------
- var dpi = this.D2DContext1.DotsPerInch;
-
- // DXGIスワップチェーンのバックバッファとデータを共有するD2Dターゲットビットマップを作成する。ビューではなく共有リソース。
- this.bs_D2DRenderTargetBitmap = new SharpDX.Direct2D1.Bitmap1(
- this.D2DContext1, // このコンテキストを通じて、
- backbuffer, // バックバッファとデータを共有する。
- new SharpDX.Direct2D1.BitmapProperties1(
- new SharpDX.Direct2D1.PixelFormat( backbuffer.Description.Format, SharpDX.Direct2D1.AlphaMode.Premultiplied ),
- dpi.Width,
- dpi.Height,
- SharpDX.Direct2D1.BitmapOptions.Target | SharpDX.Direct2D1.BitmapOptions.CannotDraw ) );
-
- // ここで設定する。
- this.D2DContext1.Target = this.bs_D2DRenderTargetBitmap;
+ this.DXGIDeviceManager.ResetDevice( d3dDevice );
//-----------------
#endregion
- #region " テキストのアンチエイリアシングを設定する。Grayscale が、すべての Windows ストアアプリで推奨される。"
- //-----------------
- this.D2DContext1.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale;
- //-----------------
+ #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
+ //----------------
+ using( var factory = this.bs_SwapChain1.GetParent<SharpDX.DXGI.Factory>() )
+ {
+ factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
+ }
+ //----------------
#endregion
}
+
+ this.サイズに依存するリソースを作成する();
+ }
+ finally
+ {
+ FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
+ }
+ }
+ public void すべてのリソースを解放する()
+ {
+ try
+ {
+ FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
+
+ // D3D 関連
+ this.bs_SwapChain1?.SetFullscreenState( fullscreen: false, targetRef: null ); // スワップチェインをウインドウモードにする。
+ this.サイズに依存するリソースを解放する();
+
+ FDK.Utilities.解放する( ref this.bs_SwapChain1 );
+ FDK.Utilities.解放する( ref this.bs_DXGIDeviceManager );
+
+ // その他
+ FDK.Utilities.解放する( ref this.bs_WicImagingFactory2 );
+ FDK.Utilities.解放する( ref this.bs_DWriteFactory );
+ FDK.Utilities.解放する( ref this.bs_D2DFactory2 );
+
+ this.bs_D3DDeviceDebug?.ReportLiveDeviceObjects( SharpDX.Direct3D11.ReportingLevel.Detail );
+ FDK.Utilities.解放する( ref this.bs_D3DDeviceDebug );
+ }
+ finally
+ {
+ FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
+ }
+ }
+ public void Dispose()
+ {
+ this.すべてのリソースを解放する();
+ }
+ public void サイズに依存するリソースを作成する()
+ {
+ try
+ {
+ FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
+
+ #region " スワップチェーンのサイズを変更する。"
+ //----------------
+ Debug.Assert( null != this.SwapChain1 ); // スワップチェーンは(デバイスとともに)すでに生成されていること。
+
+ // ResizeTarget は、全画面モードにしたとき、モニタ画面の解像度も変更する。
+ //var mode = new SharpDX.DXGI.ModeDescription(
+ // width: (int) this.物理画面サイズpx.Width,
+ // height: (int) this.物理画面サイズpx.Height,
+ // refreshRate: new SharpDX.DXGI.Rational( 60000, 1001 ), // 多くのモニタは(60,1)じゃない;一致しないとFlipじゃなくBlitになるので注意(MSDN)。
+ // format: SharpDX.DXGI.Format.B8G8R8A8_UNorm );
+ //this.SwapChain.ResizeTarget( ref mode );
+
+ // ResizeBuffers は、全画面モードにしたとき、モニタの解像度を変更しない。
+ // ただし、swapChainFlags に AllowModeSwitch を指定すると変更される(ResizeTargetと同じ挙動になる)。
+ this.SwapChain1.ResizeBuffers(
+ bufferCount: 2,
+ width: (int) this.物理画面サイズpx.Width,
+ height: (int) this.物理画面サイズpx.Height,
+ newFormat: SharpDX.DXGI.Format.B8G8R8A8_UNorm,
+ //swapChainFlags: SharpDX.DXGI.SwapChainFlags.None );
+ swapChainFlags: SharpDX.DXGI.SwapChainFlags.AllowModeSwitch );
+ //----------------
+ #endregion
+
+ // バックバッファを使って、D3D / D2D 関連のリソースを作成する。
+ using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain1, 0 ) )
+ {
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ using( d3dDevice )
+ {
+ // D3D 関連
+ #region " レンダーターゲットビューを作成する。"
+ //----------------
+ this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( d3dDevice, backBuffer );
+ //----------------
+ #endregion
+ #region " 深度ステンシルテクスチャを作成する。"
+ //----------------
+ var descDepth = backBuffer.Description;
+ //descDepth.Width = backBuffer.Description.Width; → backBuffer に同じ
+ //descDepth.Height = backBuffer.Description.Height; → 同上
+ descDepth.MipLevels = 1; // ミップマップレベル数
+ descDepth.ArraySize = 1; // 配列サイズ
+ descDepth.Format = SharpDX.DXGI.Format.D32_Float; // フォーマット(深度のみ)
+ descDepth.Usage = SharpDX.Direct3D11.ResourceUsage.Default; // デフォルト使用法
+ descDepth.BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil; // 深度ステンシル
+ descDepth.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; // CPUからはアクセスしない
+ descDepth.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; // その他の設定なし
+ this.bs_D3DDepthStencil = new SharpDX.Direct3D11.Texture2D( d3dDevice, descDepth );
+ //----------------
+ #endregion
+ #region " 深度ステンシルビューを作成する。"
+ //----------------
+ var descDSV = new SharpDX.Direct3D11.DepthStencilViewDescription() {
+ Format = descDepth.Format,
+ Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D,
+ Flags = SharpDX.Direct3D11.DepthStencilViewFlags.None,
+ Texture2D = new SharpDX.Direct3D11.DepthStencilViewDescription.Texture2DResource() {
+ MipSlice = 0,
+ },
+ };
+ this.bs_D3DDepthStencilView = new SharpDX.Direct3D11.DepthStencilView( d3dDevice, this.bs_D3DDepthStencil, descDSV );
+ //----------------
+ #endregion
+ #region " 深度ステンシルステートを作成する。"
+ //----------------
+ var DepthSencil = new SharpDX.Direct3D11.DepthStencilStateDescription() {
+ IsDepthEnabled = true, // 深度テストあり
+ DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All, // 書き込む
+ DepthComparison = SharpDX.Direct3D11.Comparison.Less, // 手前の物体を描画
+ IsStencilEnabled = false, // ステンシルテストなし。
+ StencilReadMask = 0, // ステンシル読み込みマスク。
+ StencilWriteMask = 0, // ステンシル書き込みマスク。
+
+ // 面が表を向いている場合のステンシル・テストの設定
+ FrontFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
+ FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
+ DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
+ PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
+ Comparison = SharpDX.Direct3D11.Comparison.Never, // 常に失敗
+ },
+
+ // 面が裏を向いている場合のステンシル・テストの設定
+ BackFace = new SharpDX.Direct3D11.DepthStencilOperationDescription() {
+ FailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
+ DepthFailOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
+ PassOperation = SharpDX.Direct3D11.StencilOperation.Keep, // 維持
+ Comparison = SharpDX.Direct3D11.Comparison.Always, // 常に成功
+ },
+ };
+ this.bs_D3DDepthStencilState = new SharpDX.Direct3D11.DepthStencilState( d3dDevice, DepthSencil );
+ //----------------
+ #endregion
+ #region " ビューポートを作成する。"
+ //----------------
+ this.bs_D3DViewPort[ 0 ] = new SharpDX.Mathematics.Interop.RawViewportF() {
+ X = 0.0f,
+ Y = 0.0f,
+ Width = (float) backBuffer.Description.Width, // 物理画面単位[px]
+ Height = (float) backBuffer.Description.Height, // 物理画面単位[px]
+ MinDepth = 0.0f,
+ MaxDepth = 1.0f,
+ };
+ //----------------
+ #endregion
+ #region " 全テクスチャで共有するリソースを作成する。"
+ //----------------
+ FDK.メディア.テクスチャ.全インスタンスで共有するリソースを作成する( this );
+ //----------------
+ #endregion
+
+ // D2D 関連
+ using( var backsurface = SharpDX.DXGI.Surface.FromSwapChain( this.bs_SwapChain1, 0 ) )
+ {
+ #region " D2DDevice を作成する。"
+ //-----------------
+ using( var dxgiDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.DXGI.Device>() )
+ {
+ if( null == dxgiDevice )
+ throw new FDKException( "Direct3D11デバイスが、IDXGIDevice3 をサポートしていません。" );
+
+ this.bs_D2DDevice1 = new SharpDX.Direct2D1.Device1( this.D2DFactory2, dxgiDevice );
+ }
+ //-----------------
+ #endregion
+ #region " D2Dの既定のデバイスコンテキストを作成する。"
+ //-----------------
+ this.bs_D2DContext1 = new SharpDX.Direct2D1.DeviceContext1( this.D2DDevice1, SharpDX.Direct2D1.DeviceContextOptions.None );
+
+ // 現在のディスプレイDPI を取得し、D2DContext に設定する。
+ //this.D2DContext1.DotsPerInch = this.D2DFactory2.DesktopDpi;
+ this.D2DContext1.DotsPerInch = new SharpDX.Size2F( 96f, 96f );
+ //-----------------
+ #endregion
+ #region " D2Dの既定のレンダーターゲットビットマップを作成する。"
+ //-----------------
+ var dpi = this.D2DContext1.DotsPerInch;
+
+ // DXGIスワップチェーンのバックバッファとデータを共有するD2Dターゲットビットマップを作成する。ビューではなく共有リソース。
+ this.bs_D2DRenderTargetBitmap = new SharpDX.Direct2D1.Bitmap1(
+ this.D2DContext1, // このコンテキストを通じて、
+ backsurface, // バックバッファとデータを共有する。
+ new SharpDX.Direct2D1.BitmapProperties1(
+ new SharpDX.Direct2D1.PixelFormat( backsurface.Description.Format, SharpDX.Direct2D1.AlphaMode.Premultiplied ),
+ dpi.Width,
+ dpi.Height,
+ SharpDX.Direct2D1.BitmapOptions.Target | SharpDX.Direct2D1.BitmapOptions.CannotDraw ) );
+
+ // ここでもうD2Dのレンダーターゲットとして登録しておく。
+ this.D2DContext1.Target = this.bs_D2DRenderTargetBitmap;
+ //-----------------
+ #endregion
+ #region " テキストのアンチエイリアシングを設定する。"
+ //-----------------
+ // Grayscale が、すべての Windows ストアアプリで推奨される。らしい。
+ this.D2DContext1.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale;
+ //-----------------
+ #endregion
+ }
+ }
+ }
+ }
+ finally
+ {
+ FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
}
public void サイズに依存するリソースを解放する()
{
- // D2D 関連
- if( null != this.bs_D2DContext1 )
- this.bs_D2DContext1.Target = null;
- FDK.Utilities.解放する( ref this.bs_D2DRenderTargetBitmap );
- FDK.Utilities.解放する( ref this.bs_D2DContext1 );
- FDK.Utilities.解放する( ref this.bs_D2DDevice1 );
-
- // D3D 関連
- var d3dDevice = (SharpDX.Direct3D11.Device) null;
- using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ try
{
- // 描画ターゲットを解除する。
- d3dDevice.ImmediateContext.OutputMerger.ResetTargets();
+ FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
+
+ // D2D 関連
+ if( null != this.bs_D2DContext1 )
+ this.bs_D2DContext1.Target = null;
+ FDK.Utilities.解放する( ref this.bs_D2DRenderTargetBitmap );
+ FDK.Utilities.解放する( ref this.bs_D2DContext1 );
+ FDK.Utilities.解放する( ref this.bs_D2DDevice1 );
- FDK.メディア.テクスチャ.共有リソースを解放する();
- FDK.Utilities.解放する( ref this.bs_D3DDepthStencilView );
- FDK.Utilities.解放する( ref this.bs_D3DDepthStencil );
- FDK.Utilities.解放する( ref this.bs_D3DRenderTargetView );
- //FDK.Utilities.解放する( ref this.bs_SwapChain ); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
+ // D3D 関連
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ using( d3dDevice )
+ using( var d3dContext = d3dDevice.ImmediateContext )
+ {
+ d3dContext.ClearState();
+ d3dContext.OutputMerger.ResetTargets();
- // (0,0)は、サイズ依存リソース無効の印。
- this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
+ FDK.メディア.テクスチャ.全インスタンスで共有するリソースを解放する();
+
+ FDK.Utilities.解放する( ref this.bs_D3DDepthStencilState );
+ FDK.Utilities.解放する( ref this.bs_D3DDepthStencilView );
+ FDK.Utilities.解放する( ref this.bs_D3DDepthStencil );
+ FDK.Utilities.解放する( ref this.bs_D3DRenderTargetView );
+ //FDK.Utilities.解放する( ref this.bs_SwapChain ); → スワップチェーンは解放しない(これの生成・解放はデバイスとセットで行う)。
+
+ // (0,0)は、サイズ依存リソース無効の印。
+ this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
+ }
+ }
+ finally
+ {
+ FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
}
public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ )
{
+ 異常状態なのでアプリを終了せよ = false;
+ SharpDX.Result 削除理由;
+
var d3dDevice = (SharpDX.Direct3D11.Device) null;
using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ using( d3dDevice )
{
- 異常状態なのでアプリを終了せよ = false;
+ 削除理由 = d3dDevice.DeviceRemovedReason;
+ }
- var 削除理由 = d3dDevice.DeviceRemovedReason;
- if( 削除理由.Success )
- return;
+ if( 削除理由.Success )
+ return; // デバイスは消失していない。
- var エラー詳細 = new[] {
+ var エラー詳細 = new[] {
new { Code = SharpDX.DXGI.ResultCode.DeviceHung.Code, Info = SharpDX.DXGI.ResultCode.DeviceHung.ApiCode, Rebuild = true },
new { Code = SharpDX.DXGI.ResultCode.DeviceReset.Code, Info = SharpDX.DXGI.ResultCode.DeviceReset.ApiCode, Rebuild = true },
new { Code = SharpDX.DXGI.ResultCode.DeviceRemoved.Code, Info = SharpDX.DXGI.ResultCode.DeviceRemoved.ApiCode, Rebuild = false },
new { Code = SharpDX.DXGI.ResultCode.InvalidCall.Code, Info = SharpDX.DXGI.ResultCode.InvalidCall.ApiCode, Rebuild = false },
}.First( ( エラー ) => エラー.Code == 削除理由.Code ); // 見つからないなら System.InvalidOperationException 。
- Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
+ Trace.WriteLine( $"D3Dデバイスが消失しました: {エラー詳細.Info}" );
- if( エラー詳細.Rebuild )
- {
- this.すべてのリソースを解放する();
- this.すべてのリソースを作成する();
- }
- else
- {
- 異常状態なのでアプリを終了せよ = true;
- }
+ if( エラー詳細.Rebuild )
+ {
+ this.すべてのリソースを解放する();
+ this.すべてのリソースを作成する();
}
+ else
+ {
+ 異常状態なのでアプリを終了せよ = true;
+ }
+ }
+ public void D2DContextの設定をリセットする( SharpDX.Direct2D1.DeviceContext1 context1 )
+ {
+ context1.Transform = SharpDX.Matrix3x2.Identity;
+ context1.PrimitiveBlend = SharpDX.Direct2D1.PrimitiveBlend.SourceOver;
}
private float dz( float 高さdpx, float 視野角deg )
private SharpDX.DirectWrite.Factory bs_DWriteFactory = null;
private SharpDX.WIC.ImagingFactory2 bs_WicImagingFactory2 = null;
private SharpDX.MediaFoundation.DXGIDeviceManager bs_DXGIDeviceManager = null;
- private SharpDX.DXGI.SwapChain bs_SwapChain = null;
+ private SharpDX.DXGI.SwapChain1 bs_SwapChain1 = null;
private SharpDX.Mathematics.Interop.RawViewportF[] bs_D3DViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
private SharpDX.Direct3D11.DepthStencilState bs_D3DDepthStencilState = null;
private SharpDX.Direct3D11.RenderTargetView bs_D3DRenderTargetView = null;
private SharpDX.Direct3D11.Texture2D bs_D3DDepthStencil = null;
private SharpDX.Direct3D11.DepthStencilView bs_D3DDepthStencilView = null;
+ private SharpDX.Direct3D11.DeviceDebug bs_D3DDeviceDebug = null;
private SharpDX.Direct2D1.Device1 bs_D2DDevice1 = null;
private SharpDX.Direct2D1.DeviceContext1 bs_D2DContext1 = null;
private SharpDX.Direct2D1.Bitmap1 bs_D2DRenderTargetBitmap = null;