【问题标题】:Locking Frames Per Second to 60fps将每秒帧数锁定为 60fps
【发布时间】:2016-05-03 21:41:36
【问题描述】:

我从 Extra Credits on FPS 中看到了这一集,他们提到您通常应该将 fps 锁定为 30 的倍数,因为它与显示器的刷新率相匹配并减少了伪影。我的代码以 60fps 的速度运行,但我仍然在运动中得到非常微妙的伪影。

https://www.youtube.com/watch?v=zL5kOyHWI_E

它在 Windows 窗体中,所以也许真的没有什么可做的。

我的渲染循环如下所示:

private void Render() {
    Update();
    if (RenderDelegate != null)
        RenderDelegate(_renderFunctions);
    var msPause = 1000 / (double)FpsLimit - _gameTime.DeltaTime;
    if (msPause > 0)
        System.Threading.Thread.Sleep((int)msPause);
    _attachedSystem.NextFrame(); // Will call Invalidate();
}

在 WinForms 控件中的实现

protected void FormOnPaint(object sender, PaintEventArgs paintEventArgs) {
    _graphic = paintEventArgs.Graphics;
    _render();
}
void IGameMessages.DrawImage(Image image, Rectangle rect) {
    _graphic.DrawImage(image, rect);
}
void IGameMessages.NextFrame() {
    Control.Invalidate();
}

我猜按动态值睡眠不是首选方式,因为它可能与显示器刷新率不同步 1% 之类的? fps 输出在 58 到 63 fps 之间波动(DeltaTime 计算也可能有问题)

【问题讨论】:

  • 还有一个免责声明:我已经将这一行放在表单中 SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.DoubleBuffer, true);我得到的文物非常微妙。并且只在运动的“感觉”中。
  • 在 Winforms 中制作 60fps 的游戏已经是一场失败的战斗。在谈到视频谈到的 60fps 问题之前,您还有很多事情要担心。您确实应该使用专为进行游戏开发而设计的框架,而不是试图将其硬塞到 winforms 中,您将获得很多好处,例如硬件加速。
  • WinForms 也绝不会是我个人的选择。我正在做一个有 10 年历史的项目,老板想在应用程序中嵌入一个小游戏。但是,是的,我敢打赌Unity。也许正确的答案是替代品?有几个要求。第一个:应用程序托管在 Windows 窗体内(不一定由绘制)。第二:我无法在客户端机器上安装任何软件,但我可以使用任意数量的 dll。
  • 与显示器同步根本不是winforms内置的,唉。 WPF 会开箱即用..
  • 直接访问视频适配器,从而导致撕裂伪影,过去 10 年已经结束并完成了。现在您渲染到内存中的表面,DWM 将其合成到屏幕上。好久没看到有人抱怨撕裂了,这是 XP 的问题吗?

标签: c# winforms gdi frame-rate


【解决方案1】:

WinForm 并不理想。原因是屏幕更新不取决于您的应用程序。 WinForms 中没有屏幕中断。

我保留了一个计时器并从左到右移动了一个对象,800 像素,“精灵”类似的对象有一个开始计数器整数。取决于过去了多少时间,一个新职位被占用了。

if(!x.AtEnd) {
    X.DeltaTime = X.Startime-currentTime;
    int x = myStartTime - currentTime;
    x.position = X.DeltaTime % 430; //time was in ms and 430 just a number 

    if (x.postion > x.end) {
        x.position=x.end;
        x.AtEnd=true;
    }
}

这在一定程度上取决于它移动的速度和外观的好坏(这也取决于计算机速度,因为较慢的计算机也需要更多时间在其他线程上执行)。使用类似上面的东西,我得到了一个合理的平滑移动对象,不像游戏中那样平滑,但它运行良好并且其中没有阻塞(延迟)代码(因为我尝试使用线程延迟,所以每个移动都花费相同的时间,但是也不流畅,画面更新太随意了)

【讨论】:

  • 我离开那家公司已经很长时间了,但无论如何感谢您的回答。 2年后我明白我应该使用框架提供的回调或线程锁,这可能是硬件提供的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多