From 97e49b76b2753bd5f7734193637767ddf91d9ae4 Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Tue, 14 Jan 2014 13:04:30 +0100 Subject: [PATCH] [OpenTK] Fix UpdateFrame quantization error The UpdateFrame event rate will now match TargetUpdatePeriod even if vsync is enabled. Previously, it would be quantized to a multiple or integer fraction of of the vsync rate. --- Source/OpenTK/GameWindow.cs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index cc1e3e7..af55fe0 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -90,6 +90,8 @@ namespace OpenTK double update_timestamp; // timestamp of last UpdateFrame event double render_timestamp; // timestamp of last RenderFrame event + double update_epsilon; // quantization error for UpdateFrame events + VSyncMode vsync; FrameEventArgs update_args = new FrameEventArgs(); @@ -439,26 +441,22 @@ namespace OpenTK void DispatchUpdateAndRenderFrame(object sender, EventArgs e) { double timestamp = watch.Elapsed.TotalSeconds; - double elapsed = ClampElapsed(timestamp - update_timestamp); - - // Calculate how many update events we need to execute in order to reach - // our desired TargetUpdateFrequency - int update_count = TargetUpdatePeriod != 0 ? - (int)(elapsed / TargetUpdatePeriod) : - 1; + double elapsed = 0; - while (update_count > 0) + elapsed = ClampElapsed(timestamp - update_timestamp); + while (elapsed > 0 && elapsed + update_epsilon >= TargetUpdatePeriod) { - // Raise UpdateFrame events until we catch up with our target update rate. - if (elapsed > 0) - { - RaiseUpdateFrame(elapsed, ref timestamp); - --update_count; - } + RaiseUpdateFrame(elapsed, ref timestamp); + + // Calculate difference (positive or negative) between + // actual elapsed time and target elapsed time. We must + // compensate for this difference. + update_epsilon += elapsed - TargetUpdatePeriod; + + // Prepare for next loop elapsed = ClampElapsed(timestamp - update_timestamp); } - //timestamp = watch.Elapsed.TotalSeconds; elapsed = ClampElapsed(timestamp - render_timestamp); if (elapsed > 0 && elapsed >= TargetRenderPeriod) { -- 2.7.4