【问题标题】:Making smooth animations in .NET/GDI+在 .NET/GDI+ 中制作流畅的动画
【发布时间】:2012-10-10 09:04:53
【问题描述】:

我在 GDI+ 中制作流畅的动画时遇到问题。我从谷歌上了解到的问题是多核处理器上的 .NET 中的时钟滴答存在某种错误。这是我正在做的简化版本:

class Animation
{
  System.Diagnostics.Stopwatch sw = new Stopwatch();
  float AnimationTime = 1000; //time it takes the animation to complete

  public bool IsComplete
  { get { return sw.ElapsedMilliseconds > AnimationTime; } }

  public void StartAnimation()
  {
     sw.Reset();
     sw.Start();
  }

  public void DoFrame()
  {
     float PercentComplete = (float)sw.ElapsedMilliseconds / AnimationTime;
     //draw the animation based on PercentComplete
  }
}

DoFrame() 是这样调用的:

Animation.Start();
do
{
  Animation.DoFrame();
  Application.DoEvents();
} while (!Animation.IsComplete);

问题是动画在大约 15 帧时非常流畅,然后它突然跳动,它实际上向后退(sw.ElapsedMilliseconds 给出的值比之前的查询要小)。这很烦人,它破坏了我原本流畅的动画,即使在 Core 2 Duo 上看起来也很棒(尽管微软说这是一个多核错误)。我有一个 i7,动画很流畅,除了每秒 2-3 帧看起来“生涩”。

我知道这是一个已知问题,Microsoft 将其归咎于处理器,所以我的问题是,有没有人知道任何解决方案?我尝试使用卡尔曼滤波器,它有点工作。我希望也许有一个既定的“正确”解决方案?

哦,顺便说一句。我尝试使用 DateTime 而不是 Stopwatch 并得到了相同的结果。

我也试过了:

double PercentComplete = (double)sw.ElapsedTicks / (double)Stopwatch.Frequency * 1000 / AnimationTime

它给了我同样的结果。

【问题讨论】:

  • DoFrame() 从主线程调用大约每秒 40-60x。在完成之前不会再次调用它。
  • 你能给出实际的代码吗?这可能是相关的。您使用的是System.Timers.Timer 或System.Windows.Forms.Timer 还是完全不同的东西?
  • 我没有使用 System.Timers.Timer。我什至不知道那堂课。我正在使用秒表,我也尝试过 DateTime,两者的结果相同。我确信实际代码不相关,因为它在 Core Duo 处理器上看起来很完美。
  • 尝试使用定时器触发DoFrame。这就是 GDI+ 中的动画通常完成的方式。
  • 或者问题是因为你使用了浮点数?

标签: c# .net animation cpu stopwatch


【解决方案1】:

这可能与您调用DoFrame() 的方式有关。使用以下基于 Windows 窗体 / GDI+ 的算法,您应该始终获得非常流畅的动画:

const double desiredFps = 500.0;
long ticks1 = 0;
var interval = Stopwatch.Frequency / desiredFps;
while (true)
{
    Application.DoEvents();
    var ticks2 = Stopwatch.GetTimestamp();
    if (ticks2 >= ticks1 + interval)
    {
        ticks1 = Stopwatch.GetTimestamp();

        // do the drawing here
    }
}

【讨论】:

  • Application.DoEvents(); 在循环中...为什么?
  • DoEvents 来自主线程......动画发生在不同的线程上......我会尝试你的方式。
  • 控制帧率似乎确实有帮助,只要系统能够比所需的帧率做得更好。持续的抖动消失了,虽然有新的间歇性抖动,但我认为我与另一个线程上发生的事情有关。谢谢!
猜你喜欢
  • 2018-11-26
  • 1970-01-01
  • 2017-05-27
  • 2014-01-16
  • 2017-06-20
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多