我在OpenGL上下文窗口中运行了一些动画,所以我需要不断地重绘它.所以我想出了以下代码:
void InitializeRedrawTimer() { var timer = new Timer(); timer.Interval = 1000 / 60; timer.Tick += new EventHandler(timer_Tick); timer.Start(); } void timer_Tick(object sender,EventArgs e) { glWin.Draw(); }
这只能给我40 FPS.如果我将间隔设置为1毫秒,我可以达到60.那么其他20毫秒去哪了?那只是由于计时器的准确性差或者是什么?如果我想让我的程序尽可能快地运行怎么办?有没有办法连续调用draw func?
解决方法
你可以尝试实现一个游戏循环.
http://blogs.msdn.com/tmiller/archive/2005/05/05/415008.aspx
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); } } //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.
此链接描述使用应用程序的空闲事件的链接.它可能是有用的.您可以简单地执行一点时间测试或睡眠以将其减慢到所需的fps.尝试使用System.Diagnostics.StopWatch类获得最准确的计时器.
希望这会有帮助.