diff --git a/SpineViewer/Resources/Strings/en.xaml b/SpineViewer/Resources/Strings/en.xaml
index e4bdbfd..5f979db 100644
--- a/SpineViewer/Resources/Strings/en.xaml
+++ b/SpineViewer/Resources/Strings/en.xaml
@@ -140,6 +140,9 @@
Forward 10 Frames
Window/Fullscreen; F11
+
+ Real-time FPS: {0:F1}
+
OK
Cancel
diff --git a/SpineViewer/Resources/Strings/ja.xaml b/SpineViewer/Resources/Strings/ja.xaml
index 16559c7..9d607b7 100644
--- a/SpineViewer/Resources/Strings/ja.xaml
+++ b/SpineViewer/Resources/Strings/ja.xaml
@@ -140,6 +140,9 @@
10フレーム進める
ウィンドウ/フルスクリーン; F11
+
+ リアルタイムFPS:{0:F1}
+
OK
キャンセル
diff --git a/SpineViewer/Resources/Strings/zh.xaml b/SpineViewer/Resources/Strings/zh.xaml
index 9fc695c..12959e2 100644
--- a/SpineViewer/Resources/Strings/zh.xaml
+++ b/SpineViewer/Resources/Strings/zh.xaml
@@ -140,6 +140,9 @@
快进 10 帧
窗口/全屏; F11
+
+ 实时帧率:{0:F1}
+
确认
取消
diff --git a/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs b/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs
index 829df00..857212d 100644
--- a/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs
+++ b/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs
@@ -156,6 +156,12 @@ namespace SpineViewer.ViewModels.MainWindow
set => SetProperty(_renderer.MaxFps, value, v => _renderer.MaxFps = _wallpaperRenderer.MaxFps = value);
}
+ public float RealTimeFps => _realTimeFps;
+ private float _realTimeFps;
+
+ private float _accumFpsTime;
+ private int _accumFpsCount;
+
public float Speed
{
get => _speed;
@@ -469,19 +475,31 @@ namespace SpineViewer.ViewModels.MainWindow
_wallpaperRenderer.SetActive(true);
_renderer.SetActive(true);
- float delta;
+ float frameDelta;
+ float updateDelta;
while (!_cancelToken?.IsCancellationRequested ?? false)
{
- delta = _clock.ElapsedTime.AsSeconds();
+ updateDelta = frameDelta = _clock.ElapsedTime.AsSeconds();
_clock.Restart();
+ // 计算实时帧率, 1 秒刷新一次
+ _accumFpsCount++;
+ _accumFpsTime += frameDelta;
+ if (_accumFpsTime > 1f)
+ {
+ _realTimeFps = _accumFpsCount / _accumFpsTime;
+ _accumFpsTime = 0f;
+ _accumFpsCount = 0;
+ OnPropertyChanged(nameof(RealTimeFps));
+ }
+
// 停止更新的时候只是时间不前进, 但是坐标变换还是要更新, 否则无法移动对象
- if (!_isUpdating) delta = 0;
+ if (!_isUpdating) updateDelta = 0;
// 加上要快进的量
lock (_forwardDeltaLock)
{
- delta += _forwardDelta;
+ updateDelta += _forwardDelta;
_forwardDelta = 0;
}
@@ -543,7 +561,7 @@ namespace SpineViewer.ViewModels.MainWindow
if (_cancelToken?.IsCancellationRequested ?? true) break; // 提前中止
sp.Update(0); // 避免物理效果出现问题
- sp.Update(delta * _speed);
+ sp.Update(updateDelta * _speed);
if (_vmMain.IsVisible)
{
diff --git a/SpineViewer/Views/MainWindow.xaml b/SpineViewer/Views/MainWindow.xaml
index 6f323d7..7e46fa2 100644
--- a/SpineViewer/Views/MainWindow.xaml
+++ b/SpineViewer/Views/MainWindow.xaml
@@ -912,14 +912,16 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SpineViewer/Views/MainWindow.xaml.cs b/SpineViewer/Views/MainWindow.xaml.cs
index 6dd44c8..07aa442 100644
--- a/SpineViewer/Views/MainWindow.xaml.cs
+++ b/SpineViewer/Views/MainWindow.xaml.cs
@@ -695,7 +695,7 @@ public partial class MainWindow : Window
_renderPanelButtonsPopupContainer.Child = _renderPanelButtonsPanel;
_loggerBoxContainer.Child = null;
- _loggerBoxPopupContainer.Child = _loggerRichTextBox;
+ _loggerBoxPopupContainer.Child = _loggerBoxPanel;
}
private void SwitchToNormalLayout()
@@ -705,7 +705,7 @@ public partial class MainWindow : Window
HandyControl.Controls.IconElement.SetGeometry(_fullScreenButton, AppResource.Geo_ArrowsMaximize);
_loggerBoxPopupContainer.Child = null;
- _loggerBoxContainer.Child = _loggerRichTextBox;
+ _loggerBoxContainer.Child = _loggerBoxPanel;
_renderPanelButtonsPopupContainer.Child = null;
_renderPanelButtonsContainer.Child = _renderPanelButtonsPanel;