增加实时帧率显示

This commit is contained in:
ww-rm
2025-11-08 00:09:55 +08:00
parent 32c826a3db
commit d6ca3cca92
6 changed files with 60 additions and 16 deletions

View File

@@ -140,6 +140,9 @@
<s:String x:Key="Str_ForwardFastTooltip">Forward 10 Frames</s:String> <s:String x:Key="Str_ForwardFastTooltip">Forward 10 Frames</s:String>
<s:String x:Key="Str_FullScreenTooltip">Window/Fullscreen; F11</s:String> <s:String x:Key="Str_FullScreenTooltip">Window/Fullscreen; F11</s:String>
<!-- 日志框下方附加信息 -->
<s:String x:Key="Str_RealTimeFps">Real-time FPS: {0:F1}</s:String>
<!-- 弹窗文本 --> <!-- 弹窗文本 -->
<s:String x:Key="Str_OK">OK</s:String> <s:String x:Key="Str_OK">OK</s:String>
<s:String x:Key="Str_Cancel">Cancel</s:String> <s:String x:Key="Str_Cancel">Cancel</s:String>

View File

@@ -140,6 +140,9 @@
<s:String x:Key="Str_ForwardFastTooltip">10フレーム進める</s:String> <s:String x:Key="Str_ForwardFastTooltip">10フレーム進める</s:String>
<s:String x:Key="Str_FullScreenTooltip">ウィンドウ/フルスクリーン; F11</s:String> <s:String x:Key="Str_FullScreenTooltip">ウィンドウ/フルスクリーン; F11</s:String>
<!-- 日志框下方附加信息 -->
<s:String x:Key="Str_RealTimeFps">リアルタイムFPS{0:F1}</s:String>
<!-- 弹窗文本 --> <!-- 弹窗文本 -->
<s:String x:Key="Str_OK">OK</s:String> <s:String x:Key="Str_OK">OK</s:String>
<s:String x:Key="Str_Cancel">キャンセル</s:String> <s:String x:Key="Str_Cancel">キャンセル</s:String>

View File

@@ -140,6 +140,9 @@
<s:String x:Key="Str_ForwardFastTooltip">快进 10 帧</s:String> <s:String x:Key="Str_ForwardFastTooltip">快进 10 帧</s:String>
<s:String x:Key="Str_FullScreenTooltip">窗口/全屏; F11</s:String> <s:String x:Key="Str_FullScreenTooltip">窗口/全屏; F11</s:String>
<!-- 日志框下方附加信息 -->
<s:String x:Key="Str_RealTimeFps">实时帧率:{0:F1}</s:String>
<!-- 弹窗文本 --> <!-- 弹窗文本 -->
<s:String x:Key="Str_OK">确认</s:String> <s:String x:Key="Str_OK">确认</s:String>
<s:String x:Key="Str_Cancel">取消</s:String> <s:String x:Key="Str_Cancel">取消</s:String>

View File

@@ -156,6 +156,12 @@ namespace SpineViewer.ViewModels.MainWindow
set => SetProperty(_renderer.MaxFps, value, v => _renderer.MaxFps = _wallpaperRenderer.MaxFps = value); 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 public float Speed
{ {
get => _speed; get => _speed;
@@ -469,19 +475,31 @@ namespace SpineViewer.ViewModels.MainWindow
_wallpaperRenderer.SetActive(true); _wallpaperRenderer.SetActive(true);
_renderer.SetActive(true); _renderer.SetActive(true);
float delta; float frameDelta;
float updateDelta;
while (!_cancelToken?.IsCancellationRequested ?? false) while (!_cancelToken?.IsCancellationRequested ?? false)
{ {
delta = _clock.ElapsedTime.AsSeconds(); updateDelta = frameDelta = _clock.ElapsedTime.AsSeconds();
_clock.Restart(); _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) lock (_forwardDeltaLock)
{ {
delta += _forwardDelta; updateDelta += _forwardDelta;
_forwardDelta = 0; _forwardDelta = 0;
} }
@@ -543,7 +561,7 @@ namespace SpineViewer.ViewModels.MainWindow
if (_cancelToken?.IsCancellationRequested ?? true) break; // 提前中止 if (_cancelToken?.IsCancellationRequested ?? true) break; // 提前中止
sp.Update(0); // 避免物理效果出现问题 sp.Update(0); // 避免物理效果出现问题
sp.Update(delta * _speed); sp.Update(updateDelta * _speed);
if (_vmMain.IsVisible) if (_vmMain.IsVisible)
{ {

View File

@@ -912,14 +912,16 @@
</Grid> </Grid>
<StatusBar DockPanel.Dock="Bottom"> <StatusBar DockPanel.Dock="Bottom">
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}"> <StatusBarItem>
<TextBlock.Text> <TextBlock Foreground="{DynamicResource PrimaryTextBrush}">
<MultiBinding Converter="{StaticResource StrFmtCvter}" ConverterParameter="Str_ListViewStatusBar"> <TextBlock.Text>
<Binding Path="Items.Count" ElementName="_spineFilesListBox"/> <MultiBinding Converter="{StaticResource StrFmtCvter}" ConverterParameter="Str_ListViewStatusBar">
<Binding Path="SelectedItems.Count" ElementName="_spineFilesListBox"/> <Binding Path="Items.Count" ElementName="_spineFilesListBox"/>
</MultiBinding> <Binding Path="SelectedItems.Count" ElementName="_spineFilesListBox"/>
</TextBlock.Text> </MultiBinding>
</TextBlock> </TextBlock.Text>
</TextBlock>
</StatusBarItem>
</StatusBar> </StatusBar>
<ListBox x:Name="_spineFilesListBox" <ListBox x:Name="_spineFilesListBox"
@@ -1052,7 +1054,22 @@
<!-- 日志框容器 --> <!-- 日志框容器 -->
<Border Grid.Row="2" Name="_loggerBoxContainer"> <Border Grid.Row="2" Name="_loggerBoxContainer">
<RichTextBox x:Name="_loggerRichTextBox" Grid.Row="2" Style="{StaticResource MyLogRichTextBoxStyle}"/> <Border x:Name="_loggerBoxPanel" DataContext="{Binding SFMLRendererViewModel}">
<DockPanel>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource StrFmtCvter}" ConverterParameter="Str_RealTimeFps">
<Binding Path="RealTimeFps"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StatusBarItem>
</StatusBar>
<RichTextBox x:Name="_loggerRichTextBox" Grid.Row="2" Style="{StaticResource MyLogRichTextBoxStyle}"/>
</DockPanel>
</Border>
</Border> </Border>
</Grid> </Grid>
</Border> </Border>

View File

@@ -695,7 +695,7 @@ public partial class MainWindow : Window
_renderPanelButtonsPopupContainer.Child = _renderPanelButtonsPanel; _renderPanelButtonsPopupContainer.Child = _renderPanelButtonsPanel;
_loggerBoxContainer.Child = null; _loggerBoxContainer.Child = null;
_loggerBoxPopupContainer.Child = _loggerRichTextBox; _loggerBoxPopupContainer.Child = _loggerBoxPanel;
} }
private void SwitchToNormalLayout() private void SwitchToNormalLayout()
@@ -705,7 +705,7 @@ public partial class MainWindow : Window
HandyControl.Controls.IconElement.SetGeometry(_fullScreenButton, AppResource.Geo_ArrowsMaximize); HandyControl.Controls.IconElement.SetGeometry(_fullScreenButton, AppResource.Geo_ArrowsMaximize);
_loggerBoxPopupContainer.Child = null; _loggerBoxPopupContainer.Child = null;
_loggerBoxContainer.Child = _loggerRichTextBox; _loggerBoxContainer.Child = _loggerBoxPanel;
_renderPanelButtonsPopupContainer.Child = null; _renderPanelButtonsPopupContainer.Child = null;
_renderPanelButtonsContainer.Child = _renderPanelButtonsPanel; _renderPanelButtonsContainer.Child = _renderPanelButtonsPanel;