直接在WPF中绘制快速图形,而不是使用CompositionTarget,渲染

xt0899hw  于 2022-12-05  发布在  其他
关注(0)|答案(1)|浏览(173)

我有一个抛出事件的控件,我需要在上述事件触发后立即绘制。该事件以固定的间隔每秒触发大约15次,并按预期进行处理。我尝试了以下场景:

案例1

在XAML中,我创建了一个画布。每当自定义控件中的事件触发时,我都会更新计数器。当CompositionTarget事件触发并且计数器发生更改时,画布将被重新绘制(基于计数器)。但是,这太慢了。CompositionTarget事件的触发速度很低,并且不规则。请参见:
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/how-to-render-on-a-per-frame-interval-using-compositiontarget?view=netframeworkdesktop-4.8
Why is Frame Rate in WPF Irregular and Not Limited To Monitor Refresh?

案例2

我安装了SkiaSharp WPF Nuget包。尝试了与场景1基本相同的操作,这次使用了OnPaintSurface事件。但我得到的结果大致相同,似乎OnPaintService的调用方式与CompositionTarget类似。
演示(注意不规则的更新,有时帧会挂起或掉落):

演示代码:
第一个
同样,我尝试使用SkiaSharp直接在可写位图上绘制,结果也是一样。我编写的代码看起来类似于:
The most efficient way to draw in SkiaSharp without using PaintSurface event
有没有办法直接在WPF中绘图?也许我遗漏了一些东西,或者我还没有完全理解SkiaSharp?有没有其他的软件包可以让我使用,比如SkiaSharp?我不想和WPF说再见,因为我还需要在我的应用程序中使用一些其他的WPF组件。

编辑:我正在努力实现的目标:

触发事件的“组件”是一个mod音乐播放器(SharpMik)。我想在屏幕上绘制播放器中播放的音符(就像一个音乐跟踪器)。当使用OnPaintSurface和普通画布时,我不能得到比这更好的结果(当音乐播放的同时,你会看到音符没有正确地随节拍更新(轻微延迟)):

上述结果的代码:
第一次

xzabzqsa

xzabzqsa1#

通过反复试验和用户Clemens(非常感谢!)的反馈,我学到了以下内容。

  • 如果您想要快速绘制,请不要使用CompositionTarget事件。直接绘制即可。不用说,请尽量将所需的绘制量保持在最低限度。
  • 当绘图的时间很关键时(例如动画),我会说,不要太依赖事件。我的事件调用程序不是太精确。
  • 就目前而言,WPF绘图速度足够快。如果我遇到严重的问题,我可能会检查一下MonoGame / SkiaSharp是否是可以提高性能的工具。

为了解决这个问题,我事先计算了每个“帧”之间经过的滴答数。然后,当音乐开始播放时,我开始循环更新屏幕。我画了一帧,等待滴答数,直到下一帧。为了保持同步,我比较了音乐经过的滴答数和动画经过的滴答数,并相应地改变了帧速度。如果这有意义的话)

编辑:

虽然我的速度得到了很大的提高,但这还不够。我改用了MonoGame。我还了解到经典的WinForms比WPF的性能略好。

相关问题