From f7fe85a7a0d1ee2ca61bd5cc11a39639a99ea03a 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: Mon, 10 Oct 2016 02:17:15 +0900 Subject: [PATCH] =?utf8?q?DPX=E2=86=92PX=E5=A4=89=E6=8F=9B=E3=81=AB?= =?utf8?q?=E5=A4=B1=E6=95=97=E3=81=97=E3=81=A6=E3=81=84=E3=81=9F=E3=83=9F?= =?utf8?q?=E3=82=B9=E3=82=92=E4=BF=AE=E6=AD=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- FDK24/ApplicationBase.cs | 64 +- FDK24/メディア/テクスチャ.cs | 11 +- FDK24/メディア/テクスチャフォント.cs | 6 +- FDK24/メディア/デバイスリソース.cs | 643 +++++++++++---------- .../ビットマップ付きテクスチャ.cs | 4 +- FDK24/メディア/動画.cs | 48 +- FDK24/メディア/描画可能画像.cs | 3 +- FDK24/メディア/文字列画像.cs | 12 +- FDK24/メディア/画像.cs | 20 +- StrokeStyleT/StrokeStyleT.cs | 20 +- .../タイトル/タイトルステージ.cs | 2 +- StrokeStyleT/ステージ/ドラムセット.cs | 26 +- StrokeStyleT/ステージ/フェードアウト.cs | 11 +- StrokeStyleT/ステージ/フェードイン.cs | 11 +- .../ログイン/ログインステージ.cs | 4 + .../曲読込/曲読込ステージ.cs | 4 + .../ステージ/演奏/コンボジャンプ.cs | 8 +- .../ステージ/演奏/スクロール譜面.cs | 28 +- .../演奏/ヒットレーン種別.cs | 2 +- .../演奏/ヒット判定文字列.cs | 76 ++- .../ステージ/演奏/レーンフレーム.cs | 2 +- StrokeStyleT/ステージ/演奏/回転羽.cs | 23 +- .../ステージ/演奏/演奏ステージ.cs | 30 +- .../ステージ/起動/起動ステージ.cs | 14 +- .../ステージ/選曲/曲パネルビュー.cs | 6 +- .../ステージ/選曲/選曲ステージ.cs | 4 +- StrokeStyleT/ユーザ/ユーザ管理.cs | 2 +- StrokeStyleT/曲/MusicNode.cs | 4 +- StrokeStyleT/曲/Node.cs | 4 +- StrokeStyleT/曲/タイトルテクスチャ.cs | 6 +- 30 files changed, 581 insertions(+), 517 deletions(-) diff --git a/FDK24/ApplicationBase.cs b/FDK24/ApplicationBase.cs index ad3001e..63c7434 100644 --- a/FDK24/ApplicationBase.cs +++ b/FDK24/ApplicationBase.cs @@ -91,7 +91,7 @@ namespace FDK // 以下は実装例。 //---------------- Debug.Assert( null == this.スレッド排他領域.デバイスリソース, "デバイスリソースの作成前であること。" ); - this.設計画面サイズdpx = new SharpDX.Size2F( 640, 480 ); // 例。 + this.設計画面サイズdpx = new SharpDX.Size2F( 640, 480 ); } protected virtual void 終了する() { @@ -144,29 +144,47 @@ namespace FDK FDK.Log.現在のスレッドに名前をつける( "GUI" ); FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" ); - FDK.Log.BeginInfo( "派生クラスを初期化します。" ); - this.初期化する(); - Debug.Assert( SharpDX.Size2F.Empty != this.設計画面サイズdpx, "初期化メソッド内で設計画面サイズを設定してあること。" ); - FDK.Log.Info( $"設計画面サイズ: {this.設計画面サイズdpx}" ); - FDK.Log.Info( $"物理画面サイズ: {this.Window.ClientSize}" ); - FDK.Log.EndInfo( "派生クラスを初期化しました。" ); + try + { + FDK.Log.BeginInfo( "派生クラスを初期化します。" ); + this.初期化する(); + Debug.Assert( SharpDX.Size2F.Empty != this.設計画面サイズdpx, "初期化メソッド内で設計画面サイズを設定してあること。" ); + FDK.Log.Info( $"設計画面サイズ: {this.設計画面サイズdpx}" ); + FDK.Log.Info( $"物理画面サイズ: {this.Window.ClientSize}" ); + } + finally + { + FDK.Log.EndInfo( "派生クラスを初期化しました。" ); + } - FDK.Log.BeginInfo( "デバイスリソースを作成します。" ); - this.スレッド排他領域.WriteLock( () => { - this.スレッド排他領域.デバイスリソース = new メディア.デバイスリソース(); - this.スレッド排他領域.デバイスリソース.設計画面サイズdpx = this.設計画面サイズdpx; - this.スレッド排他領域.デバイスリソース.すべてのリソースを作成する( this.Window.ClientSize, this.Window.Handle ); - } ); - FDK.Log.EndInfo( "デバイスリソースを作成しました。" ); - - FDK.Log.BeginInfo( "進行描画スレッドを開始します。" ); - this.進行描画スレッド = new System.Threading.Thread( this.進行描画スレッド処理 ) { - Name = "進行描画スレッド", - Priority = System.Threading.ThreadPriority.AboveNormal, // 優先度: やや高 - }; - this.進行描画スレッド.Start(); - this.スレッド排他領域.進行描画スレッド生存中.ONになるまでブロックする(); - FDK.Log.EndInfo( "進行描画スレッドを開始しました。" ); + try + { + FDK.Log.BeginInfo( "デバイスリソースを作成します。" ); + this.スレッド排他領域.WriteLock( () => { + this.スレッド排他領域.デバイスリソース = new メディア.デバイスリソース(); + this.スレッド排他領域.デバイスリソース.設計画面サイズdpx = this.設計画面サイズdpx; + this.スレッド排他領域.デバイスリソース.すべてのリソースを作成する( this.Window.ClientSize, this.Window.Handle ); + } ); + } + finally + { + FDK.Log.EndInfo( "デバイスリソースを作成しました。" ); + } + + try + { + FDK.Log.BeginInfo( "進行描画スレッドを開始します。" ); + this.進行描画スレッド = new System.Threading.Thread( this.進行描画スレッド処理 ) { + Name = "進行描画スレッド", + Priority = System.Threading.ThreadPriority.AboveNormal, // 優先度: やや高 + }; + this.進行描画スレッド.Start(); + this.スレッド排他領域.進行描画スレッド生存中.ONになるまでブロックする(); + } + finally + { + FDK.Log.EndInfo( "進行描画スレッドを開始しました。" ); + } FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" ); } diff --git a/FDK24/メディア/テクスチャ.cs b/FDK24/メディア/テクスチャ.cs index 813f3dd..e80a999 100644 --- a/FDK24/メディア/テクスチャ.cs +++ b/FDK24/メディア/テクスチャ.cs @@ -15,7 +15,6 @@ namespace FDK.メディア public float 不透明度 { get; set; } = 1f; public bool 加算合成する { get; set; } = false; public SharpDX.Size2F サイズdpx => this.ShaderResourceViewSize; - public SharpDX.Matrix 等倍スケーリング行列 => SharpDX.Matrix.Scaling( this.サイズdpx.Width, this.サイズdpx.Height, 1f ); public テクスチャ( string 画像ファイルパス, SharpDX.Direct3D11.BindFlags bindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource ) { @@ -94,7 +93,7 @@ namespace FDK.メディア /// テクスチャを描画する。 /// テクスチャは1×1のモデルサイズで表現されており、それにこのワールド行列を適用する。 /// テクスチャ座標(値域0~1)で指定する。 - public void 進行描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null ) + public void 描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null ) { var d3dDevice = (SharpDX.Direct3D11.Device) null; using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) ) @@ -109,10 +108,10 @@ namespace FDK.メディア this.定数バッファの転送元データ.World = ワールド行列変換; // ビュー変換行列 - this.定数バッファの転送元データ.View = dr.ビュー変換行列; + this.定数バッファの転送元データ.View = dr.ビュー変換行列; // 転置済み // 射影変換行列 - this.定数バッファの転送元データ.Projection = dr.射影変換行列; + this.定数バッファの転送元データ.Projection = dr.射影変換行列; // 転置済み // 描画元矩形 if( null == 転送元矩形 ) @@ -204,7 +203,7 @@ namespace FDK.メディア // (2) 全インスタンス共通項目(static) - public static void 共有リソースを作成する( FDK.メディア.デバイスリソース dr ) + public static void 全インスタンスで共有するリソースを作成する( FDK.メディア.デバイスリソース dr ) { var d3dDevice = (SharpDX.Direct3D11.Device) null; using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( dr.DXGIDeviceManager, out d3dDevice ) ) @@ -322,7 +321,7 @@ namespace FDK.メディア #endregion } } - public static void 共有リソースを解放する() + public static void 全インスタンスで共有するリソースを解放する() { FDK.Utilities.解放する( ref テクスチャ.SamplerState ); FDK.Utilities.解放する( ref テクスチャ.RasterizerState ); diff --git a/FDK24/メディア/テクスチャフォント.cs b/FDK24/メディア/テクスチャフォント.cs index b62e35c..6937943 100644 --- a/FDK24/メディア/テクスチャフォント.cs +++ b/FDK24/メディア/テクスチャフォント.cs @@ -48,12 +48,12 @@ namespace FDK.メディア { var 文字矩形 = 有効文字矩形s.ElementAt( i ); - float 中央X = 0f - ( 文字列全体のサイズdpx.Width / 2f ) + 左端dpx + ( 文字矩形.Width / 2f ); + float 中央Xdpx = 0f - ( 文字列全体のサイズdpx.Width / 2f ) + 左端dpx + ( 文字矩形.Width / 2f ); var world = SharpDX.Matrix.Scaling( 文字列全体のサイズdpx.Width, 文字列全体のサイズdpx.Height, 1f ) - * SharpDX.Matrix.Translation( 中央X, 0f, 0f ) + * SharpDX.Matrix.Translation( 中央Xdpx, 0f, 0f ) * 文字列全体のワールド変換行列; - this.文字盤.進行描画する( dr, world, 文字矩形 ); + this.文字盤.描画する( dr, world, 文字矩形 ); 左端dpx += 文字矩形.Width; } diff --git a/FDK24/メディア/デバイスリソース.cs b/FDK24/メディア/デバイスリソース.cs index 1669c73..d15fd99 100644 --- a/FDK24/メディア/デバイスリソース.cs +++ b/FDK24/メディア/デバイスリソース.cs @@ -37,20 +37,20 @@ namespace FDK.メディア 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.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 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.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 ); @@ -58,342 +58,388 @@ namespace FDK.メディア 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 void すべてのリソースを作成する( System.Drawing.Size バックバッファサイズpx, IntPtr ウィンドウハンドル ) { - this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズ.Width, バックバッファサイズ.Height ); - this.ウィンドウハンドル = ウィンドウハンドル; + try + { + FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" ); + + this.物理画面サイズpx = new SharpDX.Size2F( バックバッファサイズpx.Width, バックバッファサイズpx.Height ); + this.ウィンドウハンドル = ウィンドウハンドル; - 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, - Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch, - }; - // 機能レベル - 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をサポートするなら必須。 + #region " D2DFactory2 を作成する。" + //----------------- + { + var デバッグレベル = SharpDX.Direct2D1.DebugLevel.None; #if DEBUG - // D3D11 Debugメッセージは、プロジェクトプロパティで「ネイティブコードのデバッグを有効にする」を ON にしないと表示されないので注意。 - creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.Debug; + // プロジェクトがデバッグビルドに含まれている場合は、Direct2D デバッグレイヤーを SDK レイヤーを介して有効にする。 + デバッグレベル = SharpDX.Direct2D1.DebugLevel.Information; #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 " デバイスからデバッグオブジェクトを取得する。" - //---------------- - this.bs_D3DDeviceDebug = d3dDevice.QueryInterfaceOrNull(); - //---------------- + this.bs_D2DFactory2 = new SharpDX.Direct2D1.Factory2( SharpDX.Direct2D1.FactoryType.SingleThreaded, デバッグレベル ); + } + //----------------- #endregion - #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) " + #region " DWriteFactory を作成する。" //----------------- - using( var videoDevice = d3dDevice.QueryInterfaceOrNull() ) - { - if( null == videoDevice ) - throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" ); - } + this.bs_DWriteFactory = new SharpDX.DirectWrite.Factory( SharpDX.DirectWrite.FactoryType.Shared ); //----------------- #endregion - #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。" + #region " WicImagingFactory2 を作成する。" //----------------- - using( var multithread = d3dDevice.QueryInterfaceOrNull() ) - { - if( null == multithread ) - throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" ); - - multithread.SetMultithreadProtected( true ); - } + this.bs_WicImagingFactory2 = new SharpDX.WIC.ImagingFactory2(); //----------------- #endregion - #region " DXGIデバイスマネージャに D3Dデバイスを登録する。" + + var d3dDevice = (SharpDX.Direct3D11.Device) null; + + #region " DXGIDeviceManager を作成する。" //----------------- - this.DXGIDeviceManager.ResetDevice( d3dDevice ); + this.bs_DXGIDeviceManager = new SharpDX.MediaFoundation.DXGIDeviceManager(); //----------------- #endregion - #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。" + #region " D3Dデバイス、スワップチェーンを作成する。" //---------------- - using( var factory = this.bs_SwapChain.GetParent() ) - { - factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll ); - } + // スワップチェーン 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, + Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch, + }; + // 機能レベル + 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をサポートするなら BgraSupport フラグが必須。 +#if DEBUG + // D3D11 Debugメッセージは、プロジェクトプロパティで「ネイティブコードのデバッグを有効にする」を ON にしないと表示されないので注意。 + 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 - } - this.サイズに依存するリソースを作成する(); - } - public void すべてのリソースを解放する() - { - // D3D 関連 - this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null ); // スワップチェインをウインドウモードにする。 - this.サイズに依存するリソースを解放する(); - - 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 ); - - this.bs_D3DDeviceDebug?.ReportLiveDeviceObjects( SharpDX.Direct3D11.ReportingLevel.Detail ); - FDK.Utilities.解放する( ref this.bs_D3DDeviceDebug ); - } - public void Dispose() => this.すべてのリソースを解放する(); - 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.AllowModeSwitch ); - //---------------- - #endregion - - using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain( this.bs_SwapChain, 0 ) ) - { - var d3dDevice = (SharpDX.Direct3D11.Device) null; - using( var d3dLock = new FDK.同期.AutoD3DDeviceLock( this.DXGIDeviceManager, out d3dDevice ) ) using( d3dDevice ) { // D3D 関連 - #region " RenderTargetView の作成 " - //---------------- - this.bs_D3DRenderTargetView = new SharpDX.Direct3D11.RenderTargetView( d3dDevice, backBuffer ); - //---------------- - #endregion - #region " 深度ステンシルテクスチャの作成 " + + #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 ); + this.bs_D3DDeviceDebug = d3dDevice.QueryInterfaceOrNull(); //---------------- #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 ); - //---------------- + #region " D3DDevice が ID3D11VideoDevice を実装してないならエラー。(Win8以降のPCでは実装されているはず。) " + //----------------- + using( var videoDevice = d3dDevice.QueryInterfaceOrNull() ) + { + if( null == videoDevice ) + throw new FDKException( "Direct3D11デバイスが、ID3D11VideoDevice をサポートしていません。" ); + } + //----------------- #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 ); - //---------------- + #region " マルチスレッドモードを ON に設定する。DXVAを使う場合は必須。" + //----------------- + using( var multithread = d3dDevice.QueryInterfaceOrNull() ) + { + if( null == multithread ) + throw new FDKException( "Direct3D11デバイスが、ID3D10Multithread をサポートしていません。" ); + + multithread.SetMultithreadProtected( true ); + } + //----------------- #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, - }; - //---------------- + #region " DXGIデバイスマネージャに D3Dデバイスを登録する。" + //----------------- + this.DXGIDeviceManager.ResetDevice( d3dDevice ); + //----------------- #endregion - #region " テクスチャの共有リソースの作成 " + #region " すべての Windows イベントを無視する。具体的には PrintScreen と Alt+Enter 。" //---------------- - FDK.メディア.テクスチャ.共有リソースを作成する( this ); + using( var factory = this.bs_SwapChain.GetParent() ) + { + factory.MakeWindowAssociation( ウィンドウハンドル, SharpDX.DXGI.WindowAssociationFlags.IgnoreAll ); + } //---------------- #endregion + } - // D2D 関連 - using( var backsurface = SharpDX.DXGI.Surface.FromSwapChain( this.bs_SwapChain, 0 ) ) - { - #region " D2DDevice を作成する。" - //----------------- - using( var dxgiDevice = d3dDevice.QueryInterfaceOrNull() ) - { - if( null == dxgiDevice ) - throw new FDKException( "Direct3D11デバイスが、IDXGIDevice3 をサポートしていません。" ); + this.サイズに依存するリソースを作成する(); + } + finally + { + FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" ); + } + } + public void すべてのリソースを解放する() + { + try + { + FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" ); - this.bs_D2DDevice1 = new SharpDX.Direct2D1.Device1( this.D2DFactory2, dxgiDevice ); - } - //----------------- - #endregion - #region " D2Dの既定のコンテキスト D2DContext1 を作成する。" - //----------------- - this.bs_D2DContext1 = new SharpDX.Direct2D1.DeviceContext1( this.D2DDevice1, SharpDX.Direct2D1.DeviceContextOptions.None ); + // D3D 関連 + this.bs_SwapChain?.SetFullscreenState( fullscreen: false, targetRef: null ); // スワップチェインをウインドウモードにする。 + this.サイズに依存するリソースを解放する(); + + 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 ); + + 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.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.AllowModeSwitch ); + //---------------- + #endregion - // 現在のディスプレイDPI を取得し、D2DContext に設定する。 - this.D2DContext1.DotsPerInch = this.D2DFactory2.DesktopDpi; - //----------------- + // バックバッファを使って、D3D / D2D 関連のリソースを作成する。 + using( var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain( this.bs_SwapChain, 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 " 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 ) ); - - // ここで設定する。 - this.D2DContext1.Target = this.bs_D2DRenderTargetBitmap; - //----------------- + #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 " テキストのアンチエイリアシングを設定する。Grayscale が、すべての Windows ストアアプリで推奨される。" - //----------------- - this.D2DContext1.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale; - //----------------- + #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_SwapChain, 0 ) ) + { + #region " D2DDevice を作成する。" + //----------------- + using( var dxgiDevice = d3dDevice.QueryInterfaceOrNull() ) + { + 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; + //----------------- + #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 ) ) - using( d3dDevice ) - using( var d3dContext = d3dDevice.ImmediateContext ) + try { - d3dContext.ClearState(); - d3dContext.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 ); + + // 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(); - FDK.メディア.テクスチャ.共有リソースを解放する(); + 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 ); → スワップチェーンは解放しない(生成・解放はデバイスとセット)。 + 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 ); + // (0,0)は、サイズ依存リソース無効の印。 + this.物理画面サイズpx = new SharpDX.Size2F( 0, 0 ); + } + } + finally + { + FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" ); } } public void D3Dデバイスが消失していれば再構築する( out bool 異常状態なのでアプリを終了せよ ) @@ -407,8 +453,9 @@ namespace FDK.メディア { 削除理由 = d3dDevice.DeviceRemovedReason; } + if( 削除理由.Success ) - return; + return; // デバイスは消失していない。 var エラー詳細 = new[] { new { Code = SharpDX.DXGI.ResultCode.DeviceHung.Code, Info = SharpDX.DXGI.ResultCode.DeviceHung.ApiCode, Rebuild = true }, diff --git a/FDK24/メディア/ビットマップ付きテクスチャ.cs b/FDK24/メディア/ビットマップ付きテクスチャ.cs index e939dfb..c57ea44 100644 --- a/FDK24/メディア/ビットマップ付きテクスチャ.cs +++ b/FDK24/メディア/ビットマップ付きテクスチャ.cs @@ -22,7 +22,7 @@ namespace FDK.メディア // テクスチャを作成する。 base.Onデバイス依存リソースの作成( dr ); - // 作成したテクスチャとデータを共有するビットマップを作成する。 + // 作成したテクスチャとデータを共有するビットマップターゲットを作成する。 using( var dxgiSurface = this.Texture.QueryInterfaceOrNull() ) { var bmpProp = new SharpDX.Direct2D1.BitmapProperties1() { @@ -34,7 +34,7 @@ namespace FDK.メディア } protected override void Onデバイス依存リソースの解放( デバイスリソース dr ) { - // ビットマップを解放する。 + // ビットマップターゲットを解放する。 FDK.Utilities.解放する( ref this.BitmapTarget ); // テクスチャを解放する。 diff --git a/FDK24/メディア/動画.cs b/FDK24/メディア/動画.cs index 0f3ef42..dcc6dd7 100644 --- a/FDK24/メディア/動画.cs +++ b/FDK24/メディア/動画.cs @@ -29,7 +29,7 @@ namespace FDK.メディア this.前フレームの時刻 = FDK.カウンタ.QPCTimer.未使用; this.ループした際の先頭時刻 = 0; - string 変数付きファイルパス = フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this.動画ファイルパス ); + string 変数付きファイルパス = フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this.動画ファイルパス ); // Log出力用。 var result = SharpDX.Result.Ok; try { @@ -112,7 +112,7 @@ namespace FDK.メディア { // フォーマットを部分メディアタイプの属性に設定。 mediaType.Set( SharpDX.MediaFoundation.MediaTypeAttributeKeys.MajorType, SharpDX.MediaFoundation.MediaTypeGuids.Video ); - mediaType.Set( SharpDX.MediaFoundation.MediaTypeAttributeKeys.Subtype, SharpDX.MediaFoundation.VideoFormatGuids.Argb32 ); // ARGB32 フォーマットで固定。 + mediaType.Set( SharpDX.MediaFoundation.MediaTypeAttributeKeys.Subtype, SharpDX.MediaFoundation.VideoFormatGuids.Argb32 ); // ARGB32 フォーマットで固定。SourceReaderEx を使わない場合、H264 では NV12 しか選べないので注意。 // 部分メディアタイプを SourceReaderEx にセットする。SourceReaderEx は、必要なデコーダをロードするだろう。 this.SourceReaderEx.SetCurrentMediaType( SharpDX.MediaFoundation.SourceReaderIndex.FirstVideoStream, mediaType ); @@ -196,19 +196,19 @@ namespace FDK.メディア #region " デコードの前処理を行う。" //---------------- this.デコードキャッシング(); - Log.Info( $"{Utilities.現在のメソッド名}: 動画のセットアップを行いました。[{変数付きファイルパス}]" ); + Log.Info( $"{Utilities.現在のメソッド名}: 動画のセットアップ(フレームキャッシング)を行いました。[{変数付きファイルパス}]" ); //---------------- #endregion // 準備完了。以降は、サンプルを読み込みたいときに、適宜 ReadSample() する。 - // コールバックを使っていないので、IMFSourceReader::ReadSample() はサンプルが用意できるまでブロックすることに注意。 + // コールバックを使っていない(非同期である)ので、IMFSourceReader::ReadSample() はサンプルが用意できるまでブロックすることに注意。 } finally { if( result.Failure ) this.全リソースを解放する(); - // 失敗しても、一応活性化は成功とする。(進行描画はされない。) + //this.活性化していない = true; --> 失敗しても、一応活性化は成功とする。(進行描画はしない。) } } protected override void Onデバイス依存リソースの解放( デバイスリソース dr ) @@ -220,14 +220,16 @@ namespace FDK.メディア System.Threading.Thread.Sleep( 500 ); this.全リソースを解放する(); + Log.Info( $"{Utilities.現在のメソッド名}: 動画を解放しました。[{フォルダ.絶対パスに含まれるフォルダ変数を展開して返す( this.動画ファイルパス )}]" ); } public void 進行描画する( デバイスリソース dr, SharpDX.RectangleF 描画先矩形dpx, float 不透明度0to1 = 1.0f, bool ループ再生する = false ) { // Direct2D の行列は、設計単位じゃなく物理単位で計算するので注意。 - var 変換行列2Dpx = SharpDX.Matrix3x2.Identity - * SharpDX.Matrix3x2.Scaling( 描画先矩形dpx.Width / this.サイズdpx.Width, 描画先矩形dpx.Height / this.サイズdpx.Height ) // スケーリング。 - * dr.行列を単位変換するDPXtoPX( SharpDX.Matrix3x2.Translation( 描画先矩形dpx.Left, 描画先矩形dpx.Top ) ); // 平行移動(物理単位)、 + var 変換行列2Dpx = + dr.拡大行列DPXtoPX // スケーリング(1) DPX → PX + * SharpDX.Matrix3x2.Scaling( 描画先矩形dpx.Width / this.サイズdpx.Width, 描画先矩形dpx.Height / this.サイズdpx.Height ) // スケーリング(2) + * SharpDX.Matrix3x2.Translation( 描画先矩形dpx.Left * dr.拡大率DPXtoPX横方法, 描画先矩形dpx.Top * dr.拡大率DPXtoPX縦方向 ); // 平行移動(物理単位)、 // 描画する。 this.進行描画する( dr, 変換行列2Dpx ); @@ -330,9 +332,9 @@ namespace FDK.メディア #endregion #region " サンプルバッファをロックする。" //----------------- - byte[] scanLine0_bp = new byte[ 8 ]; // 生ポインタが格納される。32bitなら[0~3]、64bitなら[0~7]が有効。(CPUではなく.NETに依存) + byte[] scanLine0_bp = new byte[ 8 ]; // 「生ポインタ」が格納される。32bitなら[0~3]、64bitなら[0~7]が有効。(CPUではなく.NETに依存) int pitch = 0; - byte[] bufferStart_bp = new byte[ 8 ]; // 生ポインタが格納される。詳細は同上だが、ここでは受け取るだけで何もしない。 + byte[] bufferStart_bp = new byte[ 8 ]; // 「生ポインタ」が格納される。こちらは使わない。 int bufferLength; try { @@ -414,7 +416,6 @@ namespace FDK.メディア //----------------- try { - this.D2Dビットマップ?.Dispose(); this.D2Dビットマップ = SharpDX.Direct2D1.Bitmap.FromWicBitmap( dr.D2DContext1, this.WICビットマップ ); @@ -466,8 +467,7 @@ namespace FDK.メディア // 変換行列とブレンドモードを設定する。 dr.D2DContext1.Transform = 変換行列2Dpx; - dr.D2DContext1.PrimitiveBlend = - ( this.加算合成 ) ? SharpDX.Direct2D1.PrimitiveBlend.Add : SharpDX.Direct2D1.PrimitiveBlend.SourceOver; + dr.D2DContext1.PrimitiveBlend = ( this.加算合成 ) ? SharpDX.Direct2D1.PrimitiveBlend.Add : SharpDX.Direct2D1.PrimitiveBlend.SourceOver; // D2Dビットマップを描画する。 dr.D2DContext1.DrawBitmap( this.D2Dビットマップ, this.不透明度0to1, SharpDX.Direct2D1.InterpolationMode.Linear ); @@ -491,21 +491,21 @@ namespace FDK.メディア this.LastSharpDXResult = SharpDX.Result.Ok; try { - var streamFlags = SharpDX.MediaFoundation.SourceReaderFlags.None; + var ストリームフラグ = SharpDX.MediaFoundation.SourceReaderFlags.None; long サンプルの時刻 = 0; #region " SourceReader から次のサンプル(フレーム)を1つ取得する。" //----------------- { - int actualStreamIndex = 0; + int 実ストリーム番号 = 0; try { this.Sample?.Dispose(); this.Sample = this.SourceReaderEx.ReadSample( SharpDX.MediaFoundation.SourceReaderIndex.FirstVideoStream, SharpDX.MediaFoundation.SourceReaderControlFlags.None, - out actualStreamIndex, - out streamFlags, + out 実ストリーム番号, + out ストリームフラグ, out サンプルの時刻 ); } catch( SharpDX.SharpDXException e ) @@ -519,7 +519,7 @@ namespace FDK.メディア #endregion #region " 取得結果フラグに応じて、必要な処理があれば行なう。" //--------------------------------------------------- - if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Endofstream ) ) // BOX化コストとか気にしない + if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Endofstream ) ) // BOX化コストとか気にしない { #region " ストリーム終了 " //---------------- @@ -543,27 +543,27 @@ namespace FDK.メディア //---------------- #endregion } - else if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Newstream ) ) + else if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Newstream ) ) { // 未対応。 } - else if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Nativemediatypechanged ) ) + else if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Nativemediatypechanged ) ) { // 未対応。 } - else if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Currentmediatypechanged ) ) + else if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Currentmediatypechanged ) ) { // 未対応。 } - else if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.StreamTick ) ) + else if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.StreamTick ) ) { // 未対応。 } - else if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.AllEffectsremoved ) ) + else if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.AllEffectsremoved ) ) { // 未対応。 } - else if( streamFlags.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Error ) ) + else if( ストリームフラグ.HasFlag( SharpDX.MediaFoundation.SourceReaderFlags.Error ) ) { #region " エラー " //---------------- diff --git a/FDK24/メディア/描画可能画像.cs b/FDK24/メディア/描画可能画像.cs index c561cad..d99ee85 100644 --- a/FDK24/メディア/描画可能画像.cs +++ b/FDK24/メディア/描画可能画像.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace FDK.メディア { /// - /// 画像ファイルから生成され、レンダーターゲットとしても描画可能な Bitmap を扱うクラス。 + /// 画像ファイルから生成され、レンダーターゲットとしても描画可能なビットマップを扱うクラス。 /// public class 描画可能画像 : FDK.メディア.画像 { @@ -39,6 +39,7 @@ namespace FDK.メディア { try { + dr.D2DContextの設定をリセットする( dr.D2DContext1 ); dr.D2DContext1.Target = this.Bitmap; FDK.Utilities.D2DBatchDraw( dr.D2DContext1, () => { 描画アクション( dr.D2DContext1, this.Bitmap ); diff --git a/FDK24/メディア/文字列画像.cs b/FDK24/メディア/文字列画像.cs index 8cb4ac7..43d7b00 100644 --- a/FDK24/メディア/文字列画像.cs +++ b/FDK24/メディア/文字列画像.cs @@ -35,9 +35,8 @@ namespace FDK.メディア } protected override void Onデバイス依存リソースの作成( デバイスリソース dr ) { - //FDK.Log.Info( $"{FDK.Utilities.現在のメソッド名}: 文字列ビットマップを生成します。" ); - this.前回の表示文字列 = null; + if( this.表示文字列.Nullでも空でもない() ) { this.ビットマップを生成する( dr ); @@ -51,8 +50,6 @@ namespace FDK.メディア FDK.Utilities.解放する( ref this.ビットマップレンダーターゲット ); FDK.Utilities.解放する( ref this.テキストレイアウト ); FDK.Utilities.解放する( ref this.テキストフォーマット ); - - //FDK.Log.Info( $"{FDK.Utilities.現在のメソッド名}: 文字列ビットマップを解放しました。" ); } public void 進行描画する( デバイスリソース dr, @@ -63,9 +60,10 @@ namespace FDK.メディア float Y方向拡大率 = 1.0f, SharpDX.Matrix? 変換行列3Dpx = null ) { - var 変換行列2Dpx = SharpDX.Matrix3x2.Identity - * SharpDX.Matrix3x2.Scaling( X方向拡大率, Y方向拡大率 ) // スケーリング - * dr.行列を単位変換するDPXtoPX( SharpDX.Matrix3x2.Translation( 左位置dpx, 上位置dpx ) ); // 平行移動(物理単位)。 + var 変換行列2Dpx = + dr.拡大行列DPXtoPX // スケーリング(1) DPX → PX + * SharpDX.Matrix3x2.Scaling( X方向拡大率, Y方向拡大率 ) // スケーリング(2) + * SharpDX.Matrix3x2.Translation( 左位置dpx * dr.拡大率DPXtoPX横方法, 上位置dpx * dr.拡大率DPXtoPX縦方向 ); // 平行移動(物理単位)。 this.進行描画する( dr, 変換行列2Dpx, 変換行列3Dpx, 不透明度0to1 ); } diff --git a/FDK24/メディア/画像.cs b/FDK24/メディア/画像.cs index e502964..6415041 100644 --- a/FDK24/メディア/画像.cs +++ b/FDK24/メディア/画像.cs @@ -12,7 +12,7 @@ namespace FDK.メディア /// /// 画像は、設計単位で作成される。 /// - public SharpDX.Size2F サイズdpx => new SharpDX.Size2F( (float) this.Bitmap.PixelSize.Width, (float) this.Bitmap.PixelSize.Height ); + public SharpDX.Size2F サイズdpx => ( new SharpDX.Size2F( (float) this.Bitmap.PixelSize.Width, (float) this.Bitmap.PixelSize.Height ) ); // あまり頻繁に変更されないであろう描画パラメータは、メソッド引数ではなくプロパティにしておく。 public SharpDX.Direct2D1.InterpolationMode 補正モード { get; set; } = SharpDX.Direct2D1.InterpolationMode.Linear; @@ -29,9 +29,6 @@ namespace FDK.メディア protected override void Onデバイス依存リソースの解放( デバイスリソース dr ) { FDK.Utilities.解放する( ref this.Bitmap ); - - string 変数付きファイルパス = フォルダ.絶対パスをフォルダ変数付き絶対パスに変換して返す( this.画像ファイルパス ); - //Log.Info( $"{Utilities.現在のメソッド名}: 画像を解放しました。[{変数付きファイルパス}]" ); } /// @@ -45,7 +42,7 @@ namespace FDK.メディア /// 画像の縦方向の拡大率。 /// 画像の転送元範囲。画像は設計単位で作成されている。 /// 射影行列。Direct2D の仕様により、設計単位ではなく物理単位で構築すること。 - public virtual void 進行描画する( + public virtual void 描画する( FDK.メディア.デバイスリソース dr, float 左位置dpx, float 上位置dpx, @@ -55,11 +52,12 @@ namespace FDK.メディア SharpDX.RectangleF? 転送元矩形dpx = null, SharpDX.Matrix? 変換行列3Dpx = null ) { - var 変換行列2Dpx = SharpDX.Matrix3x2.Identity - * SharpDX.Matrix3x2.Scaling( X方向拡大率, Y方向拡大率 ) // スケーリング。 - * dr.行列を単位変換するDPXtoPX( SharpDX.Matrix3x2.Translation( 左位置dpx, 上位置dpx ) ); // 平行移動(物理単位)。 + var 変換行列2Dpx = + dr.拡大行列DPXtoPX // スケーリング(1) DPX → PX + * SharpDX.Matrix3x2.Scaling( X方向拡大率, Y方向拡大率 ) // スケーリング(2) + * SharpDX.Matrix3x2.Translation( 左位置dpx * dr.拡大率DPXtoPX横方法, 上位置dpx * dr.拡大率DPXtoPX縦方向 ); // 平行移動(物理単位)。 - this.進行描画する( dr, 変換行列2Dpx, 変換行列3Dpx, 不透明度0to1, 転送元矩形dpx ); + this.描画する( dr, 変換行列2Dpx, 変換行列3Dpx, 不透明度0to1, 転送元矩形dpx ); } /// @@ -70,7 +68,7 @@ namespace FDK.メディア /// 射影行列。Direct2D の仕様により、設計単位ではなく物理単位で構築すること。 /// 不透明度。(0:透明~1:不透明) /// 描画する画像範囲。画像は設計単位で作成されている。 - public virtual void 進行描画する( + public virtual void 描画する( FDK.メディア.デバイスリソース dr, SharpDX.Matrix3x2? 変換行列2Dpx = null, SharpDX.Matrix? 変換行列3Dpx = null, @@ -108,7 +106,7 @@ namespace FDK.メディア var sourceFrame = (SharpDX.WIC.BitmapFrameDecode) null; var converter = (SharpDX.WIC.FormatConverter) null; - string 変数付きファイルパス = フォルダ.絶対パスをフォルダ変数付き絶対パスに変換して返す( this.画像ファイルパス ); + string 変数付きファイルパス = フォルダ.絶対パスをフォルダ変数付き絶対パスに変換して返す( this.画像ファイルパス ); // Log出力用 try { #region " 画像ファイルパスの有効性を確認する。" diff --git a/StrokeStyleT/StrokeStyleT.cs b/StrokeStyleT/StrokeStyleT.cs index 90168bb..c0ac9ab 100644 --- a/StrokeStyleT/StrokeStyleT.cs +++ b/StrokeStyleT/StrokeStyleT.cs @@ -44,11 +44,10 @@ namespace SST protected override void 初期化する() { FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" ); - Debug.Assert( null == this.スレッド排他領域.デバイスリソース, "デバイスリソースの作成前であること。" ); this.Window.Text = $"StrokeStyle {System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()}"; - this.設計画面サイズdpx = new SharpDX.Size2F( 1920, 1080 ); // 設計画面サイズdpx + this.設計画面サイズdpx = new SharpDX.Size2F( 1920, 1080 ); // 設計画面サイズdpx(固定) #region " コンフィグ を初期化する。" //---------------- @@ -57,8 +56,11 @@ namespace SST StrokeStyleT.bs_Config.ConfigXmlを読み込む(); //---------------- #endregion - + #region " コンフィグで指定されたウィンドウサイズに変更。" + //---------------- this.Window.ClientSize = new System.Drawing.Size( StrokeStyleT.Config.物理画面サイズpx.Width, StrokeStyleT.Config.物理画面サイズpx.Height ); + //---------------- + #endregion #region " System.Stopwatch が高解像度タイマを使わないならエラー。" //----------------- @@ -152,11 +154,13 @@ namespace SST #endregion #region " WASAPIデバイスを解放する。" //---------------- + FDK.Log.Info( "WASAPIデバイスを解放します。" ); FDK.Utilities.解放する( ref StrokeStyleT.bs_Wasapiデバイス ); //---------------- #endregion #region " コンフィグを解放する。" //---------------- + FDK.Log.Info( "コンフィグを解放します。" ); StrokeStyleT.bs_Config = null; //---------------- #endregion @@ -174,7 +178,7 @@ namespace SST this.スレッド排他領域.WriteLock( () => { - #region " 描画を準備する。" + #region " 描画の準備を行う。" //---------------- var dr = this.スレッド排他領域.デバイスリソース; var d3dDevice = (SharpDX.Direct3D11.Device) null; @@ -195,12 +199,11 @@ namespace SST //---------------- #endregion - // 現在のステージを進行描画する。 this.現在のステージ?.進行描画する( this.スレッド排他領域.デバイスリソース ); } ); - // 表示する。垂直帰線待ちなどで時間がかかるのでロックしないこと。 + // スワップチェーンを表示する。垂直帰線待ちなどで時間がかかるので、この部分はスレッド排他領域の外に配置すること。 if( false == this.スレッド排他領域.アプリを終了せよ ) { this.スレッド排他領域.デバイスリソース.SwapChain.Present( @@ -208,17 +211,16 @@ namespace SST SharpDX.DXGI.PresentFlags.None ); } + // ステージの状態をチェックし、必要あれば遷移またはアプリを終了する。 this.スレッド排他領域.WriteLock( () => { if( null != this.現在のステージ ) { - // ステージの状態チェックを行い、必要あれば遷移、またはアプリを終了する。 switch( this.現在のステージ.GetType().Name ) { case nameof( ステージ.ステージ ): - #region " 最初のダミーステージ " + #region " 最初のダミーステージ → 起動ステージへ。" //---------------- - // 起動ステージへ遷移する。 this.起動ステージ.活性化する( this.スレッド排他領域.デバイスリソース ); this.現在のステージ = this.起動ステージ; //---------------- diff --git a/StrokeStyleT/ステージ/タイトル/タイトルステージ.cs b/StrokeStyleT/ステージ/タイトル/タイトルステージ.cs index 3581cea..82d7e8f 100644 --- a/StrokeStyleT/ステージ/タイトル/タイトルステージ.cs +++ b/StrokeStyleT/ステージ/タイトル/タイトルステージ.cs @@ -36,7 +36,7 @@ namespace SST.ステージ.タイトル return; // 進行・描画。 - this.背景画像.進行描画する( dr, 0.0f, 0.0f ); + this.背景画像.描画する( dr, 0.0f, 0.0f ); // 入力。 diff --git a/StrokeStyleT/ステージ/ドラムセット.cs b/StrokeStyleT/ステージ/ドラムセット.cs index 35c34cc..c4c6fb5 100644 --- a/StrokeStyleT/ステージ/ドラムセット.cs +++ b/StrokeStyleT/ステージ/ドラムセット.cs @@ -49,19 +49,19 @@ namespace SST.ステージ } public void 進行描画する( デバイスリソース dr ) { - this.Bass.進行描画する( dr, 881f, 891f ); - this.LowTom.進行描画する( dr, 999f, 901f ); - this.HiTom.進行描画する( dr, 850f, 901f ); - this.FloorTom.進行描画する( dr, 1050f, 981f ); - this.Snare.進行描画する( dr, 741f, 988f ); - this.HiHatBottom.進行描画する( dr, 657f, 935f ); - this.HiHatTop.進行描画する( dr, 657f, ( 935f - 20f * this.ハイハットの開度 ) ); - this.RCymbalStand.進行描画する( dr, 1229f, 920f ); - this.RCymbal.進行描画する( dr, 1257f - this.RCymbal.サイズdpx.Width / 2f, 923f - this.RCymbal.サイズdpx.Height / 2f ); - this.RCymbalTop.進行描画する( dr, 1229f, 880f ); - this.LCymbalStand.進行描画する( dr, 472f, 916f ); - this.LCymbal.進行描画する( dr, 649f - this.LCymbal.サイズdpx.Width / 2f, 918f - this.LCymbal.サイズdpx.Height / 2f ); - this.LCymbalTop.進行描画する( dr, 633f, 891f ); + this.Bass.描画する( dr, 881f, 891f ); + this.LowTom.描画する( dr, 999f, 901f ); + this.HiTom.描画する( dr, 850f, 901f ); + this.FloorTom.描画する( dr, 1050f, 981f ); + this.Snare.描画する( dr, 741f, 988f ); + this.HiHatBottom.描画する( dr, 657f, 935f ); + this.HiHatTop.描画する( dr, 657f, ( 935f - 20f * this.ハイハットの開度 ) ); + this.RCymbalStand.描画する( dr, 1229f, 920f ); + this.RCymbal.描画する( dr, 1257f - this.RCymbal.サイズdpx.Width / 2f, 923f - this.RCymbal.サイズdpx.Height / 2f ); + this.RCymbalTop.描画する( dr, 1229f, 880f ); + this.LCymbalStand.描画する( dr, 472f, 916f ); + this.LCymbal.描画する( dr, 649f - this.LCymbal.サイズdpx.Width / 2f, 918f - this.LCymbal.サイズdpx.Height / 2f ); + this.LCymbalTop.描画する( dr, 633f, 891f ); } protected readonly FDK.メディア.画像 HiHatTop; diff --git a/StrokeStyleT/ステージ/フェードアウト.cs b/StrokeStyleT/ステージ/フェードアウト.cs index 4927a8c..c23e816 100644 --- a/StrokeStyleT/ステージ/フェードアウト.cs +++ b/StrokeStyleT/ステージ/フェードアウト.cs @@ -38,12 +38,13 @@ namespace SST.ステージ { for( int y = 0; y < タイル枚数Y; y++ ) { - var 変換行列2Dpx = dr.行列を単位変換するDPXtoPX( - SharpDX.Matrix3x2.Translation( - x * フェードアウトに使うタイル画像.サイズdpx.Width, - y * フェードアウトに使うタイル画像.サイズdpx.Height ) ); + var 変換行列2Dpx = + dr.拡大行列DPXtoPX + * SharpDX.Matrix3x2.Translation( + ( x * フェードアウトに使うタイル画像.サイズdpx.Width ) * dr.拡大率DPXtoPX横方法, + ( y * フェードアウトに使うタイル画像.サイズdpx.Height ) * dr.拡大率DPXtoPX縦方向 ); - フェードアウトに使うタイル画像?.進行描画する( + フェードアウトに使うタイル画像?.描画する( dr, 変換行列2Dpx: 変換行列2Dpx, 変換行列3Dpx: null, diff --git a/StrokeStyleT/ステージ/フェードイン.cs b/StrokeStyleT/ステージ/フェードイン.cs index 5f04849..5d0e7bd 100644 --- a/StrokeStyleT/ステージ/フェードイン.cs +++ b/StrokeStyleT/ステージ/フェードイン.cs @@ -38,12 +38,13 @@ namespace SST.ステージ { for( int y = 0; y < タイル枚数Y; y++ ) { - var 変換行列2Dpx = dr.行列を単位変換するDPXtoPX( - SharpDX.Matrix3x2.Translation( - x * フェードインに使うタイル画像.サイズdpx.Width, - y * フェードインに使うタイル画像.サイズdpx.Height ) ); + var 変換行列2Dpx = + dr.拡大行列DPXtoPX + * SharpDX.Matrix3x2.Translation( + ( x * フェードインに使うタイル画像.サイズdpx.Width ) * dr.拡大率DPXtoPX横方法, + ( y * フェードインに使うタイル画像.サイズdpx.Height ) * dr.拡大率DPXtoPX縦方向 ); - フェードインに使うタイル画像?.進行描画する( + フェードインに使うタイル画像?.描画する( dr, 変換行列2Dpx: 変換行列2Dpx, 変換行列3Dpx: null, diff --git a/StrokeStyleT/ステージ/ログイン/ログインステージ.cs b/StrokeStyleT/ステージ/ログイン/ログインステージ.cs index dbf5afb..e7b5ef3 100644 --- a/StrokeStyleT/ステージ/ログイン/ログインステージ.cs +++ b/StrokeStyleT/ステージ/ログイン/ログインステージ.cs @@ -24,6 +24,10 @@ namespace SST.ステージ.ログイン キャンセル, } public フェーズ 現在のフェーズ { get; protected set; } = フェーズ.初期状態; + + /// + /// ログインしたユーザの、ユーザリストにおけるインデックス番号。 + /// public int ユーザインデックス { get; protected set; } = 0; public ログインステージ() diff --git a/StrokeStyleT/ステージ/曲読込/曲読込ステージ.cs b/StrokeStyleT/ステージ/曲読込/曲読込ステージ.cs index 0507a64..5da0ec7 100644 --- a/StrokeStyleT/ステージ/曲読込/曲読込ステージ.cs +++ b/StrokeStyleT/ステージ/曲読込/曲読込ステージ.cs @@ -20,7 +20,9 @@ namespace SST.ステージ.曲読込 { FDK.Log.Info( "曲読込ステージを開始します。" ); Trace.Assert( null != StrokeStyleT.曲ツリー管理.現在選択されているノード, "[バグあり] 選択曲が null です。" ); + this.現在のフェーズ = フェーズ.読込中; + var 選択曲 = (SST.曲.MusicNode) StrokeStyleT.曲ツリー管理.現在選択されているノード; FDK.Log.Info( $"選択曲「{選択曲.タイトル}」({FDK.フォルダ.絶対パスをフォルダ変数付き絶対パスに変換して返す( 選択曲.sstfファイルパス )})" ); } @@ -45,6 +47,8 @@ namespace SST.ステージ.曲読込 user.Rideは左, user.Chinaは左, user.Splashは左 ); + + // フェーズ終了。 this.現在のフェーズ = フェーズ.終了; break; } diff --git a/StrokeStyleT/ステージ/演奏/コンボジャンプ.cs b/StrokeStyleT/ステージ/演奏/コンボジャンプ.cs index a03296a..5426a8f 100644 --- a/StrokeStyleT/ステージ/演奏/コンボジャンプ.cs +++ b/StrokeStyleT/ステージ/演奏/コンボジャンプ.cs @@ -101,13 +101,11 @@ namespace SST.ステージ.演奏 float y = 下辺Ydpx; int jump = this.ジャンプインデックス値 - ( 桁数 * 桁ごとのジャンプの遅れ ); - // 単位 を表示。 - + // "COMBO" を表示。 x -= COMBO矩形.Width; - this.数値と単位の画像.進行描画する( dr, x, 下辺Ydpx - COMBO矩形.Height, 不透明度0to1: 不透明度0to1, 転送元矩形dpx: COMBO矩形 ); + this.数値と単位の画像.描画する( dr, x, ( 下辺Ydpx - COMBO矩形.Height ), 不透明度0to1, 転送元矩形dpx: COMBO矩形 ); // 数値を1の位から順に表示。 - for( int i = 0; i < 桁数; i++ ) { var rc = this.文字矩形dpx[ 位の数[ i ] ]; @@ -119,7 +117,7 @@ namespace SST.ステージ.演奏 if( ( 0 <= jump ) && ( 180 > jump ) ) y += this.ジャンプ差分値[ jump ]; - this.数値と単位の画像.進行描画する( dr, x, y, 不透明度0to1, 転送元矩形dpx: rc ); + this.数値と単位の画像.描画する( dr, x, y, 不透明度0to1, 転送元矩形dpx: rc ); } //----------------- #endregion diff --git a/StrokeStyleT/ステージ/演奏/スクロール譜面.cs b/StrokeStyleT/ステージ/演奏/スクロール譜面.cs index 9da1860..b29a030 100644 --- a/StrokeStyleT/ステージ/演奏/スクロール譜面.cs +++ b/StrokeStyleT/ステージ/演奏/スクロール譜面.cs @@ -80,7 +80,7 @@ namespace SST.ステージ.演奏 if( this.活性化した直後である ) { this.活性化した直後である = false; - this.描画開始チップ番号 = 0; // 演奏開始。 + this.描画開始チップ番号 = 0; // -1 → 0; 演奏開始。 this.チップアニメ.開始する( 最初の値: 0, 最後の値: 48, 値をひとつ増加させるのにかける時間ms: 10 ); } //---------------- @@ -98,7 +98,7 @@ namespace SST.ステージ.演奏 // チップのY座標を算出し、ループの終了判定を行う。 double y = 座標.判定バーの中央Y座標dpx + 描画距離dpx; - if( y < -40.0 ) // y が画面上端より上に出ていればそこでチップのループ描画は終了。-40 dpx はチップが隠れるであろう適当なマージン。 + if( y < -40.0 ) // y が画面上端より上に出ていればそこでチップのループ描画は終了。-40dpx はチップが隠れるであろう適当なマージン。 break; // チップが描画開始チップであり、かつ、そのY座標が画面下端を超えたなら、描画開始チップ番号を更新する。 @@ -161,7 +161,7 @@ namespace SST.ステージ.演奏 switch( chip.チップ種別 ) { case SSTFormat.チップ種別.小節線: - #region " *** " + #region " 小節線を1本表示する。" //---------------- { float 左位置dpx = 座標.レーンフレーム左端のX座標dpx + this.レーン種別toレーンフレーム左端からの相対X位置dpx[ SSTFormat.レーン種別.LeftCrash ] - 1f; @@ -170,8 +170,8 @@ namespace SST.ステージ.演奏 if( null != 画像範囲orNull ) { var 画像範囲 = (SharpDX.RectangleF) 画像範囲orNull; - this.チップ画像.進行描画する( dr, 左位置dpx, 上位置dpx, 転送元矩形dpx: 画像範囲 ); - this.チップ画像.進行描画する( dr, 左位置dpx + 画像範囲.Width, 上位置dpx, 転送元矩形dpx: 画像範囲 ); + this.チップ画像.描画する( dr, 左位置dpx, 上位置dpx, 転送元矩形dpx: 画像範囲 ); + this.チップ画像.描画する( dr, 左位置dpx + 画像範囲.Width, 上位置dpx, 転送元矩形dpx: 画像範囲 ); } } //---------------- @@ -179,7 +179,7 @@ namespace SST.ステージ.演奏 break; case SSTFormat.チップ種別.拍線: - #region " *** " + #region " 拍線を1本表示する。" //---------------- { float 左位置dpx = 座標.レーンフレーム左端のX座標dpx + this.レーン種別toレーンフレーム左端からの相対X位置dpx[ SSTFormat.レーン種別.LeftCrash ] - 1f; @@ -188,8 +188,8 @@ namespace SST.ステージ.演奏 if( null != 画像範囲orNull ) { var 画像範囲 = (SharpDX.RectangleF) 画像範囲orNull; - this.チップ画像.進行描画する( dr, 左位置dpx: 左位置dpx, 上位置dpx: 上位置dpx, 転送元矩形dpx: 画像範囲 ); - this.チップ画像.進行描画する( dr, 左位置dpx: 左位置dpx + 画像範囲.Width, 上位置dpx: 上位置dpx, 転送元矩形dpx: 画像範囲 ); + this.チップ画像.描画する( dr, 左位置dpx: 左位置dpx, 上位置dpx: 上位置dpx, 転送元矩形dpx: 画像範囲 ); + this.チップ画像.描画する( dr, 左位置dpx: 左位置dpx + 画像範囲.Width, 上位置dpx: 上位置dpx, 転送元矩形dpx: 画像範囲 ); } } //---------------- @@ -203,7 +203,7 @@ namespace SST.ステージ.演奏 return; this.チップ画像.加算合成 = false; - float 音量0to1 = chip.音量 * 0.25f; + float 音量0to1 = chip.音量 * 0.25f; // 1~4 → 0.25~1.00 switch( chip.チップ種別 ) { @@ -314,12 +314,12 @@ namespace SST.ステージ.演奏 var 画像範囲 = (SharpDX.RectangleF) 画像範囲orNull; float チップ1枚の高さdpx = 18f; - 画像範囲.Offset( 0f, this.チップアニメ.現在値 * 15f ); // 下端3dpxは下のチップと共有してるので、18f-3f = 15f。 + 画像範囲.Offset( 0f, this.チップアニメ.現在値 * 15f ); // 下端3dpxは下のチップと共有する前提のデザインなので、18f-3f = 15f。 画像範囲.Height = チップ1枚の高さdpx; float 左位置dpx = 座標.レーンフレーム左端のX座標dpx + this.レーン種別toレーンフレーム左端からの相対X位置dpx[ elane ] - 画像範囲.Width / 2f; float 上位置dpx = Ydpx - ( チップ1枚の高さdpx / 2f ) * 音量0to1; - this.チップ画像.進行描画する( dr, 左位置dpx, 上位置dpx, 転送元矩形dpx: 画像範囲, Y方向拡大率: 音量0to1 ); + this.チップ画像.描画する( dr, 左位置dpx, 上位置dpx, 転送元矩形dpx: 画像範囲, Y方向拡大率: 音量0to1 ); } protected void 単画チップを1つ描画する( デバイスリソース dr, SSTFormat.レーン種別 eLane, SharpDX.RectangleF? 元矩形dpx, float 上位置dpx, float 音量0to1 ) { @@ -327,7 +327,7 @@ namespace SST.ステージ.演奏 return; var 画像範囲dpx = (SharpDX.RectangleF) 元矩形dpx; - this.チップ画像.進行描画する( + this.チップ画像.描画する( dr, 左位置dpx: 座標.レーンフレーム左端のX座標dpx + this.レーン種別toレーンフレーム左端からの相対X位置dpx[ eLane ] - ( 画像範囲dpx.Width / 2f ), 上位置dpx: 上位置dpx - ( ( 画像範囲dpx.Height / 2f ) * 音量0to1 ), @@ -341,8 +341,6 @@ namespace SST.ステージ.演奏 protected Dictionary ヒット判定を行うチップと対応するレーン = null; protected readonly FDK.カウンタ.単純増加後反復カウンタ チップアニメ = new FDK.カウンタ.単純増加後反復カウンタ(); protected readonly Dictionary レーン種別toレーンフレーム左端からの相対X位置dpx = new Dictionary() { - #region " *** " - //---------------- { SSTFormat.レーン種別.LeftCrash, +36f }, { SSTFormat.レーン種別.HiHat, +105f }, { SSTFormat.レーン種別.Foot, +145f }, @@ -352,8 +350,6 @@ namespace SST.ステージ.演奏 { SSTFormat.レーン種別.Tom2, +448f }, { SSTFormat.レーン種別.Tom3, +544f }, { SSTFormat.レーン種別.RightCrash, +632f }, - //---------------- - #endregion }; } } diff --git a/StrokeStyleT/ステージ/演奏/ヒットレーン種別.cs b/StrokeStyleT/ステージ/演奏/ヒットレーン種別.cs index 2ac60b5..353db69 100644 --- a/StrokeStyleT/ステージ/演奏/ヒットレーン種別.cs +++ b/StrokeStyleT/ステージ/演奏/ヒットレーン種別.cs @@ -3,7 +3,7 @@ namespace SST.ステージ.演奏 { /// - /// 判定文字列のレーン種別。SSTFormat.レーン種別とは独立に定義する。 + /// 判定文字列のレーン種別。SSTFormat.レーン種別とはまた微妙に異なるので、独立して定義する。(涙 /// enum ヒットレーン種別 { diff --git a/StrokeStyleT/ステージ/演奏/ヒット判定文字列.cs b/StrokeStyleT/ステージ/演奏/ヒット判定文字列.cs index 761880d..e19b39b 100644 --- a/StrokeStyleT/ステージ/演奏/ヒット判定文字列.cs +++ b/StrokeStyleT/ステージ/演奏/ヒット判定文字列.cs @@ -16,19 +16,17 @@ namespace SST.ステージ.演奏 } public void 表示開始( ヒットレーン種別 レーン種別, ヒット判定種別 ヒット判定種別 ) { - Debug.Assert( this.活性化している ); - if( レーン種別 == ヒットレーン種別.Unknown ) return; // レーンに対応する進行描画コンテキストを更新し、表示を開始するためのパラメータを設定する。 - if( this.ヒット判定レーンto進行描画コンテキスト.ContainsKey( レーン種別 ) ) // すでにあったら - this.ヒット判定レーンto進行描画コンテキスト.Remove( レーン種別 ); // 削除してから + if( this.ヒット判定レーンto進行描画コンテキスト.ContainsKey( レーン種別 ) ) // すでにあったら、 + this.ヒット判定レーンto進行描画コンテキスト.Remove( レーン種別 ); // 削除してから、 this.ヒット判定レーンto進行描画コンテキスト.Add( // 追加。 レーン種別, new 進行描画コンテキスト() { ヒット判定種別 = ヒット判定種別, - 進行カウンタ = new FDK.カウンタ.単純増加後不変カウンタ( 最初の値: 0, 最後の値: 300, 値をひとつ増加させるのにかける時間ms: 1 ), // カウント開始=表示開始 + 進行カウンタ = new FDK.カウンタ.単純増加後不変カウンタ( 最初の値: 0, 最後の値: 300, 値をひとつ増加させるのにかける時間ms: 1 ), // カウント開始(=表示開始) X方向拡大率 = 1f, Y方向拡大率 = 1f, 相対X座標dpx = 0, @@ -38,8 +36,6 @@ namespace SST.ステージ.演奏 } public void 表示開始( SSTFormat.チップ種別 チップ種別, ヒット判定種別 ヒット判定種別 ) { - Debug.Assert( this.活性化している ); - var レーン種別 = チップ種別.対応するヒットレーン種別を返す(); this.表示開始( レーン種別, ヒット判定種別 ); } @@ -53,16 +49,18 @@ namespace SST.ステージ.演奏 } protected override void On非活性化( デバイスリソース dr ) { + this.ヒット判定レーンto進行描画コンテキスト.Clear(); } public void 進行描画する( デバイスリソース dr ) { - // すべての ヒットレーン種別 について進行描画する。 + // すべての ヒットレーン種別 について、進行描画する。 foreach( var lane_object in typeof( ヒットレーン種別 ).GetEnumValues() ) { var lane = (ヒットレーン種別) lane_object; var context = this.ヒット判定レーンto進行描画コンテキスト[ lane ]; + if( context.進行カウンタ.停止中である ) - continue; // このレーンについては何もしない。 + continue; // カウンタが停止中 → このレーンについては何もしない。 // 進行。 @@ -76,22 +74,31 @@ namespace SST.ステージ.演奏 //---------------- #endregion - if( context.ヒット判定種別 == ヒット判定種別.MISS ) + if( context.ヒット判定種別 != ヒット判定種別.MISS ) { - #region " (A) Miss のアニメーション進行だけ他とは違ってたり。" + #region " (A) Perfect, Great, Good, Poor, Auto のアニメーション進行。" //----------------- if( context.進行カウンタ.現在値 < 50 ) { - // (A-a) 0~49 - context.X方向拡大率 = 1.0f; + // (B-a) 0~49 + context.X方向拡大率 = 1.0f + ( 1.0f * ( 1.0f - ( context.進行カウンタ.現在値 / 50.0f ) ) ); context.Y方向拡大率 = context.進行カウンタ.現在値 / 50.0f; context.相対X座標dpx = 0; context.相対Y座標dpx = 0; context.透明度0to1 = 1.0f; } - else if( context.進行カウンタ.現在値 < 200 ) + else if( context.進行カウンタ.現在値 < 130 ) { - // (A-b) 50~199 + // (B-b) 50~129 + context.X方向拡大率 = 1.0f; + context.Y方向拡大率 = 1.0f; + context.相対X座標dpx = 0; + context.相対Y座標dpx = ( ( context.進行カウンタ.現在値 % 6 ) == 0 ) ? ( StrokeStyleT.乱数.Next( 6 ) - 3 ) : context.相対Y座標dpx; + context.透明度0to1 = 1.0f; + } + else if( context.進行カウンタ.現在値 < 240 ) + { + // (B-c) 130~239 context.X方向拡大率 = 1.0f; context.Y方向拡大率 = 1.0f; context.相対X座標dpx = 0; @@ -100,9 +107,9 @@ namespace SST.ステージ.演奏 } else { - // (A-c) 200~300 - context.X方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f ); - context.Y方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f ); + // (B-d) 240~300 + context.X方向拡大率 = 1.0f; + context.Y方向拡大率 = 1.0f - ( ( 1.0f * ( context.進行カウンタ.現在値 - 240 ) ) / 60.0f ); context.相対X座標dpx = 0; context.相対Y座標dpx = 0; context.透明度0to1 = 1.0f; @@ -112,29 +119,20 @@ namespace SST.ステージ.演奏 } else { - #region " (B) Perfect, Great, Good, Poor, Auto のアニメーション進行。" + #region " (B) Miss のアニメーション進行だけ他とは違ってたり。" //----------------- if( context.進行カウンタ.現在値 < 50 ) { - // (B-a) 0~49 - context.X方向拡大率 = 1.0f + ( 1.0f * ( 1.0f - ( context.進行カウンタ.現在値 / 50.0f ) ) ); + // (A-a) 0~49 + context.X方向拡大率 = 1.0f; context.Y方向拡大率 = context.進行カウンタ.現在値 / 50.0f; context.相対X座標dpx = 0; context.相対Y座標dpx = 0; context.透明度0to1 = 1.0f; } - else if( context.進行カウンタ.現在値 < 130 ) - { - // (B-b) 50~129 - context.X方向拡大率 = 1.0f; - context.Y方向拡大率 = 1.0f; - context.相対X座標dpx = 0; - context.相対Y座標dpx = ( ( context.進行カウンタ.現在値 % 6 ) == 0 ) ? ( StrokeStyleT.乱数.Next( 6 ) - 3 ) : context.相対Y座標dpx; - context.透明度0to1 = 1.0f; - } - else if( context.進行カウンタ.現在値 < 240 ) + else if( context.進行カウンタ.現在値 < 200 ) { - // (B-c) 130~239 + // (A-b) 50~199 context.X方向拡大率 = 1.0f; context.Y方向拡大率 = 1.0f; context.相対X座標dpx = 0; @@ -143,9 +141,9 @@ namespace SST.ステージ.演奏 } else { - // (B-d) 240~300 - context.X方向拡大率 = 1.0f; - context.Y方向拡大率 = 1.0f - ( ( 1.0f * ( context.進行カウンタ.現在値 - 240 ) ) / 60.0f ); + // (A-c) 200~300 + context.X方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f ); + context.Y方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f ); context.相対X座標dpx = 0; context.相対Y座標dpx = 0; context.透明度0to1 = 1.0f; @@ -167,7 +165,7 @@ namespace SST.ステージ.演奏 -( ( 判定文字列の画像.サイズdpx.Width * context.X方向拡大率 ) / 2f ), -( ( 判定文字列の画像.サイズdpx.Height * context.Y方向拡大率 ) / 2f ) ); - 判定文字列の画像?.進行描画する( + 判定文字列の画像?.描画する( dr, 左位置dpx: 判定文字列の左上端位置.X, 上位置dpx: 判定文字列の左上端位置.Y, @@ -178,7 +176,7 @@ namespace SST.ステージ.演奏 } /// - /// ヒット判定レーンには、それぞれに1つずつの進行描画コンテキストが存在する。 + /// ヒット判定レーンには、それぞれに1つずつの進行描画コンテキストを用意する。 /// protected class 進行描画コンテキスト { @@ -224,16 +222,12 @@ namespace SST.ステージ.演奏 } protected Dictionary<ヒットレーン種別, 進行描画コンテキスト> ヒット判定レーンto進行描画コンテキスト = null; protected readonly Dictionary<ヒット判定種別, FDK.メディア.画像> 文字列画像 = new Dictionary<ヒット判定種別, 画像>() { - #region " *** " - //---------------- { ヒット判定種別.PERFECT, new 画像( @"$(Static)\images\Judge Perfect.png" ) }, { ヒット判定種別.GREAT, new 画像( @"$(Static)\images\Judge Great.png" ) }, { ヒット判定種別.GOOD, new 画像( @"$(Static)\images\Judge Good.png" ) }, { ヒット判定種別.POOR, new 画像( @"$(Static)\images\Judge Poor.png" ) }, { ヒット判定種別.MISS, new 画像( @"$(Static)\images\Judge Miss.png" ) }, { ヒット判定種別.AUTO, new 画像( @"$(Static)\images\Judge Auto.png" ) }, - //---------------- - #endregion }; } } diff --git a/StrokeStyleT/ステージ/演奏/レーンフレーム.cs b/StrokeStyleT/ステージ/演奏/レーンフレーム.cs index e08b6e1..99a53b2 100644 --- a/StrokeStyleT/ステージ/演奏/レーンフレーム.cs +++ b/StrokeStyleT/ステージ/演奏/レーンフレーム.cs @@ -17,7 +17,7 @@ namespace SST.ステージ.演奏 } public void 進行描画する( デバイスリソース dr ) { - this.レーンフレーム画像.進行描画する( dr, 座標.レーンフレーム左端のX座標dpx, 0f ); + this.レーンフレーム画像.描画する( dr, 座標.レーンフレーム左端のX座標dpx, 0f ); } protected readonly FDK.メディア.画像 レーンフレーム画像; diff --git a/StrokeStyleT/ステージ/演奏/回転羽.cs b/StrokeStyleT/ステージ/演奏/回転羽.cs index e73a764..1d7cd1e 100644 --- a/StrokeStyleT/ステージ/演奏/回転羽.cs +++ b/StrokeStyleT/ステージ/演奏/回転羽.cs @@ -28,7 +28,7 @@ namespace SST.ステージ.演奏 } public void 発火する( SharpDX.Vector2 中央位置dpx ) { - float 角度 = StrokeStyleT.乱数.Next( 360 ); + float 開始角度 = StrokeStyleT.乱数.Next( 360 ); // 羽を、小羽大羽あわせて 8 枚登録。 int i = 0; @@ -39,8 +39,8 @@ namespace SST.ステージ.演奏 if( false == this.コンテキスト[ i ].使用中 ) { this.コンテキスト[ i ].使用中 = true; - this.コンテキスト[ i ].中央位置px = 中央位置dpx; - this.コンテキスト[ i ].回転単位 = SharpDX.MathUtil.DegreesToRadians( 角度 + ( 羽番号 * 90.0f ) ); // 開始角度 = 0, 90, 180, 270, 0, 90, 180, 270 + this.コンテキスト[ i ].中央位置dpx = 中央位置dpx; + this.コンテキスト[ i ].回転開始角度 = SharpDX.MathUtil.DegreesToRadians( 開始角度 + ( 羽番号 * 90.0f ) ); // 回転開始角度 = 0, 90, 180, 270, 0, 90, 180, 270 this.コンテキスト[ i ].回転速度 = ( 羽番号 < 4 ) ? -1.5f : 1.5f; // 小羽と大羽は反対の方向に回転する this.コンテキスト[ i ].サイズ = ( 羽番号 < 4 ) ? 1.0f : 0.6f; // 小羽は大羽の0.6倍 this.コンテキスト[ i ].進行カウンタ = new FDK.カウンタ.単純増加後不変カウンタ( 最初の値: 0, 最後の値: 70, 値をひとつ増加させるのにかける時間ms: 3 ); // 0 to 70 (210ms) @@ -82,26 +82,27 @@ namespace SST.ステージ.演奏 // 現在の進行カウンタの進行割合に応じて、Z軸回転率・幅拡大率・移動量を計算する。 float 進行割合0to1 = context.進行カウンタ.現在値の割合; - float Z軸回転率 = context.回転単位 + ( context.回転速度 * SharpDX.MathUtil.DegreesToRadians( 60.0f * 進行割合0to1 ) ); // 0→1 のとき 0→60度(等速で) + float Z軸回転率 = context.回転開始角度 + ( context.回転速度 * SharpDX.MathUtil.DegreesToRadians( 60.0f * 進行割合0to1 ) ); // 0→1 のとき 0→60度(等速で) float 幅拡大率 = (float) ( ( 0.1 + 0.9 * Math.Cos( 進行割合0to1 * Math.PI / 2.0 ) ) * context.サイズ ); // 0→1 のとき 1.0→0.1(加速しながら) - float 平行移動量 = (float) ( Math.Sin( 進行割合0to1 * Math.PI / 2.0 ) * context.サイズ * -50.0 ); // 0→1 のとき (0→0.8)×サイズ(減速しながら) + float 平行移動量 = (float) ( Math.Sin( 進行割合0to1 * Math.PI / 2.0 ) * context.サイズ ); // 0→1 のとき 0→サイズ(減速しながら) // 1枚描画する。 var 変換行列2D = - dr.行列を単位変換するDPXtoPX( SharpDX.Matrix3x2.Translation( -70f + 100f * 進行割合0to1, -70f + 100f * 進行割合0to1 ) ) // 物理単位。 - * SharpDX.Matrix3x2.Scaling( 0.2f + 幅拡大率, 0.2f + context.サイズ ) + dr.拡大行列DPXtoPX // スケーリング(1) DPX → PX + * SharpDX.Matrix3x2.Translation( ( 40f * 平行移動量 ) * dr.拡大率DPXtoPX横方法, ( 40f * 平行移動量 ) * dr.拡大率DPXtoPX縦方向 ) // 物理単位。 + * SharpDX.Matrix3x2.Scaling( 0.2f + 幅拡大率, 0.2f + context.サイズ ) // スケーリング(2) * SharpDX.Matrix3x2.Rotation( Z軸回転率 ) // 画像の左上端が中心。 - * dr.行列を単位変換するDPXtoPX( SharpDX.Matrix3x2.Translation( context.中央位置px.X, context.中央位置px.Y ) ); // 物理単位。 + * SharpDX.Matrix3x2.Translation( context.中央位置dpx.X * dr.拡大率DPXtoPX横方法, context.中央位置dpx.Y * dr.拡大率DPXtoPX縦方向 ); // 物理単位。 - this.羽画像.進行描画する( dr, 変換行列2D ); + this.羽画像.描画する( dr, 変換行列2D ); } } protected class Cコンテキスト { public bool 使用中; - public SharpDX.Vector2 中央位置px; - public float 回転単位; + public SharpDX.Vector2 中央位置dpx; + public float 回転開始角度; public float 回転速度; public float サイズ; public FDK.カウンタ.単純増加後不変カウンタ 進行カウンタ; diff --git a/StrokeStyleT/ステージ/演奏/演奏ステージ.cs b/StrokeStyleT/ステージ/演奏/演奏ステージ.cs index 5854270..74a906c 100644 --- a/StrokeStyleT/ステージ/演奏/演奏ステージ.cs +++ b/StrokeStyleT/ステージ/演奏/演奏ステージ.cs @@ -32,7 +32,7 @@ namespace SST.ステージ.演奏 this.子リスト.Add( this.ステージ台 = new 画像( @"$(Static)\images\ステージ台.png" ) ); this.子リスト.Add( this.FPS画像 = new 文字列画像() ); - // 子Activity の外部依存 Action を実装する。 + // 子Activity の外部依存 Action の実体を定義する。 this.スクロール譜面.ヒット判定文字列開始 = ( chipType, hitType ) => { this.ヒット判定文字列.表示開始( chipType, hitType ); }; this.スクロール譜面.コンボリセット = () => { this.コンボ.COMBO値 = 0; }; this.スクロール譜面.コンボ加算 = () => { this.コンボ.COMBO値++; }; @@ -49,16 +49,16 @@ namespace SST.ステージ.演奏 FDK.Log.Info( "演奏ステージを開始します。" ); Debug.Assert( null != StrokeStyleT.演奏スコア, "[バグあり] 演奏スコアが null です。" ); - #region " ヒットした回数をすべてクリア。" + #region " すべてのヒット判定種別について、ヒット回数をクリア。" //---------------- this.ヒットした回数.Clear(); foreach( var 判定 in typeof( ヒット判定種別 ).GetEnumValues() ) this.ヒットした回数[ (ヒット判定種別) 判定 ] = 0; //---------------- #endregion - #region " 選択ノードの持つ動画ファイルパスが有効なら背景動画とBGMを初期化する。" + #region " 選択ノードの持つ動画ファイルパスが有効なら、背景動画とBGMを初期化する。" //---------------- - var 動画ファイルパス = ( (SST.曲.MusicNode) StrokeStyleT.曲ツリー管理.現在選択されているノード ).動画ファイルパス; + var 動画ファイルパス = ( (SST.曲.MusicNode) StrokeStyleT.曲ツリー管理.現在選択されているノード )?.動画ファイルパス; if( 動画ファイルパス.Nullでも空でもない() ) { this.子リスト.Add( this.背景動画 = new 動画( 動画ファイルパス ) ); // 子リストに追加 @@ -82,7 +82,7 @@ namespace SST.ステージ.演奏 { FDK.Log.Info( "演奏ステージを終了します。" ); - //this.BGMを解放する(); → ここではまだ解放しない。結果ステージが終わったときに解放する。 + //this.BGMを解放する(); → ここではまだ解放しない。結果ステージが終わるときに、外部から解放する。 if( null != this.背景動画 ) this.子リスト.Remove( this.背景動画 ); // 子リストから削除 @@ -95,9 +95,9 @@ namespace SST.ステージ.演奏 //---------------- if( this.活性化した直後である ) { - this.演奏開始時刻sec = this.サウンドタイマ.現在のデバイス位置secを取得する( StrokeStyleT.Wasapiデバイス.AudioClock ); - this.FPS = new FDK.カウンタ.FPS(); this.活性化した直後である = false; + this.FPS = new FDK.カウンタ.FPS(); + this.演奏開始時刻sec = this.サウンドタイマ.現在のデバイス位置secを取得する( StrokeStyleT.Wasapiデバイス.AudioClock ); } //---------------- #endregion @@ -108,17 +108,17 @@ namespace SST.ステージ.演奏 this.FPS.VPSをカウントする(); this.FPS画像.表示文字列 = $"VPS: {this.FPS.現在のVPS.ToString()}"; - #region " 譜面スクロール速度の追い付き進行。" + #region " 譜面スクロール速度が変化している場合の追い付き進行。" //---------------- if( this.現在進行描画中の譜面スクロール速度の倍率 < StrokeStyleT.ユーザ管理.現在選択されているユーザ.譜面スクロール速度の倍率 ) { - // 時間間隔に関係なく進行描画ごとに倍率を変えてしまっているが、まあVPSなど60~120くらいやろうからよし。 + // todo: 時間間隔に関係なく進行描画ごとに倍率を変えてしまっているので、あとからVPSに依存しないよう修正すること。 this.現在進行描画中の譜面スクロール速度の倍率 = Math.Min( this.現在進行描画中の譜面スクロール速度の倍率 + 0.05, StrokeStyleT.ユーザ管理.現在選択されているユーザ.譜面スクロール速度の倍率 ); } else if( this.現在進行描画中の譜面スクロール速度の倍率 > StrokeStyleT.ユーザ管理.現在選択されているユーザ.譜面スクロール速度の倍率 ) { - // 同上。 + // todo: 同上。 this.現在進行描画中の譜面スクロール速度の倍率 = Math.Max( this.現在進行描画中の譜面スクロール速度の倍率 - 0.05, StrokeStyleT.ユーザ管理.現在選択されているユーザ.譜面スクロール速度の倍率 ); } @@ -130,7 +130,7 @@ namespace SST.ステージ.演奏 // 背景動画チップがヒット済みなら、背景動画の進行描画を行う。 this.背景動画?.進行描画する( dr, new SharpDX.RectangleF( 0f, 0f, dr.設計画面サイズdpx.Width, dr.設計画面サイズdpx.Height ) ); - // 動画が重たいかもしれないので、時刻をここで再取得する。 + // 動画が重たいかもしれないので、演奏時刻をここで再度取得する。 演奏時刻sec = this.サウンドタイマ.現在のデバイス位置secを取得する( StrokeStyleT.Wasapiデバイス.AudioClock ) - this.演奏開始時刻sec; // 背景動画が再生されているのにBGMがまだ再生されていないなら、再生を開始する。 @@ -141,12 +141,12 @@ namespace SST.ステージ.演奏 } } - this.ステージ台.進行描画する( dr, 0.0f, 0.0f ); + this.ステージ台.描画する( dr, 0.0f, 0.0f ); this.レーンフレーム.進行描画する( dr ); this.コンボ.進行描画する( dr ); this.ヒット判定文字列.進行描画する( dr ); this.スクロール譜面.小節線拍線を進行描画する( dr, 演奏時刻sec, this.現在進行描画中の譜面スクロール速度の倍率 ); - this.判定バー.進行描画する( dr, 597f, 座標.判定バーの中央Y座標dpx - 43f ); + this.判定バー.描画する( dr, 597f, 座標.判定バーの中央Y座標dpx - 43f ); this.ドラムセット.進行描画する( dr ); this.スクロール譜面.チップを進行描画する( dr, 演奏時刻sec, this.現在進行描画中の譜面スクロール速度の倍率 ); this.回転羽.進行描画する( dr ); @@ -177,7 +177,7 @@ namespace SST.ステージ.演奏 } public void BGMを解放する() { - if( null != this.BGM ) // 背景動画がなければ null である + if( null != this.BGM ) // 背景動画がなければ BGM も null である { StrokeStyleT.Wasapiデバイス.サウンドをミキサーから削除する( this.BGM ); FDK.Utilities.解放する( ref this.BGM ); @@ -201,7 +201,7 @@ namespace SST.ステージ.演奏 protected readonly FDK.メディア.画像 ステージ台; protected readonly FDK.メディア.文字列画像 FPS画像; /// - /// 解放は、このクラスの非活性化後に、外から行われる。 + /// 解放は、演奏ステージクラスの非活性化後に、外部から行われる。 /// /// protected FDK.メディア.サウンド.WASAPI排他.Sound BGM = null; diff --git a/StrokeStyleT/ステージ/起動/起動ステージ.cs b/StrokeStyleT/ステージ/起動/起動ステージ.cs index 7e34713..3d6f462 100644 --- a/StrokeStyleT/ステージ/起動/起動ステージ.cs +++ b/StrokeStyleT/ステージ/起動/起動ステージ.cs @@ -47,9 +47,11 @@ namespace SST.ステージ.起動 case フェーズ.開始: #region " フェードインを開始する。" //----------------- - this.現在のフェーズ = フェーズ.フェードイン; this.フェーズカウンタ = new FDK.カウンタ.単純増加後不変カウンタ( 最初の値: 0, 最後の値: 1, 値をひとつ増加させるのにかける時間ms: 1000 ); this.フェードイン.開始する(); + + // 次のフェーズへ。 + this.現在のフェーズ = フェーズ.フェードイン; //----------------- #endregion break; @@ -57,7 +59,7 @@ namespace SST.ステージ.起動 case フェーズ.フェードイン: #region " 背景画像とフェードインを描画する。" //----------------- - this.背景画像.進行描画する( dr, 0f, 0f ); + this.背景画像.描画する( dr, 0f, 0f ); this.フェードイン.進行描画する( dr, this.フェードインアウト兼用パネル ); //----------------- #endregion @@ -65,8 +67,8 @@ namespace SST.ステージ.起動 //----------------- if( this.フェーズカウンタ.終了値に達した ) { - this.現在のフェーズ = フェーズ.表示中; this.フェーズカウンタ.開始する( 最初の値: 0, 最後の値: 2, 値をひとつ増加させるのにかける時間ms: 1000 ); + this.現在のフェーズ = フェーズ.表示中; } //----------------- #endregion @@ -75,16 +77,16 @@ namespace SST.ステージ.起動 case フェーズ.表示中: #region " 背景画像を表示する。" //----------------- - this.背景画像.進行描画する( dr, 0f, 0f ); + this.背景画像.描画する( dr, 0f, 0f ); //----------------- #endregion #region " 持ち時間に達したら次のフェーズへ。" //----------------- if( this.フェーズカウンタ.終了値に達した ) { - this.現在のフェーズ = フェーズ.フェードアウト; this.フェーズカウンタ.開始する( 最初の値: 0, 最後の値: 2, 値をひとつ増加させるのにかける時間ms: 1000 ); this.フェードアウト.開始する(); + this.現在のフェーズ = フェーズ.フェードアウト; } //----------------- #endregion @@ -93,7 +95,7 @@ namespace SST.ステージ.起動 case フェーズ.フェードアウト: #region " 背景画像とフェードアウトを表示する。" //----------------- - this.背景画像.進行描画する( dr, 0f, 0f ); + this.背景画像.描画する( dr, 0f, 0f ); this.フェードアウト.進行描画する( dr, this.フェードインアウト兼用パネル ); //----------------- #endregion diff --git a/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs b/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs index 184fa65..a13bb62 100644 --- a/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs +++ b/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs @@ -57,7 +57,7 @@ namespace SST.ステージ.選曲 this.カーソル位置.X--; // 制限なし // カーソルと一緒に、選択曲も移動する。 - StrokeStyleT.曲ツリー管理.前のノードを選択する(); + StrokeStyleT.曲ツリー管理.前のノードを選択する(); // 1つ左へ = 3つ前へ StrokeStyleT.曲ツリー管理.前のノードを選択する(); StrokeStyleT.曲ツリー管理.前のノードを選択する(); } @@ -66,7 +66,7 @@ namespace SST.ステージ.選曲 this.カーソル位置.X++; // 制限なし // カーソルと一緒に、選択曲も移動する。 - StrokeStyleT.曲ツリー管理.次のノードを選択する(); + StrokeStyleT.曲ツリー管理.次のノードを選択する(); // 1つ右へ = 3つ次へ StrokeStyleT.曲ツリー管理.次のノードを選択する(); StrokeStyleT.曲ツリー管理.次のノードを選択する(); } @@ -252,7 +252,7 @@ namespace SST.ステージ.選曲 var Y軸回転 = SharpDX.Matrix.RotationY( SharpDX.MathUtil.DegreesToRadians( ( パネル位置.X - 4 ) * パネル間X方向角度deg ) ); - this.Nullパネルの画像.進行描画する( dr, ( 拡大縮小 * 平行移動 * Y軸回転 ) ); + this.Nullパネルの画像.描画する( dr, ( 拡大縮小 * 平行移動 * Y軸回転 ) ); } if( null != パネルノード ) { diff --git a/StrokeStyleT/ステージ/選曲/選曲ステージ.cs b/StrokeStyleT/ステージ/選曲/選曲ステージ.cs index c4348e6..6877add 100644 --- a/StrokeStyleT/ステージ/選曲/選曲ステージ.cs +++ b/StrokeStyleT/ステージ/選曲/選曲ステージ.cs @@ -31,7 +31,7 @@ namespace SST.ステージ.選曲 this.背景動画.ループ再生する = true; this.現在のフェーズ = フェーズ.表示中; - this.子リスト.Add( StrokeStyleT.曲ツリー管理 ); // コンストラクタで追加したら static への直接参照がずっと子リストに残る。 + this.子リスト.Add( StrokeStyleT.曲ツリー管理 ); // コンストラクタで追加したら static への直接参照がずっと子リストに残るので、ここで。 } protected override void On非活性化( デバイスリソース dr ) { @@ -51,7 +51,7 @@ namespace SST.ステージ.選曲 case フェーズ.表示中: this.現在のフェーズ = フェーズ.表示中; this.曲パネルビュー.進行描画する( dr ); - this.ステージ台.進行描画する( dr, 0.0f, 0.0f ); + this.ステージ台.描画する( dr, 0.0f, 0.0f ); this.ドラムセット.進行描画する( dr ); break; } diff --git a/StrokeStyleT/ユーザ/ユーザ管理.cs b/StrokeStyleT/ユーザ/ユーザ管理.cs index d4252b1..6e44d4e 100644 --- a/StrokeStyleT/ユーザ/ユーザ管理.cs +++ b/StrokeStyleT/ユーザ/ユーザ管理.cs @@ -19,7 +19,7 @@ namespace SST.ユーザ } public void ユーザを選択する( ユーザ 選択対象ユーザ ) { - if( null != 選択対象ユーザ ) // null は OK + if( null != 選択対象ユーザ ) // null でもエラーじゃない { if( null == this.ユーザリスト.Find( user => user == 選択対象ユーザ ) ) { diff --git a/StrokeStyleT/曲/MusicNode.cs b/StrokeStyleT/曲/MusicNode.cs index d0814f9..0a795e9 100644 --- a/StrokeStyleT/曲/MusicNode.cs +++ b/StrokeStyleT/曲/MusicNode.cs @@ -24,9 +24,9 @@ namespace SST.曲 ( from ファイル名 in Directory.GetFiles( Path.GetDirectoryName( this.sstfファイルパス ) ) where 対応するサムネイル画像名.Any( thumbファイル名 => ( Path.GetFileName( ファイル名 ).ToLower() == thumbファイル名 ) ) select ファイル名 ).FirstOrDefault(); // 複数あったら、最初に見つけたほうを採用。1つも見つからなければ null。 + if( null != サムネイル画像ファイルパス ) { - // サムネイル画像ファイルがあるならインスタンスを生成。 this.サムネイル画像 = new テクスチャ( サムネイル画像ファイルパス ); } @@ -52,7 +52,7 @@ namespace SST.曲 } public override void ノード画像を描画する( デバイスリソース dr, SharpDX.Matrix ワールド変換行列 ) { - this.サムネイル画像?.進行描画する( dr, ワールド変換行列 ); + this.サムネイル画像?.描画する( dr, ワールド変換行列 ); } protected FDK.メディア.テクスチャ サムネイル画像 = null; diff --git a/StrokeStyleT/曲/Node.cs b/StrokeStyleT/曲/Node.cs index 6fffd7e..d6caec8 100644 --- a/StrokeStyleT/曲/Node.cs +++ b/StrokeStyleT/曲/Node.cs @@ -102,12 +102,12 @@ namespace SST.曲 public virtual void ノード画像を描画する( デバイスリソース dr, SharpDX.Matrix ワールド変換行列 ) { if( Node.既定の曲画像.活性化している ) - Node.既定の曲画像.進行描画する( dr, ワールド変換行列 ); + Node.既定の曲画像.描画する( dr, ワールド変換行列 ); } public virtual void タイトル画像を描画する( デバイスリソース dr, SharpDX.Matrix ワールド変換行列 ) { if( this.タイトル文画像.活性化している ) - this.タイトル文画像.進行描画する( dr, ワールド変換行列 ); + this.タイトル文画像.描画する( dr, ワールド変換行列 ); } protected タイトルテクスチャ タイトル文画像 = null; diff --git a/StrokeStyleT/曲/タイトルテクスチャ.cs b/StrokeStyleT/曲/タイトルテクスチャ.cs index 211719d..c518f25 100644 --- a/StrokeStyleT/曲/タイトルテクスチャ.cs +++ b/StrokeStyleT/曲/タイトルテクスチャ.cs @@ -30,7 +30,7 @@ namespace SST.曲 // ビットマップ付きテクスチャを解放する。 base.Onデバイス依存リソースの解放( dr ); } - public new void 進行描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null ) + public new void 描画する( デバイスリソース dr, SharpDX.Matrix ワールド行列変換, SharpDX.RectangleF? 転送元矩形 = null ) { if( this.表示文字列.Nullまたは空である() ) return; @@ -40,7 +40,7 @@ namespace SST.曲 this.テクスチャを更新する( dr ); // テクスチャを描画する。 - base.進行描画する( dr, ワールド行列変換, 転送元矩形 ); + base.描画する( dr, ワールド行列変換, 転送元矩形 ); } protected float フォントサイズpt = 30.0f; @@ -85,7 +85,7 @@ namespace SST.曲 #endregion // ビットマップ付きテクスチャを作成する。(上で設定した ユーザ指定サイズdpx の大きさで作成される。) - base.Onデバイス依存リソースの作成( dr ); + base.Onデバイス依存リソースの作成( dr ); // this. じゃなくて base. #region " ビットマップに文字列を描画する。" //---------------- -- 2.11.0