{
return; // まだ初期化されてない(ので何もしない)。
}
- if( null == this.デバイスリソース.D3DDevice )
- {
- Trace.WriteLine( "D3Dデバイスが null です。" );
- return;
- }
if( this.WindowState == FormWindowState.Minimized )
{
Trace.WriteLine( "最小化されました。" );
<Compile Include="フォルダ.cs" />
<Compile Include="メディア\テクスチャ.cs" />
<Compile Include="メディア\デバイスリソース.cs" />
+ <Compile Include="同期\AutoD3DDeviceLock.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
public static void 共有リソースを作成する( FDK.メディア.デバイスリソース dr )
{
- #region " 頂点シェーダ "
- //----------------
- var シェーダコンパイルのオプション =
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
+ {
+ #region " 頂点シェーダ "
+ //----------------
+ var シェーダコンパイルのオプション =
SharpDX.D3DCompiler.ShaderFlags.Debug |
SharpDX.D3DCompiler.ShaderFlags.SkipOptimization |
SharpDX.D3DCompiler.ShaderFlags.EnableStrictness |
SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor;
- // シェーダコードをコンパイルする。
- using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
- FDK.Properties.Resources.テクスチャ用シェーダコード,
- "VS", "vs_4_0", シェーダコンパイルのオプション ) )
- {
- // 頂点シェーダを生成する。
- テクスチャ.VertexShader = new SharpDX.Direct3D11.VertexShader( dr.D3DDevice, code );
- }
- //----------------
- #endregion
- #region " ピクセルシェーダ "
- //----------------
- // シェーダコードをコンパイルする。
- using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
- FDK.Properties.Resources.テクスチャ用シェーダコード,
- "PS", "ps_4_0", シェーダコンパイルのオプション ) )
- {
- // ピクセルシェーダを作成する。
- テクスチャ.PixelShader = new SharpDX.Direct3D11.PixelShader( dr.D3DDevice, code );
+ // シェーダコードをコンパイルする。
+ using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
+ FDK.Properties.Resources.テクスチャ用シェーダコード,
+ "VS", "vs_4_0", シェーダコンパイルのオプション ) )
+ {
+ // 頂点シェーダを生成する。
+ テクスチャ.VertexShader = new SharpDX.Direct3D11.VertexShader( d3dDevice, code );
+ }
+ //----------------
+ #endregion
+ #region " ピクセルシェーダ "
+ //----------------
+ // シェーダコードをコンパイルする。
+ using( var code = SharpDX.D3DCompiler.ShaderBytecode.Compile(
+ FDK.Properties.Resources.テクスチャ用シェーダコード,
+ "PS", "ps_4_0", シェーダコンパイルのオプション ) )
+ {
+ // ピクセルシェーダを作成する。
+ テクスチャ.PixelShader = new SharpDX.Direct3D11.PixelShader( d3dDevice, code );
+ }
+ //----------------
+ #endregion
+ #region " ブレンドステート "
+ //----------------
+ var BlendState = new SharpDX.Direct3D11.BlendStateDescription() {
+ AlphaToCoverageEnable = false, // アルファマスクで透過する(するならZバッファ必須)
+ IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
+ };
+ BlendState.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
+ BlendState.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All; // RGBA の書き込みマスク。
+
+ // アルファ値のブレンディング設定 ... 特になし
+ BlendState.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
+ BlendState.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
+ BlendState.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
+
+ // 色値のブレンディング設定 ... アルファ強度に応じた透明合成(テクスチャのアルファ値は、テクスチャのアルファ×ピクセルシェーダでの全体アルファとする(HLSL参照))
+ BlendState.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
+ BlendState.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.InverseSourceAlpha;
+ BlendState.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
+
+ // ブレンドステートを作成する。
+ テクスチャ.BlendState = new SharpDX.Direct3D11.BlendState( d3dDevice, BlendState );
+ //----------------
+ #endregion
+ #region " ラスタライザステート "
+ //----------------
+ var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
+ FillMode = SharpDX.Direct3D11.FillMode.Solid, // 普通に描画する
+ CullMode = SharpDX.Direct3D11.CullMode.None, // 両面を描画する
+ IsFrontCounterClockwise = false, // 時計回りが表面
+ DepthBias = 0,
+ DepthBiasClamp = 0,
+ SlopeScaledDepthBias = 0,
+ IsDepthClipEnabled = true,
+ IsScissorEnabled = false,
+ IsMultisampleEnabled = false,
+ IsAntialiasedLineEnabled = false,
+ };
+ テクスチャ.RasterizerState = new SharpDX.Direct3D11.RasterizerState( d3dDevice, RSDesc );
+ //----------------
+ #endregion
+ #region " サンプラーステート "
+ //----------------
+ var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
+ Filter = SharpDX.Direct3D11.Filter.Anisotropic,
+ AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
+ AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
+ AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
+ MipLodBias = 0.0f,
+ MaximumAnisotropy = 2,
+ ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
+ BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
+ MinimumLod = float.MinValue,
+ MaximumLod = float.MaxValue,
+ };
+ テクスチャ.SamplerState = new SharpDX.Direct3D11.SamplerState( d3dDevice, descSampler );
+ //----------------
+ #endregion
}
- //----------------
- #endregion
- #region " ブレンドステート "
- //----------------
- var BlendState = new SharpDX.Direct3D11.BlendStateDescription() {
- AlphaToCoverageEnable = false, // アルファマスクで透過する(するならZバッファ必須)
- IndependentBlendEnable = false, // 個別設定。false なら BendStateDescription.RenderTarget[0] だけが有効で、[1~7] は無視される。
- };
- BlendState.RenderTarget[ 0 ].IsBlendEnabled = true; // true ならブレンディングが有効。
- BlendState.RenderTarget[ 0 ].RenderTargetWriteMask = SharpDX.Direct3D11.ColorWriteMaskFlags.All; // RGBA の書き込みマスク。
-
- // アルファ値のブレンディング設定 ... 特になし
- BlendState.RenderTarget[ 0 ].SourceAlphaBlend = SharpDX.Direct3D11.BlendOption.One;
- BlendState.RenderTarget[ 0 ].DestinationAlphaBlend = SharpDX.Direct3D11.BlendOption.Zero;
- BlendState.RenderTarget[ 0 ].AlphaBlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
-
- // 色値のブレンディング設定 ... アルファ強度に応じた透明合成(テクスチャのアルファ値は、テクスチャのアルファ×ピクセルシェーダでの全体アルファとする(HLSL参照))
- BlendState.RenderTarget[ 0 ].SourceBlend = SharpDX.Direct3D11.BlendOption.SourceAlpha;
- BlendState.RenderTarget[ 0 ].DestinationBlend = SharpDX.Direct3D11.BlendOption.InverseSourceAlpha;
- BlendState.RenderTarget[ 0 ].BlendOperation = SharpDX.Direct3D11.BlendOperation.Add;
-
- // ブレンドステートを作成する。
- テクスチャ.BlendState = new SharpDX.Direct3D11.BlendState( dr.D3DDevice, BlendState );
- //----------------
- #endregion
- #region " ラスタライザステート "
- //----------------
- var RSDesc = new SharpDX.Direct3D11.RasterizerStateDescription() {
- FillMode = SharpDX.Direct3D11.FillMode.Solid, // 普通に描画する
- CullMode = SharpDX.Direct3D11.CullMode.None, // 両面を描画する
- IsFrontCounterClockwise = false, // 時計回りが表面
- DepthBias = 0,
- DepthBiasClamp = 0,
- SlopeScaledDepthBias = 0,
- IsDepthClipEnabled = true,
- IsScissorEnabled = false,
- IsMultisampleEnabled = false,
- IsAntialiasedLineEnabled = false,
- };
- テクスチャ.RasterizerState = new SharpDX.Direct3D11.RasterizerState( dr.D3DDevice, RSDesc );
- //----------------
- #endregion
- #region " サンプラーステート "
- //----------------
- var descSampler = new SharpDX.Direct3D11.SamplerStateDescription() {
- Filter = SharpDX.Direct3D11.Filter.Anisotropic,
- AddressU = SharpDX.Direct3D11.TextureAddressMode.Wrap,
- AddressV = SharpDX.Direct3D11.TextureAddressMode.Wrap,
- AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap,
- MipLodBias = 0.0f,
- MaximumAnisotropy = 2,
- ComparisonFunction = SharpDX.Direct3D11.Comparison.Never,
- BorderColor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ),
- MinimumLod = float.MinValue,
- MaximumLod = float.MaxValue,
- };
- テクスチャ.SamplerState = new SharpDX.Direct3D11.SamplerState( dr.D3DDevice, descSampler );
- //----------------
- #endregion
}
public static void 共有リソースを解放する()
{
}
protected override void On活性化( デバイスリソース dr )
{
- #region " 定数バッファ "
- //----------------
- var cBufferDesc = new SharpDX.Direct3D11.BufferDescription() {
- Usage = SharpDX.Direct3D11.ResourceUsage.Dynamic, // 動的使用法
- BindFlags = SharpDX.Direct3D11.BindFlags.ConstantBuffer, // 定数バッファ
- CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Write, // CPUから書き込む
- OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
- SizeInBytes = SharpDX.Utilities.SizeOf<ST定数バッファの転送元データ>(), // バッファサイズ
- StructureByteStride = 0,
- };
- this.ConstantBuffer = new SharpDX.Direct3D11.Buffer( dr.D3DDevice, cBufferDesc );
- //----------------
- #endregion
- #region " シェーダーリソースビュー "
- //----------------
- this.ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
- dr.D3DDevice, "テスト用テクスチャ画像.jpg", out this.ShaderResourceViewSize );
- //----------------
- #endregion
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
+ {
+ #region " 定数バッファ "
+ //----------------
+ var cBufferDesc = new SharpDX.Direct3D11.BufferDescription() {
+ Usage = SharpDX.Direct3D11.ResourceUsage.Dynamic, // 動的使用法
+ BindFlags = SharpDX.Direct3D11.BindFlags.ConstantBuffer, // 定数バッファ
+ CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Write, // CPUから書き込む
+ OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
+ SizeInBytes = SharpDX.Utilities.SizeOf<ST定数バッファの転送元データ>(), // バッファサイズ
+ StructureByteStride = 0,
+ };
+ this.ConstantBuffer = new SharpDX.Direct3D11.Buffer( d3dDevice, cBufferDesc );
+ //----------------
+ #endregion
+ #region " シェーダーリソースビュー "
+ //----------------
+ this.ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile(
+ d3dDevice, FDK.フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this.画像ファイルパス ), out this.ShaderResourceViewSize );
+ //----------------
+ #endregion
+ }
}
protected override void On非活性化( デバイスリソース dr )
{
/// <param name="転送元矩形">テクスチャ座標(値域0~1)で指定する。</param>
public void 進行描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null )
{
- var d3dContext = dr.D3DDevice.ImmediateContext;
-
- #region " 定数バッファを更新する。"
- //----------------
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) )
{
- // ワールド変換行列
- ワールド行列変換.Transpose(); // 転置
- this.定数バッファの転送元データ.World = ワールド行列変換;
-
- // ビュー変換行列
- this.定数バッファの転送元データ.View = dr.ビュー変換行列;
-
- // 射影変換行列
- this.定数バッファの転送元データ.Projection = dr.射影変換行列;
-
- // 描画元矩形
- if( null == 転送元矩形 )
- 転送元矩形 = new SharpDX.RectangleF( 0f, 0f, 1f, 1f );
- this.定数バッファの転送元データ.TexLeft = 転送元矩形.Value.Left;
- this.定数バッファの転送元データ.TexTop = 転送元矩形.Value.Top;
- this.定数バッファの転送元データ.TexRight = 転送元矩形.Value.Right;
- this.定数バッファの転送元データ.TexBottom = 転送元矩形.Value.Bottom;
-
- // アルファ
- this.定数バッファの転送元データ.TexAlpha = this.不透明度;
- this.定数バッファの転送元データ.dummy1 = 0f;
- this.定数バッファの転送元データ.dummy2 = 0f;
- this.定数バッファの転送元データ.dummy3 = 0f;
-
- // 定数バッファへの書き込み
- var dataBox = d3dContext.MapSubresource(
- resourceRef: this.ConstantBuffer,
- subresource: 0,
- mapType: SharpDX.Direct3D11.MapMode.WriteDiscard,
- mapFlags: SharpDX.Direct3D11.MapFlags.None );
- SharpDX.Utilities.Write( dataBox.DataPointer, ref this.定数バッファの転送元データ );
- d3dContext.UnmapSubresource( this.ConstantBuffer, 0 );
+ var d3dContext = d3dDevice.ImmediateContext;
+
+ #region " 定数バッファを更新する。"
+ //----------------
+ {
+ // ワールド変換行列
+ ワールド行列変換.Transpose(); // 転置
+ this.定数バッファの転送元データ.World = ワールド行列変換;
+
+ // ビュー変換行列
+ this.定数バッファの転送元データ.View = dr.ビュー変換行列;
+
+ // 射影変換行列
+ this.定数バッファの転送元データ.Projection = dr.射影変換行列;
+
+ // 描画元矩形
+ if( null == 転送元矩形 )
+ 転送元矩形 = new SharpDX.RectangleF( 0f, 0f, 1f, 1f );
+ this.定数バッファの転送元データ.TexLeft = 転送元矩形.Value.Left;
+ this.定数バッファの転送元データ.TexTop = 転送元矩形.Value.Top;
+ this.定数バッファの転送元データ.TexRight = 転送元矩形.Value.Right;
+ this.定数バッファの転送元データ.TexBottom = 転送元矩形.Value.Bottom;
+
+ // アルファ
+ this.定数バッファの転送元データ.TexAlpha = this.不透明度;
+ this.定数バッファの転送元データ.dummy1 = 0f;
+ this.定数バッファの転送元データ.dummy2 = 0f;
+ this.定数バッファの転送元データ.dummy3 = 0f;
+
+ // 定数バッファへの書き込み
+ var dataBox = d3dContext.MapSubresource(
+ resourceRef: this.ConstantBuffer,
+ subresource: 0,
+ mapType: SharpDX.Direct3D11.MapMode.WriteDiscard,
+ mapFlags: SharpDX.Direct3D11.MapFlags.None );
+ SharpDX.Utilities.Write( dataBox.DataPointer, ref this.定数バッファの転送元データ );
+ d3dContext.UnmapSubresource( this.ConstantBuffer, 0 );
+ }
+ //----------------
+ #endregion
+ #region " 3Dパイプラインを設定する。"
+ //----------------
+ // 入力アセンブラ
+ d3dContext.InputAssembler.InputLayout = null;
+ d3dContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
+
+ // 頂点シェーダ
+ d3dContext.VertexShader.Set( テクスチャ.VertexShader );
+ d3dContext.VertexShader.SetConstantBuffers( 0, this.ConstantBuffer );
+
+ // ジオメトリシェーダ
+ d3dContext.GeometryShader.Set( null );
+
+ // ラスタライザ
+ d3dContext.Rasterizer.SetViewports( dr.D3DViewPort );
+ d3dContext.Rasterizer.State = テクスチャ.RasterizerState;
+
+ // ピクセルシェーダ
+ d3dContext.PixelShader.Set( テクスチャ.PixelShader );
+ d3dContext.PixelShader.SetConstantBuffers( 0, this.ConstantBuffer );
+ d3dContext.PixelShader.SetShaderResources( 0, 1, this.ShaderResourceView );
+ d3dContext.PixelShader.SetSamplers( 0, 1, テクスチャ.SamplerState );
+
+ // 出力マージャ
+ d3dContext.OutputMerger.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
+ d3dContext.OutputMerger.SetBlendState( テクスチャ.BlendState, new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ), -1 );
+ d3dContext.OutputMerger.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
+ //----------------
+ #endregion
+
+ // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
+ d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
}
- //----------------
- #endregion
- #region " 3Dパイプラインを設定する。"
- //----------------
- // 入力アセンブラ
- d3dContext.InputAssembler.InputLayout = null;
- d3dContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;
-
- // 頂点シェーダ
- d3dContext.VertexShader.Set( テクスチャ.VertexShader );
- d3dContext.VertexShader.SetConstantBuffers( 0, this.ConstantBuffer );
-
- // ジオメトリシェーダ
- d3dContext.GeometryShader.Set( null );
-
- // ラスタライザ
- d3dContext.Rasterizer.SetViewports( dr.D3DViewPort );
- d3dContext.Rasterizer.State = テクスチャ.RasterizerState;
-
- // ピクセルシェーダ
- d3dContext.PixelShader.Set( テクスチャ.PixelShader );
- d3dContext.PixelShader.SetConstantBuffers( 0, this.ConstantBuffer );
- d3dContext.PixelShader.SetShaderResources( 0, 1, this.ShaderResourceView );
- d3dContext.PixelShader.SetSamplers( 0, 1, テクスチャ.SamplerState );
-
- // 出力マージャ
- d3dContext.OutputMerger.SetTargets( dr.D3DDepthStencilView, dr.D3DRenderTargetView );
- d3dContext.OutputMerger.SetBlendState( テクスチャ.BlendState, new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ), -1 );
- d3dContext.OutputMerger.SetDepthStencilState( dr.D3DDepthStencilState, 0 );
- //----------------
- #endregion
-
- // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。
- d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 );
}
protected string 画像ファイルパス = null;
return mat;
}
}
- public SharpDX.Direct3D11.Device D3DDevice => this.bs_D3DDevice;
+ 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;
Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) );
Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル );
- #region " デバイス、スワップチェーンを作成する。"
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+
+ #region " DXGIDeviceManager を作成する。"
+ //-----------------
+ this.bs_DXGIDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager();
+ //-----------------
+ #endregion
+ #region " D3Dデバイス、スワップチェーンを作成する。"
//----------------
// スワップチェーン desc
var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() {
SharpDX.Direct3D11.DeviceCreationFlags.None,
featureLevels,
swapChainDesc,
- out this.bs_D3DDevice,
+ out d3dDevice,
out this.bs_SwapChain );
Trace.WriteLine( "D3Dデバイスとスワップチェーンを生成しました。" );
- Trace.WriteLine( $"機能レベル: {this.bs_D3DDevice.FeatureLevel.ToString()}" );
+ Trace.WriteLine( $"機能レベル: {d3dDevice.FeatureLevel.ToString()}" );
//----------------
#endregion
- #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
- //----------------
- using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
+
+ using( d3dDevice )
{
- factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
- }
- //----------------
- #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, // ステンシル書き込みマスク。
+ #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) "
+ //-----------------
+ using( var videoDevice = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D11.VideoDevice>() )
+ {
+ if( null == videoDevice )
+ throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" );
+ }
+ //-----------------
+ #endregion
+ #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。"
+ //-----------------
+ using( var multithread = d3dDevice.QueryInterfaceOrNull<SharpDX.Direct3D.DeviceMultithread>() )
+ {
+ if( null == multithread )
+ throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" );
- // 面が表を向いている場合のステンシル・テストの設定
- 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, // 常に失敗
- },
+ multithread.SetMultithreadProtected( true );
+ }
+ //-----------------
+ #endregion
+ #region " DXGIデバイスマネージャに D3Dデバイスを登録する。"
+ //-----------------
+ this.DXGIDeviceManager.ResetDevice( d3dDevice );
+ //-----------------
+ #endregion
+ #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。"
+ //----------------
+ using( var factory = this.bs_SwapChain.GetParent<SharpDX.DXGI.Factory>() )
+ {
+ factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll );
+ }
+ //----------------
+ #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, // ステンシル書き込みマスク。
- // 面が裏を向いている場合のステンシル・テストの設定
- 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( this.bs_D3DDevice, DepthSencil );
- //----------------
- #endregion
+ // 面が表を向いている場合のステンシル・テストの設定
+ 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
+ }
this.サイズに依存するリソースを作成する();
}
public void すべてのリソースを解放する()
{
- // デバイスステートをクリアする。
- this.bs_D3DDevice?.ImmediateContext?.ClearState();
+ 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.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null );
- this.サイズに依存するリソースを解放する();
+ this.サイズに依存するリソースを解放する();
- // 取得したインターフェイスの開放
- this.bs_D3DDepthStencilState?.Dispose();
- this.bs_SwapChain?.Dispose();
- this.bs_D3DDevice?.Dispose();
+ // 取得したインターフェイスの開放
+ this.bs_D3DDepthStencilState?.Dispose();
+ this.bs_SwapChain?.Dispose();
+ this.bs_DXGIDeviceManager?.ResetDevice( null );
+ this.bs_DXGIDeviceManager?.Dispose();
+ }
}
public void サイズに依存するリソースを作成する()
{
// 新しいサイズになったバックバッファを取得して、リソースを作成する。
using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>( this.bs_SwapChain, 0 ) )
{
- #region " RenderTargetView の作成 "
- //----------------
- this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( this.bs_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( this.bs_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(
- this.bs_D3DDevice,
- this.bs_D3DDepthStencil,
- descDSV );
- //----------------
- #endregion
- #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,
- };
- //----------------
- #endregion
- #region " テクスチャの共有リソースの作成 "
- //----------------
- FDK.メディア.テクスチャ.共有リソースを作成する( this );
- //----------------
- #endregion
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out 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 " ビューポートの設定 "
+ //----------------
+ 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,
+ };
+ //----------------
+ #endregion
+ #region " テクスチャの共有リソースの作成 "
+ //----------------
+ FDK.メディア.テクスチャ.共有リソースを作成する( this );
+ //----------------
+ #endregion
+ }
}
}
public void サイズに依存するリソースを解放する()
{
- // 描画ターゲットを解除する。
- this.D3DDevice.ImmediateContext.OutputMerger.ResetTargets();
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ {
+ // 描画ターゲットを解除する。
+ d3dDevice.ImmediateContext.OutputMerger.ResetTargets();
- FDK.メディア.テクスチャ.共有リソースを解放する();
- this.bs_D3DDepthStencilView?.Dispose();
- this.bs_D3DDepthStencil?.Dispose();
- this.bs_D3DRenderTargetView?.Dispose();
- //this.bs_SwapChain?.Dispose(); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
+ FDK.メディア.テクスチャ.共有リソースを解放する();
+ this.bs_D3DDepthStencilView?.Dispose();
+ this.bs_D3DDepthStencil?.Dispose();
+ this.bs_D3DRenderTargetView?.Dispose();
+ //this.bs_SwapChain?.Dispose(); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。
- // (0,0)は、サイズ依存リソース無効の印。
- this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
+ // (0,0)は、サイズ依存リソース無効の印。
+ this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 );
+ }
}
public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ )
{
- 異常状態なのでアプリを終了せよ = false;
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) )
+ {
+ 異常状態なのでアプリを終了せよ = false;
- var 削除理由 = this.bs_D3DDevice.DeviceRemovedReason;
- if( 削除理由.Success )
- return;
+ var 削除理由 = d3dDevice.DeviceRemovedReason;
+ 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;
+ }
}
}
#region " バックストア。"
//----------------
- private SharpDX.Direct3D11.Device bs_D3DDevice = null;
+ private SharpDX.MediaFoundation.DXGIDeviceManager bs_DXGIDeviceManager = null;
private SharpDX.DXGI.SwapChain bs_SwapChain = null;
private SharpDX.Mathematics.Interop.RawViewportF[] bs_D3DViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
private SharpDX.Direct3D11.DepthStencilState bs_D3DDepthStencilState = null;
--- /dev/null
+using System;
+using System.Collections.Generic;
+
+namespace FDK.同期
+{
+ /// <summary>
+ /// DXGIデバイスマネージャからD3Dデバイスを取得するためのロック機構。
+ /// </summary>
+ /// <remarks>
+ /// MediaFoundation と Direct3D は、DXGI のロックを介して Direct3Dデバイス を共有する。
+ /// </remarks>
+ public class AutoD3DDeviceLock : IDisposable
+ {
+ public AutoD3DDeviceLock( SharpDX.MediaFoundation.DXGIDeviceManager deviceManager, out SharpDX.Direct3D11.Device d3dDevice )
+ {
+ this.deviceManager = deviceManager;
+ this.deviceHandle = this.deviceManager.OpenDeviceHandle();
+ this.デバイスをロックし取得する( out d3dDevice );
+ }
+ public void Dispose()
+ {
+ this.デバイスを解放しロックを解除する();
+ //Utility.Disposeする( ref this.deviceManager ); → ここで Dispose してはならない。Dispose する責任は呼び出しもとにある。
+ this.deviceManager = null; // 自分の参照だけを外す。
+ }
+
+ private void デバイスをロックし取得する( out SharpDX.Direct3D11.Device d3dDevice )
+ {
+ var dev = this.deviceManager.LockDevice(
+ this.deviceHandle,
+ typeof( SharpDX.Direct3D11.Device ).GUID,
+ true ); // Lockできるまでブロックする
+
+ d3dDevice = new SharpDX.Direct3D11.Device( dev );
+ }
+ private void デバイスを解放しロックを解除する()
+ {
+ if( IntPtr.Zero == this.deviceHandle )
+ return;
+
+ this.deviceManager.UnlockDevice( this.deviceHandle );
+ this.deviceManager.CloseDeviceHandle( this.deviceHandle );
+ this.deviceHandle = IntPtr.Zero;
+ }
+
+ private SharpDX.MediaFoundation.DXGIDeviceManager deviceManager = null;
+ private IntPtr deviceHandle = IntPtr.Zero;
+ }
+}
this.testTexture.活性化する( this.デバイスリソース );
}
- var d3dContext = this.デバイスリソース.D3DDevice.ImmediateContext;
-
- #region " ビューをクリアする。"
- //----------------
- d3dContext.ClearRenderTargetView(
- this.デバイスリソース.D3DRenderTargetView, SharpDX.Color4.Black );
+ var d3dDevice = (SharpDX.Direct3D11.Device) null;
+ using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.デバイスリソース.DXGIDeviceManager, out d3dDevice ) )
+ {
+ #region " ビューをクリアする。"
+ //----------------
+ d3dDevice.ImmediateContext.ClearRenderTargetView(
+ this.デバイスリソース.D3DRenderTargetView, SharpDX.Color4.Black );
- d3dContext.ClearDepthStencilView(
- this.デバイスリソース.D3DDepthStencilView,
- SharpDX.Direct3D11.DepthStencilClearFlags.Depth, // ここでは深度バッファのみ。
- depth: 1.0f,
- stencil: 0 );
- //----------------
- #endregion
+ d3dDevice.ImmediateContext.ClearDepthStencilView(
+ this.デバイスリソース.D3DDepthStencilView,
+ SharpDX.Direct3D11.DepthStencilClearFlags.Depth, // ここでは深度バッファのみ。
+ depth: 1.0f,
+ stencil: 0 );
+ //----------------
+ #endregion
+ }
#warning " テストコード。"
var matScale = SharpDX.Matrix.Scaling( 320f, 240f, 1.0f );