From b1f90c380e6b915b5a4bdf3614e9260bbc67cd38 Mon Sep 17 00:00:00 2001 From: Jarl Gullberg Date: Sun, 1 Oct 2017 20:06:50 +0200 Subject: [PATCH] Add builtin frame time measurement. GLArea automatically synchronizes to GDK's refresh rate, which may lead to incorrect frame time measurements if it's not correctly measured. This property is guaranteed to always contain the actual live frame delta of the previous frame in render functions. --- src/OpenTK.GLWidget/GLWidget.cs | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/OpenTK.GLWidget/GLWidget.cs b/src/OpenTK.GLWidget/GLWidget.cs index 6b11da02..54b6bd78 100644 --- a/src/OpenTK.GLWidget/GLWidget.cs +++ b/src/OpenTK.GLWidget/GLWidget.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.ComponentModel; +using Gdk; using OpenTK.Graphics; using Gtk; @@ -20,6 +21,16 @@ namespace OpenTK private IGraphicsContext _GraphicsContext; private bool _Initialized = false; + /// + /// The previous frame time reported by GTK. + /// + private double? PreviousFrameTime; + + /// + /// Gets the time taken to render the last frame (in seconds). + /// + public double DeltaTime { get; private set; } + /// /// The set for this widget. /// @@ -54,6 +65,7 @@ namespace OpenTK GraphicsContextFlags = graphicsContextFlags; + AddTickCallback(UpdateFrameTime); SetRequiredVersion(glVersionMajor, glVersionMinor); if (graphicsMode.Depth > 0) @@ -72,6 +84,31 @@ namespace OpenTK } } + /// + /// Updates the time delta with a new value from the last frame. + /// + /// The sending widget. + /// The relevant frame clock. + /// true if the callback should be called again; otherwise, false. + private bool UpdateFrameTime(Widget widget, FrameClock frameClock) + { + var frameTimeµSeconds = frameClock.FrameTime; + + if (!PreviousFrameTime.HasValue) + { + PreviousFrameTime = frameTimeµSeconds; + + return true; + } + + var frameTimeSeconds = (frameTimeµSeconds - PreviousFrameTime) / 10e6; + + DeltaTime = (float)frameTimeSeconds; + PreviousFrameTime = frameTimeµSeconds; + + return true; + } + /// /// Destructs this object. ///