From 4ac8ebae9fb2d3b0da6ffe2961ed3da0a15d01c3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E3=81=8F=E3=81=BE=E3=81=8B=E3=81=BF=E5=B7=A5=E6=88=BF?= Date: Sat, 17 Sep 2016 18:35:32 +0900 Subject: [PATCH] =?utf8?q?FDK.Utilities,=20FDK.=E3=83=A1=E3=83=87=E3=82=A3?= =?utf8?q?=E3=82=A2.=E3=83=86=E3=82=AF=E3=82=B9=E3=83=81=E3=83=A3,=20FDK.?= =?utf8?q?=E3=83=A1=E3=83=87=E3=82=A3=E3=82=A2.=E3=83=87=E3=83=90=E3=82=A4?= =?utf8?q?=E3=82=B9=E3=83=AA=E3=82=BD=E3=83=BC=E3=82=B9=20=E3=81=AE?= =?utf8?q?=EF=BC=93=E3=81=A4=E3=81=AB=E3=80=81=E3=82=B3=E3=83=BC=E3=83=89?= =?utf8?q?=E3=82=92=E5=88=86=E5=89=B2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- FDK24/ApplicationFormBase.cs | 579 ++++--------------------- FDK24/FDK24.csproj | 3 + FDK24/Utilities.cs | 51 +++ FDK24/メディア/テクスチャ.cs | 17 + FDK24/メディア/デバイスリソース.cs | 414 ++++++++++++++++++ 5 files changed, 566 insertions(+), 498 deletions(-) create mode 100644 FDK24/Utilities.cs create mode 100644 FDK24/メディア/テクスチャ.cs create mode 100644 FDK24/メディア/デバイスリソース.cs diff --git a/FDK24/ApplicationFormBase.cs b/FDK24/ApplicationFormBase.cs index d93bd87..5b21bc9 100644 --- a/FDK24/ApplicationFormBase.cs +++ b/FDK24/ApplicationFormBase.cs @@ -14,7 +14,7 @@ namespace FDK // メインループ。 SharpDX.Windows.RenderLoop.Run( this, () => { - this.D3Dデバイスが消失していれば再構築する(); // 再構築できないなら this.Exit = true で帰ってくる。 + this.デバイスリソース.D3Dデバイスが消失していれば再構築する( out this.Exit ); if( this.Exit ) { this.終了する(); @@ -22,64 +22,16 @@ namespace FDK return; } this.シーンを描画する(); - this.SwapChain.Present( 0, SharpDX.DXGI.PresentFlags.None ); + this.デバイスリソース.SwapChain.Present( 0, SharpDX.DXGI.PresentFlags.None ); } ); } - // 定数バッファのデータ定義 - struct cbBuffer - { - public SharpDX.Matrix World; // ワールド変換行列 - public SharpDX.Matrix View; // ビュー変換行列 - public SharpDX.Matrix Projection; // 透視変換行列 - - public float TexLeft; // 描画元矩形の左u座標(0~1) - public float TexTop; // 描画元矩形の上v座標(0~1) - public float TexRight; // 描画元矩形の右u座標(0~1) - public float TexBottom; // 描画元矩形の下v座標(0~1) - - public float TexAlpha; // テクスチャに乗じるアルファ値(0~1) - public float dummy1; // float4境界に合わせるためのダミー - public float dummy2; // float4境界に合わせるためのダミー - public float dummy3; // float4境界に合わせるためのダミー - }; - // 定数バッファのデータ - cbBuffer g_cbBuffer; - - SharpDX.Mathematics.Interop.RawViewportF[] ViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ]; - SharpDX.Direct3D11.Texture2D DepthStencil = null; - SharpDX.Direct3D11.DepthStencilView DepthStencilView = null; - SharpDX.Direct3D11.VertexShader VertexShader = null; - SharpDX.Direct3D11.GeometryShader GeometryShader = null; - SharpDX.Direct3D11.PixelShader PixelShader = null; - SharpDX.Direct3D11.Buffer ConstantBuffer = null; - SharpDX.Direct3D11.BlendState BlendState = null; - SharpDX.Direct3D11.RasterizerState RasterizerState = null; - SharpDX.Direct3D11.DepthStencilState DepthStencilState = null; - SharpDX.Direct3D11.ShaderResourceView ShaderResourceView = null; - SharpDX.Direct3D11.SamplerState SamplerState = null; - - readonly SharpDX.D3DCompiler.ShaderFlags ShaderCompileOption = - SharpDX.D3DCompiler.ShaderFlags.Debug | - SharpDX.D3DCompiler.ShaderFlags.SkipOptimization | - SharpDX.D3DCompiler.ShaderFlags.EnableStrictness | - SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor; - - protected System.Drawing.Size initialFormSize = new System.Drawing.Size( 640, 480 ); - protected bool Exit; - protected SharpDX.Direct3D11.Device D3DDevice = null; - protected SharpDX.DXGI.SwapChain SwapChain = null; - protected SharpDX.Direct3D11.RenderTargetView RenderTargetView = null; - protected float 視野角 = 45f; - protected SharpDX.Size2F 設計画面サイズdpx = new SharpDX.Size2F( 640f, 480f ); - protected float 不透明度 = 0.5f; // 0:透明~1:不透明 - protected void 初期化する() { this.Text = $"StrokeStyle {System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()}"; - this.ClientSize = this.initialFormSize; - - this.デバイスリソースを作成する(); + this.ClientSize = new System.Drawing.Size( 640, 480 ); // 初期サイズ + this.デバイスリソース = new メディア.デバイスリソース(); + this.デバイスリソース.デバイスリソースを作成する( this.ClientSize, this.Handle ); // キー入力ハンドラを登録する。 this.KeyDown += ( target, arg ) => { @@ -90,355 +42,19 @@ namespace FDK } protected void 終了する() { - this.デバイスリソースを解放する(); - } - protected void デバイスリソースを作成する() - { - #region " デバイス、スワップチェーンを作成する。" - //---------------- - // スワップチェーン desc - var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() { - BufferCount = 3, - ModeDescription = new SharpDX.DXGI.ModeDescription( - this.ClientSize.Width, - this.ClientSize.Height, - new SharpDX.DXGI.Rational( 60, 1 ), - //SharpDX.DXGI.Format.R8G8B8A8_UNorm - SharpDX.DXGI.Format.B8G8R8A8_UNorm - ), - IsWindowed = true, - OutputHandle = this.Handle, - 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, - }; - - // デバイスとスワップチェーンを作成する。 - SharpDX.Direct3D11.Device.CreateWithSwapChain( - SharpDX.Direct3D.DriverType.Hardware, - SharpDX.Direct3D11.DeviceCreationFlags.None, - featureLevels, - swapChainDesc, - out this.D3DDevice, - out this.SwapChain ); - - Trace.WriteLine( "D3Dデバイスとスワップチェーンを生成しました。" ); - Trace.WriteLine( $"機能レベル: {this.D3DDevice.FeatureLevel.ToString()}" ); - //---------------- - #endregion - #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。" - //---------------- - using( var factory = this.SwapChain.GetParent() ) - { - factory.MakeWindowAssociation( this.Handle, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll ); - } - //---------------- - #endregion - #region " 頂点シェーダ " - //---------------- - // コードをコンパイルする - using( var pBlosVS = SharpDX.D3DCompiler.ShaderBytecode.Compile( - FDK.Properties.Resources.テクスチャ用シェーダコード, - "VS", "vs_4_0", this.ShaderCompileOption ) ) - { - // 頂点シェーダの作成 - this.VertexShader = new SharpDX.Direct3D11.VertexShader( this.D3DDevice, pBlosVS ); - } - //---------------- - #endregion - #region " ピクセルシェーダ " - //---------------- - // コードをコンパイルする - using( var pBlosPS = SharpDX.D3DCompiler.ShaderBytecode.Compile( - FDK.Properties.Resources.テクスチャ用シェーダコード, - "PS", "ps_4_0", this.ShaderCompileOption ) ) - { - // ピクセルシェーダの作成 - this.PixelShader = new SharpDX.Direct3D11.PixelShader( this.D3DDevice, pBlosPS ); - } - //---------------- - #endregion - #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, - StructureByteStride = 0, - }; - // 定数バッファの作成 - cBufferDesc.SizeInBytes = SharpDX.Utilities.SizeOf(); // バッファサイズ - this.ConstantBuffer = new SharpDX.Direct3D11.Buffer( this.D3DDevice, cBufferDesc ); - //---------------- - #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; - - // ブレンド・ステート・オブジェクトの作成 - this.BlendState = new SharpDX.Direct3D11.BlendState( this.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, - }; - // ラスタライザ・ステート・オブジェクトの作成 - this.RasterizerState = new SharpDX.Direct3D11.RasterizerState( this.D3DDevice, RSDesc ); - //---------------- - #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.DepthStencilState = new SharpDX.Direct3D11.DepthStencilState( this.D3DDevice, DepthSencil ); - //---------------- - #endregion - #region " シェーダーリソースビュー " - //---------------- - this.ShaderResourceView = this.CreateShaderResourceViewFromFile( "テスト用テクスチャ画像.jpg" ); - //D3DX11CreateShaderResourceViewFromFile( g_pD3DDevice, L"texture.png", NULL, NULL, &g_pTextureSRV, &hr ); - //---------------- - #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, - }; - this.SamplerState = new SharpDX.Direct3D11.SamplerState( this.D3DDevice, descSampler ); - //---------------- - #endregion - #region " リソースの種類 " - //---------------- - using( var pResource = this.ShaderResourceView.Resource ) - { - var type = pResource.Dimension; - - switch( type ) - { - case SharpDX.Direct3D11.ResourceDimension.Texture1D: - // 1次元テクスチャの処理 - using( var pTexture1D = pResource.QueryInterface() ) - { - var desc = pTexture1D.Description; - Trace.WriteLine( $"1DTexture Width={desc.Width}" ); - } - break; - - case SharpDX.Direct3D11.ResourceDimension.Texture2D: - // 2次元テクスチャの処理 - using( var pTexture2D = pResource.QueryInterface() ) - { - var desc = pTexture2D.Description; - Trace.WriteLine( $"1DTexture Width={desc.Width} Height={desc.Height}" ); - } - break; - - case SharpDX.Direct3D11.ResourceDimension.Texture3D: - // 3次元テクスチャの処理 - using( var pTexture3D = pResource.QueryInterface() ) - { - var desc = pTexture3D.Description; - Trace.WriteLine( $"1DTexture Width={desc.Width} Height={desc.Height} Depth={desc.Depth}" ); - } - break; - - default: - Trace.WriteLine( "UNKNOWN or BUFFER Resource" ); - break; - } - } - //---------------- - #endregion - - this.バックバッファを初期化する(); - } - private SharpDX.Direct3D11.ShaderResourceView CreateShaderResourceViewFromFile( string filePath ) - { - var srv = (SharpDX.Direct3D11.ShaderResourceView) null; - - using( var image = new System.Drawing.Bitmap( filePath ) ) - { - var boundsRect = new System.Drawing.Rectangle( 0, 0, image.Width, image.Height ); - using( var bitmap = image.Clone( boundsRect, System.Drawing.Imaging.PixelFormat.Format32bppArgb ) ) - { - var mapSrc = bitmap.LockBits( boundsRect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat ); - var databox = new[] { new SharpDX.DataBox( mapSrc.Scan0, bitmap.Width * 4, bitmap.Height ) }; - var textureDesc = new SharpDX.Direct3D11.Texture2DDescription() { - ArraySize = 1, - BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, - CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, - Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, - Height = bitmap.Height, - Width = bitmap.Width, - MipLevels = 1, - OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, - SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ), - Usage = SharpDX.Direct3D11.ResourceUsage.Default - }; - using( var texture = new SharpDX.Direct3D11.Texture2D( this.D3DDevice, textureDesc, databox ) ) - { - bitmap.UnlockBits( mapSrc ); - srv = new SharpDX.Direct3D11.ShaderResourceView( this.D3DDevice, texture ); - } - } - } - return srv; - } - protected void バックバッファを初期化する() - { - // バックバッファを取得 - using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain( this.SwapChain, 0 ) ) - { - #region " RenderTargetView の作成 " - //---------------- - this.RenderTargetView = new SharpDX.Direct3D11.RenderTargetView( this.D3DDevice, backBuffer ); - //---------------- - #endregion - #region " 深度ステンシルテクスチャの作成 " - //---------------- - var descDepth = backBuffer.Description; - //descDepth.Width = backBuffer.Description.Width; // 幅 - //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.DepthStencil = new SharpDX.Direct3D11.Texture2D( this.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.DepthStencilView = new SharpDX.Direct3D11.DepthStencilView( - this.D3DDevice, - this.DepthStencil, - descDSV ); - //---------------- - #endregion - #region " ビューポートの設定 " - //---------------- - this.ViewPort[ 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 - } - } - protected void デバイスリソースを解放する() - { - // デバイスステートのクリア - this.D3DDevice?.ImmediateContext?.ClearState(); - - // スワップ チェインをウインドウ モードにする - this.SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null ); - - // 取得したインターフェイスの開放 - this.SamplerState?.Dispose(); - this.ShaderResourceView?.Dispose(); - this.DepthStencilState?.Dispose(); - this.BlendState?.Dispose(); - this.RasterizerState?.Dispose(); - this.ConstantBuffer?.Dispose(); - this.PixelShader?.Dispose(); - this.GeometryShader?.Dispose(); - this.VertexShader?.Dispose(); - this.DepthStencilView?.Dispose(); - this.DepthStencil?.Dispose(); - - this.RenderTargetView?.Dispose(); - this.SwapChain?.Dispose(); - this.D3DDevice?.Dispose(); + this.デバイスリソース?.デバイスリソースを解放する(); + this.デバイスリソース = null; } protected void シーンを描画する() { + var d3dContext = this.デバイスリソース.D3DDevice.ImmediateContext; + // レンダーターゲットビューを黒でクリアする。 - this.D3DDevice.ImmediateContext.ClearRenderTargetView( - this.RenderTargetView, - SharpDX.Color4.Black ); + d3dContext.ClearRenderTargetView( this.デバイスリソース.RenderTargetView, SharpDX.Color4.Black ); // 深度ステンシルビューをクリアする。(ここでは深度バッファのみクリア。) - this.D3DDevice.ImmediateContext.ClearDepthStencilView( - this.DepthStencilView, + d3dContext.ClearDepthStencilView( + this.デバイスリソース.DepthStencilView, SharpDX.Direct3D11.DepthStencilClearFlags.Depth, depth: 1.0f, stencil: 0 ); @@ -448,133 +64,95 @@ namespace FDK #region " 定数バッファを更新 " //---------------- { - float dz = (float) ( this.設計画面サイズdpx.Height / ( 4.0 * Math.Tan( SharpDX.MathUtil.DegreesToRadians( this.視野角 / 2.0f ) ) ) ); + float dz = (float) ( this.デバイスリソース.設計画面サイズdpx.Height / ( 4.0 * Math.Tan( SharpDX.MathUtil.DegreesToRadians( this.デバイスリソース.視野角 / 2.0f ) ) ) ); // ビュー変換行列 var カメラ位置 = new SharpDX.Vector3( 0f, 0f, -2f * dz ); var 注視点 = new SharpDX.Vector3( 0f, 0f, 0f ); var カメラの上方向 = new SharpDX.Vector3( 0f, 1f, 0f ); var mat = SharpDX.Matrix.LookAtLH( カメラ位置, 注視点, カメラの上方向 ); - this.g_cbBuffer.View = mat; - this.g_cbBuffer.View.Transpose(); // 転置 + mat.Transpose(); // 転置 + this.デバイスリソース.定数バッファの転送元データ.View = mat; // ワールド変換行列 var matScale = SharpDX.Matrix.Scaling( 320f, 240f, 1.0f ); var matY = SharpDX.Matrix.RotationY( (float) ( Math.PI * ( timeGetTime() % 3000 ) ) / 1500.0f ); var matX = SharpDX.Matrix.RotationX( (float) ( Math.PI * ( timeGetTime() % 1500 ) ) / 750.0f ); - this.g_cbBuffer.World = matScale * matY * matX; - this.g_cbBuffer.World.Transpose(); // 転置 + mat = matScale * matY * matX; + mat.Transpose(); // 転置 + this.デバイスリソース.定数バッファの転送元データ.World = mat; // 射影変換行列(パースペクティブ(透視法)射影) mat = SharpDX.Matrix.PerspectiveFovLH( - SharpDX.MathUtil.DegreesToRadians( this.視野角 ), - (float) this.設計画面サイズdpx.Width / (float) this.設計画面サイズdpx.Height, // アスペクト比 + SharpDX.MathUtil.DegreesToRadians( this.デバイスリソース.視野角 ), + (float) this.デバイスリソース.設計画面サイズdpx.Width / (float) this.デバイスリソース.設計画面サイズdpx.Height, // アスペクト比 -dz, // 前方投影面までの距離 dz ); // 後方投影面までの距離 - this.g_cbBuffer.Projection = mat; - this.g_cbBuffer.Projection.Transpose(); // 転置 + mat.Transpose(); // 転置 + this.デバイスリソース.定数バッファの転送元データ.Projection = mat; // 描画元矩形 - this.g_cbBuffer.TexLeft = 0f; - this.g_cbBuffer.TexTop = 0f; - this.g_cbBuffer.TexRight = 0.5f; - this.g_cbBuffer.TexBottom = 0.5f; + this.デバイスリソース.定数バッファの転送元データ.TexLeft = 0f; + this.デバイスリソース.定数バッファの転送元データ.TexTop = 0f; + this.デバイスリソース.定数バッファの転送元データ.TexRight = 0.5f; + this.デバイスリソース.定数バッファの転送元データ.TexBottom = 0.5f; // アルファ - this.g_cbBuffer.TexAlpha = this.不透明度; - this.g_cbBuffer.dummy1 = 0f; - this.g_cbBuffer.dummy2 = 0f; - this.g_cbBuffer.dummy3 = 0f; + this.デバイスリソース.定数バッファの転送元データ.TexAlpha = this.デバイスリソース.不透明度; + this.デバイスリソース.定数バッファの転送元データ.dummy1 = 0f; + this.デバイスリソース.定数バッファの転送元データ.dummy2 = 0f; + this.デバイスリソース.定数バッファの転送元データ.dummy3 = 0f; // 定数バッファへの書き込み - var dataBox = this.D3DDevice.ImmediateContext.MapSubresource( - resourceRef: this.ConstantBuffer, + 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.g_cbBuffer ); - this.D3DDevice.ImmediateContext.UnmapSubresource( this.ConstantBuffer, 0 ); + SharpDX.Utilities.Write( dataBox.DataPointer, ref this.デバイスリソース.定数バッファの転送元データ ); + d3dContext.UnmapSubresource( this.デバイスリソース.ConstantBuffer, 0 ); } //---------------- #endregion - // IAに入力レイアウトオブジェクトを設定 - this.D3DDevice.ImmediateContext.InputAssembler.InputLayout = null; - // IAにプリミティブの種類を設定 - this.D3DDevice.ImmediateContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip; - - // VSに頂点シェーダを設定 - this.D3DDevice.ImmediateContext.VertexShader.Set( this.VertexShader ); - // VSに定数バッファを設定 - this.D3DDevice.ImmediateContext.VertexShader.SetConstantBuffers( 0, this.ConstantBuffer ); - - // GSにジオメトリシェーダを設定 - this.D3DDevice.ImmediateContext.GeometryShader.Set( null ); - // GSに定数バッファを設定 - // this.d3dDevice.ImmediateContext.GeometryShader.SetConstantBuffers( 0, this.g_pCBuffer ); - - // RSにビューポートを設定 - this.D3DDevice.ImmediateContext.Rasterizer.SetViewports( this.ViewPort ); - // RSにラスタライザ・ステート・オブジェクトを設定 - this.D3DDevice.ImmediateContext.Rasterizer.State = this.RasterizerState; - - // PSにピクセルシェーダを設定 - this.D3DDevice.ImmediateContext.PixelShader.Set( this.PixelShader ); - // PSに定数バッファを設定 - this.D3DDevice.ImmediateContext.PixelShader.SetConstantBuffers( 0, this.ConstantBuffer ); - // PSにシェーダ・リソース・ビューを設定 - this.D3DDevice.ImmediateContext.PixelShader.SetShaderResources( - 0, // 設定する最初のスロット番号 - 1, // 設定するシェーダ・リソース・ビューの数 - this.ShaderResourceView // 設定するシェーダ・リソース・ビューの配列 - ); - // PSにサンプラーを設定 - this.D3DDevice.ImmediateContext.PixelShader.SetSamplers( 0, 1, this.SamplerState ); - - // OMに深度ステンシルビューとレンダーターゲットビューを設定 - this.D3DDevice.ImmediateContext.OutputMerger.SetTargets( this.DepthStencilView, this.RenderTargetView ); - // OMにブレンド・ステート・オブジェクトを設定 - var BlendFactor = new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ); - this.D3DDevice.ImmediateContext.OutputMerger.SetBlendState( this.BlendState, BlendFactor, -1 ); - // OMに深度ステンシル・ステート・オブジェクトを設定 - this.D3DDevice.ImmediateContext.OutputMerger.SetDepthStencilState( this.DepthStencilState, 0 ); - - // 頂点バッファとインデックスバッファを使わずに描画する - this.D3DDevice.ImmediateContext.Draw( - 4, // 描画する頂点数 - 0 ); // 最初の頂点ID - } - protected void D3Dデバイスが消失していれば再構築する() - { - var 削除理由 = this.D3DDevice.DeviceRemovedReason; - - if( 削除理由.Failure ) - { - 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.DriverInternalError.Code, Info = SharpDX.DXGI.ResultCode.DriverInternalError.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}" ); - - if( エラー詳細.Rebuild ) - { - this.デバイスリソースを解放する(); - this.デバイスリソースを作成する(); - } - else - { - this.Exit = true; - } - } + // 入力アセンブラ + d3dContext.InputAssembler.InputLayout = null; + d3dContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip; + + // 頂点シェーダ + d3dContext.VertexShader.Set( this.デバイスリソース.VertexShader ); + d3dContext.VertexShader.SetConstantBuffers( 0, this.デバイスリソース.ConstantBuffer ); + + // ジオメトリシェーダ + d3dContext.GeometryShader.Set( null ); + + // ラスタライザ + d3dContext.Rasterizer.SetViewports( this.デバイスリソース.ViewPort ); + d3dContext.Rasterizer.State = this.デバイスリソース.RasterizerState; + + // ピクセルシェーダ + d3dContext.PixelShader.Set( this.デバイスリソース.PixelShader ); + d3dContext.PixelShader.SetConstantBuffers( 0, this.デバイスリソース.ConstantBuffer ); + d3dContext.PixelShader.SetShaderResources( 0, 1, this.デバイスリソース.ShaderResourceView ); + d3dContext.PixelShader.SetSamplers( 0, 1, this.デバイスリソース.SamplerState ); + + // 出力マージャ + d3dContext.OutputMerger.SetTargets( this.デバイスリソース.DepthStencilView, this.デバイスリソース.RenderTargetView ); + d3dContext.OutputMerger.SetBlendState( this.デバイスリソース.BlendState, new SharpDX.Mathematics.Interop.RawColor4( 0f, 0f, 0f, 0f ), -1 ); + d3dContext.OutputMerger.SetDepthStencilState( this.デバイスリソース.DepthStencilState, 0 ); + + // 頂点バッファとインデックスバッファを使わずに 4 つの頂点を描画する。 + d3dContext.Draw( vertexCount: 4, startVertexLocation: 0 ); } protected override void OnSizeChanged( EventArgs e ) { - if( null == this.D3DDevice ) + // 実行時条件チェック。 + if( null == this.デバイスリソース ) + { + return; // まだ初期化されてない(ので何もしない)。 + } + if( null == this.デバイスリソース.D3DDevice ) { Trace.WriteLine( "D3Dデバイスが null です。" ); return; @@ -585,21 +163,23 @@ namespace FDK return; // 何もしない } - // 描画ターゲットを解除する - this.D3DDevice.ImmediateContext.OutputMerger.ResetTargets(); // 描画ターゲットの解除 - this.RenderTargetView.Dispose(); // 描画ターゲット ビューの解放 - this.DepthStencilView.Dispose(); // 深度ステンシル ビューの解放 - this.DepthStencil.Dispose(); // 深度ステンシル テクスチャの解放 + // 描画ターゲットを解除する。 + this.デバイスリソース.D3DDevice.ImmediateContext.OutputMerger.ResetTargets(); // 描画ターゲットの解除 - // バッファの変更 - this.SwapChain.ResizeBuffers( + // サイズに依存するリソースを解放する。 + this.デバイスリソース.RenderTargetView.Dispose(); + this.デバイスリソース.DepthStencilView.Dispose(); + this.デバイスリソース.DepthStencil.Dispose(); + + // バックバッファのサイズを変更する。 + this.デバイスリソース.SwapChain.ResizeBuffers( bufferCount: 3, width: this.ClientSize.Width, height: this.ClientSize.Height, newFormat: SharpDX.DXGI.Format.R8G8B8A8_UNorm, swapChainFlags: SharpDX.DXGI.SwapChainFlags.AllowModeSwitch ); - this.バックバッファを初期化する(); + this.デバイスリソース.バックバッファを初期化する(); base.OnSizeChanged( e ); } @@ -610,6 +190,9 @@ namespace FDK base.OnKeyDown( e ); } + protected bool Exit; + protected FDK.メディア.デバイスリソース デバイスリソース = null; + [System.Runtime.InteropServices.DllImport( "winmm.dll" )] private static extern uint timeGetTime(); private const int WM_SIZE = 0x0005; diff --git a/FDK24/FDK24.csproj b/FDK24/FDK24.csproj index 3d96ce1..1022260 100644 --- a/FDK24/FDK24.csproj +++ b/FDK24/FDK24.csproj @@ -93,6 +93,9 @@ True Resources.resx + + + diff --git a/FDK24/Utilities.cs b/FDK24/Utilities.cs new file mode 100644 index 0000000..6098730 --- /dev/null +++ b/FDK24/Utilities.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace FDK +{ + public static class Utilities + { + /// + /// 画像ファイルからシェーダリソースビューを作成して返す。 + /// D3DX11CreateShaderResourceViewFromFile() の代わり。 + /// + public static SharpDX.Direct3D11.ShaderResourceView CreateShaderResourceViewFromFile( + SharpDX.Direct3D11.Device d3dDevice, string 画像ファイルパス, out SharpDX.Size2F ビューのサイズ ) + { + ビューのサイズ = new SharpDX.Size2F( 0, 0 ); + var srv = (SharpDX.Direct3D11.ShaderResourceView) null; + using( var image = new System.Drawing.Bitmap( 画像ファイルパス ) ) + { + var 画像の矩形 = new System.Drawing.Rectangle( 0, 0, image.Width, image.Height ); + using( var bitmap = image.Clone( 画像の矩形, System.Drawing.Imaging.PixelFormat.Format32bppArgb ) ) + { + var ロック領域 = bitmap.LockBits( 画像の矩形, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat ); + var dataBox = new[] { new SharpDX.DataBox( ロック領域.Scan0, bitmap.Width * 4, bitmap.Height ) }; + var textureDesc = new SharpDX.Direct3D11.Texture2DDescription() { + ArraySize = 1, + BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, + CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, + Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, + Height = bitmap.Height, + Width = bitmap.Width, + MipLevels = 1, + OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, + SampleDescription = new SharpDX.DXGI.SampleDescription( 1, 0 ), + Usage = SharpDX.Direct3D11.ResourceUsage.Default + }; + using( var texture = new SharpDX.Direct3D11.Texture2D( d3dDevice, textureDesc, dataBox ) ) + { + bitmap.UnlockBits( ロック領域 ); + srv = new SharpDX.Direct3D11.ShaderResourceView( d3dDevice, texture ); + } + } + // 戻り値1:ビューのサイズ + ビューのサイズ = new SharpDX.Size2F( 画像の矩形.Width, 画像の矩形.Height ); + } + // 戻り値2:シェーダリソースビュー + return srv; + } + } +} diff --git a/FDK24/メディア/テクスチャ.cs b/FDK24/メディア/テクスチャ.cs new file mode 100644 index 0000000..0d200db --- /dev/null +++ b/FDK24/メディア/テクスチャ.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace FDK.メディア +{ + public class テクスチャ + { + public static void 共有リソースを作成する() + { + } + public static void 共有リソースを解放する() + { + } + } +} diff --git a/FDK24/メディア/デバイスリソース.cs b/FDK24/メディア/デバイスリソース.cs new file mode 100644 index 0000000..3562903 --- /dev/null +++ b/FDK24/メディア/デバイスリソース.cs @@ -0,0 +1,414 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace FDK.メディア +{ + public class デバイスリソース + { + public SharpDX.Size2F 設計画面サイズdpx = new SharpDX.Size2F( 640f, 480f ); + public SharpDX.Size2F 物理画面サイズpx; + public IntPtr ウィンドウハンドル = IntPtr.Zero; + public float 視野角 = 45f; + public float 不透明度 = 0.5f; // 0:透明~1:不透明 + public struct ST定数バッファの転送元データ + { + public SharpDX.Matrix World; // ワールド変換行列 + public SharpDX.Matrix View; // ビュー変換行列 + public SharpDX.Matrix Projection; // 透視変換行列 + + public float TexLeft; // 描画元矩形の左u座標(0~1) + public float TexTop; // 描画元矩形の上v座標(0~1) + public float TexRight; // 描画元矩形の右u座標(0~1) + public float TexBottom; // 描画元矩形の下v座標(0~1) + + public float TexAlpha; // テクスチャに乗じるアルファ値(0~1) + public float dummy1; // float4境界に合わせるためのダミー + public float dummy2; // float4境界に合わせるためのダミー + public float dummy3; // float4境界に合わせるためのダミー + }; + public ST定数バッファの転送元データ 定数バッファの転送元データ; + + public SharpDX.Direct3D11.Device D3DDevice => this.bs_D3DDevice; + public SharpDX.DXGI.SwapChain SwapChain => this.bs_SwapChain; + public SharpDX.Direct3D11.RenderTargetView RenderTargetView => this.bs_RenderTargetView; + public SharpDX.Mathematics.Interop.RawViewportF[] ViewPort => this.bs_ViewPort; + public SharpDX.Direct3D11.Texture2D DepthStencil => this.bs_DepthStencil; + public SharpDX.Direct3D11.DepthStencilView DepthStencilView => this.bs_DepthStencilView; + public SharpDX.Direct3D11.DepthStencilState DepthStencilState => this.bs_DepthStencilState; + public SharpDX.Direct3D11.VertexShader VertexShader => this.bs_VertexShader; + public SharpDX.Direct3D11.PixelShader PixelShader => this.bs_PixelShader; + public SharpDX.Direct3D11.Buffer ConstantBuffer => this.bs_ConstantBuffer; + public SharpDX.Direct3D11.BlendState BlendState => this.bs_BlendState; + public SharpDX.Direct3D11.RasterizerState RasterizerState => this.bs_RasterizerState; + public SharpDX.Direct3D11.ShaderResourceView ShaderResourceView => this.bs_ShaderResourceView; + public SharpDX.Direct3D11.SamplerState SamplerState => this.bs_SamplerState; + + public void デバイスリソースを作成する( System.Drawing.Size バックバッファサイズ, IntPtr ウィンドウハンドル ) + { + this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズ.Width, バックバッファサイズ.Height ); + this.ウィンドウハンドル = ウィンドウハンドル; + + this.デバイスリソースを作成する(); + } + protected void デバイスリソースを作成する() + { + // これらが呼び出し前に設定されていること。 + Debug.Assert( ( 0f < this.物理画面サイズpx.Width ) && ( 0f < this.物理画面サイズpx.Height ) ); + Debug.Assert( IntPtr.Zero != this.ウィンドウハンドル ); + + #region " デバイス、スワップチェーンを作成する。" + //---------------- + // スワップチェーン desc + var swapChainDesc = new SharpDX.DXGI.SwapChainDescription() { + BufferCount = 3, + ModeDescription = new SharpDX.DXGI.ModeDescription( + (int) this.物理画面サイズpx.Width, + (int) this.物理画面サイズpx.Height, + new SharpDX.DXGI.Rational( 60, 1 ), + SharpDX.DXGI.Format.B8G8R8A8_UNorm + ), + 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, + }; + + // デバイスとスワップチェーンを作成する。 + SharpDX.Direct3D11.Device.CreateWithSwapChain( + SharpDX.Direct3D.DriverType.Hardware, + SharpDX.Direct3D11.DeviceCreationFlags.None, + featureLevels, + swapChainDesc, + out this.bs_D3DDevice, + out this.bs_SwapChain ); + + Trace.WriteLine( "D3Dデバイスとスワップチェーンを生成しました。" ); + Trace.WriteLine( $"機能レベル: {this.bs_D3DDevice.FeatureLevel.ToString()}" ); + //---------------- + #endregion + #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。" + //---------------- + using( var factory = this.bs_SwapChain.GetParent() ) + { + factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll ); + } + //---------------- + #endregion + #region " 頂点シェーダ " + //---------------- + // コードをコンパイルする + using( var pBlosVS = SharpDX.D3DCompiler.ShaderBytecode.Compile( + FDK.Properties.Resources.テクスチャ用シェーダコード, + "VS", "vs_4_0", this.ShaderCompileOption ) ) + { + // 頂点シェーダの作成 + this.bs_VertexShader = new SharpDX.Direct3D11.VertexShader( this.bs_D3DDevice, pBlosVS ); + } + //---------------- + #endregion + #region " ピクセルシェーダ " + //---------------- + // コードをコンパイルする + using( var pBlosPS = SharpDX.D3DCompiler.ShaderBytecode.Compile( + FDK.Properties.Resources.テクスチャ用シェーダコード, + "PS", "ps_4_0", this.ShaderCompileOption ) ) + { + // ピクセルシェーダの作成 + this.bs_PixelShader = new SharpDX.Direct3D11.PixelShader( this.bs_D3DDevice, pBlosPS ); + } + //---------------- + #endregion + #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, + StructureByteStride = 0, + }; + // 定数バッファの作成 + cBufferDesc.SizeInBytes = SharpDX.Utilities.SizeOf(); // バッファサイズ + this.bs_ConstantBuffer = new SharpDX.Direct3D11.Buffer( this.bs_D3DDevice, cBufferDesc ); + //---------------- + #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; + + // ブレンド・ステート・オブジェクトの作成 + this.bs_BlendState = new SharpDX.Direct3D11.BlendState( this.bs_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, + }; + // ラスタライザ・ステート・オブジェクトの作成 + this.bs_RasterizerState = new SharpDX.Direct3D11.RasterizerState( this.bs_D3DDevice, RSDesc ); + //---------------- + #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_DepthStencilState = new SharpDX.Direct3D11.DepthStencilState( this.bs_D3DDevice, DepthSencil ); + //---------------- + #endregion + #region " シェーダーリソースビュー " + //---------------- + this.bs_ShaderResourceView = FDK.Utilities.CreateShaderResourceViewFromFile( this.D3DDevice, "テスト用テクスチャ画像.jpg", out this.ShaderResourceViewSize ); + //D3DX11CreateShaderResourceViewFromFile( g_pD3DDevice, L"texture.png", NULL, NULL, &g_pTextureSRV, &hr ); + //---------------- + #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, + }; + this.bs_SamplerState = new SharpDX.Direct3D11.SamplerState( this.bs_D3DDevice, descSampler ); + //---------------- + #endregion + #region " リソースの種類 " + //---------------- + using( var pResource = this.bs_ShaderResourceView.Resource ) + { + var type = pResource.Dimension; + + switch( type ) + { + case SharpDX.Direct3D11.ResourceDimension.Texture1D: + // 1次元テクスチャの処理 + using( var pTexture1D = pResource.QueryInterface() ) + { + var desc = pTexture1D.Description; + Trace.WriteLine( $"1DTexture Width={desc.Width}" ); + } + break; + + case SharpDX.Direct3D11.ResourceDimension.Texture2D: + // 2次元テクスチャの処理 + using( var pTexture2D = pResource.QueryInterface() ) + { + var desc = pTexture2D.Description; + Trace.WriteLine( $"1DTexture Width={desc.Width} Height={desc.Height}" ); + } + break; + + case SharpDX.Direct3D11.ResourceDimension.Texture3D: + // 3次元テクスチャの処理 + using( var pTexture3D = pResource.QueryInterface() ) + { + var desc = pTexture3D.Description; + Trace.WriteLine( $"1DTexture Width={desc.Width} Height={desc.Height} Depth={desc.Depth}" ); + } + break; + + default: + Trace.WriteLine( "UNKNOWN or BUFFER Resource" ); + break; + } + } + //---------------- + #endregion + + this.バックバッファを初期化する(); + } + public void バックバッファを初期化する() + { + // バックバッファを取得 + using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain( this.bs_SwapChain, 0 ) ) + { + #region " RenderTargetView の作成 " + //---------------- + this.bs_RenderTargetView = new SharpDX.Direct3D11.RenderTargetView( this.bs_D3DDevice, backBuffer ); + //---------------- + #endregion + #region " 深度ステンシルテクスチャの作成 " + //---------------- + var descDepth = backBuffer.Description; + //descDepth.Width = backBuffer.Description.Width; // 幅 + //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_DepthStencil = 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_DepthStencilView = new SharpDX.Direct3D11.DepthStencilView( + this.bs_D3DDevice, + this.bs_DepthStencil, + descDSV ); + //---------------- + #endregion + #region " ビューポートの設定 " + //---------------- + this.bs_ViewPort[ 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 + + FDK.メディア.テクスチャ.共有リソースを作成する(); + } + } + public void デバイスリソースを解放する() + { + // デバイスステートのクリア + this.bs_D3DDevice?.ImmediateContext?.ClearState(); + + // スワップ チェインをウインドウ モードにする + this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null ); + + // 取得したインターフェイスの開放 + FDK.メディア.テクスチャ.共有リソースを解放する(); + this.bs_DepthStencilState?.Dispose(); + this.bs_DepthStencilView?.Dispose(); + this.bs_DepthStencil?.Dispose(); + this.RenderTargetView?.Dispose(); + this.bs_SamplerState?.Dispose(); + this.bs_ShaderResourceView?.Dispose(); + this.bs_RasterizerState?.Dispose(); + this.bs_BlendState?.Dispose(); + this.bs_ConstantBuffer?.Dispose(); + this.bs_PixelShader?.Dispose(); + this.bs_VertexShader?.Dispose(); + this.bs_SwapChain?.Dispose(); + this.bs_D3DDevice?.Dispose(); + } + public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ ) + { + 異常状態なのでアプリを終了せよ = false; + + var 削除理由 = this.bs_D3DDevice.DeviceRemovedReason; + if( 削除理由.Success ) + return; + + 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.DriverInternalError.Code, Info = SharpDX.DXGI.ResultCode.DriverInternalError.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}" ); + + if( エラー詳細.Rebuild ) + { + this.デバイスリソースを解放する(); + this.デバイスリソースを作成する(); + } + else + { + 異常状態なのでアプリを終了せよ = true; + } + } + + private SharpDX.Direct3D11.Device bs_D3DDevice = null; + private SharpDX.DXGI.SwapChain bs_SwapChain = null; + private SharpDX.Direct3D11.RenderTargetView bs_RenderTargetView = null; + private SharpDX.Mathematics.Interop.RawViewportF[] bs_ViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ]; + private SharpDX.Direct3D11.Texture2D bs_DepthStencil = null; + private SharpDX.Direct3D11.DepthStencilView bs_DepthStencilView = null; + private SharpDX.Direct3D11.DepthStencilState bs_DepthStencilState = null; + private SharpDX.Direct3D11.VertexShader bs_VertexShader = null; + private SharpDX.Direct3D11.PixelShader bs_PixelShader = null; + private SharpDX.Direct3D11.Buffer bs_ConstantBuffer = null; + private SharpDX.Direct3D11.BlendState bs_BlendState = null; + private SharpDX.Direct3D11.RasterizerState bs_RasterizerState = null; + private SharpDX.Direct3D11.ShaderResourceView bs_ShaderResourceView = null; + SharpDX.Size2F ShaderResourceViewSize; + private SharpDX.Direct3D11.SamplerState bs_SamplerState = null; + readonly SharpDX.D3DCompiler.ShaderFlags ShaderCompileOption = + SharpDX.D3DCompiler.ShaderFlags.Debug | + SharpDX.D3DCompiler.ShaderFlags.SkipOptimization | + SharpDX.D3DCompiler.ShaderFlags.EnableStrictness | + SharpDX.D3DCompiler.ShaderFlags.PackMatrixColumnMajor; + } +} -- 2.11.0