c# - .NET 以 60 FPS 重绘?

标签 c# winforms

我在 OpenGL 上下文窗口中运行了一些动画,因此我需要不断重绘它。所以我想出了以下代码:

private void InitializeRedrawTimer()
{
    var timer = new Timer();
    timer.Interval = 1000 / 60;
    timer.Tick += new EventHandler(timer_Tick);
    timer.Start();
}

private void timer_Tick(object sender, EventArgs e)
{
   glWin.Draw();
}

虽然这只给我 40 FPS。但是,如果我将间隔设置为 1 毫秒,我可以达到 60。那么其他 20 毫秒去哪儿了?这仅仅是因为计时器的准确性差还是什么?如果我想让我的程序尽可能快地运行,有没有办法不断调用绘制函数?

最佳答案

您可以尝试实现一个游戏循环。

https://learn.microsoft.com/archive/blogs/tmiller/my-last-post-on-render-loops-hopefully

The basic loop (slightly modified from his original version and the version in the new SDK for ease of reading):

public void MainLoop()
{
        // Hook the application’s idle event
        System.Windows.Forms.Application.Idle += new EventHandler(OnApplicationIdle);
        System.Windows.Forms.Application.Run(myForm);
}    

private void OnApplicationIdle(object sender, EventArgs e)
{
    while (AppStillIdle)
    {
         // Render a frame during idle time (no messages are waiting)
         UpdateEnvironment();
         Render3DEnvironment();
    }
}

private bool AppStillIdle
{
     get
    {
        NativeMethods.Message msg;
        return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
     }
}
    
//And the declarations for those two native methods members:        
[StructLayout(LayoutKind.Sequential)]
public struct Message
{
    public IntPtr hWnd;
    public WindowMessage msg;
    public IntPtr wParam;
    public IntPtr lParam;
    public uint time;
    public System.Drawing.Point p;
}

[System.Security.SuppressUnmanagedCodeSecurity] // We won’t use this maliciously
[DllImport(“User32.dll”, CharSet=CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);

Simple, elegant, effective. No extra allocations, no extra collections, it just works.. The Idle event fires when there’s no messages in the queue, and then the handler keeps looping continuously until a message does appear, in which case it stops.. Once all the messages are handled, the idle event is fired again, and the process starts over.

此链接描述了一个使用应用程序的空闲事件的链接。它可能有用。您可以简单地执行一点时间测试或 sleep 以将其减慢到所需的 fps。尝试使用 System.Diagnostics.StopWatch 类以获得最准确的计时器。

希望对您有所帮助。

关于c# - .NET 以 60 FPS 重绘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2063178/

相关文章:

c# - 如何在不改变文化的情况下更改 c# winform 应用程序的资源文件?

c# - FxCop:CA1033 - Microsoft 的 ReadOnlyCollection 实现是否违反了此规定?

c# - 如何在 C# 中查找类的大小

c# - DesignerHost 无法创建 Visible = false 的控件

c# - 在 Windows 窗体 (c#.net) 应用程序中加速从磁盘加载图像

c# - 在 C# 中从字典中过滤键值

c# - 使用内存中的 sql lite 单元测试流利的 nhibernate 存储库 - 没有这样的表错误

c# - 如何获取8位wav文件的数据

c# - 定期更新屏幕数据的模式

wpf - 根据其内容自动调整 ElementHost 大小