GLART week 11: TimingExamples: GLART_11_timing.java -- control animation speed Resources: NeHe: Introduction To Physical Simulations -- tutorial on building a physics simulation NOTES: ================================================================= The frequency at which screen images are drawn is called the framerate and is usually measured in frames per second. Since cpu performance varies, program execution speed can vary from one computer to another, resulting in different frame rates. If you move an animation a fixed amount in each draw(), then the animation will move at different rates on different computers, as draw() is called more often on the faster cpu. Timing is not part of OpenGL and 3D graphics but is so intrinsic to creating animations that it is worth investigating here. One crude option for controlling frame rate is to limit the screen refresh rate. "Vertical Synchronization" or "VSync" is a video setting that synchronizes screen refreshes with the refresh rate of the video monitor. If VSync is enabled then the hardware and software will only refresh at a the rate defined by the monitor, for example 60 refreshes per second. With VSync on, updates to the video device will wait till the monitor is ready to draw. Even if the program could refresh at 100 frames per second, OpenGL will only update the video buffers at perhaps 60 or 75 frames per second. This keeps the refresh rate fairly constant, but monitors can have different refresh rates, and slower graphics cards or a very graphics computationally intensive program may slow down the refresh rate below the monitor refresh rate. To insure that animations run at the same rate across various hardware, you need to update animations according to actual time elapsed, not frame render rate. To do this, check how much time has elapsed since the last frame rendered, then "step" the animation forward in proportion to that amount of time. The animation (or physics simulation) keeps track of how much time has elapsed. Java's time function, System.currentTimeMillis(), does not measure time accurately below 10 milliseconds, and will not give accurate results when measuring time elapsed between frames. Use System.nanoTime() to accurately measure time elapsed. Functions: System.nanoTime() Java's hardware timer returns elapsed time in nanoseconds. This is very accurate for small durations, not to be used to measure larger time periods like days, weeks, etc. JOApp.getSecondsPerFrame returns the average seconds per frame for the past 100 frames. This creates smoother timing than reacting to the exact time elapsed between each frame (which can vary unpredictably depending on cpu load. NOTE: Java's time function, System.currentTimeMillis() is not accurate for small durations. Use double data type for highest accuracy when measuring small time durations.