   Precision timing in OpenGL?
  So I've been looking for a 3D graphics API. I've been messing around in Direct3D for a while, but I'd like to try OpenGL now. Only problem is... from what I've read, OpenGL has no high precision timers? QueryPerformanceCounter() has worked perfectly for me in Direct3D but it seems OpenGL has no equivalent. So I ask, could someone give me some direction on how to accurately do time calculations? ~10ms granularity isn't going to cut it; I have to have at the very least 100th of a millisecond precision or else a game running in variable time step is fubar'd. I had this problem before in Xna/C# with the built-in timestepping and it wasn't pretty.There is certainly some way of doing it or else there wouldn't be any commercial games written in OpenGL, working properly. So, any idea what I should do? I'd love to move to OpenGL and be platform portable, but not having precise timing would be a dealbreaker.   
  Erm...  QueryPerformanceCounter and QueryPerformanceFrequency are a part of the Win32 API, not the DirectX API.In other words, you can use them with OpenGL.  ;)   ;  QueryPerformanceCounter isn't a D3D function, it's a Windows function! It works just as well in OpenGL as it does in D3D.If you want a cross-platform timer, you can either make one yourself using the OS-specific functions for each OS you want to target, or use a portability library like GLFW.   ;  I know, but my point is, I want to be portable. That would be my reason for using OpenGL.Hmmm, well judging from that link, it looks like I could use QPC() from windows.h if I'm on a Windows machine and use gettimeofday() if I were on a Linux/Mac machine. If its true that gettimeofday() has microsecond precision, that would be perfect.   ;Quote:I have to have at the very least 100th of a millisecond precision or else a game running in variable time step is fubar'd.Why do you need such precision?  If you want to run your game at a steady 60 frames per second, you only need at most 16 milliseconds of precision.  See fix your timestep.   ;Quote:Original post by _fastcallQuote:I have to have at the very least 100th of a millisecond precision or else a game running in variable time step is fubar'd.Why do you need such precision?  If you want to run it at a steady 60 frames per second, you only need at most 16 milliseconds of precision.  See fix your timestep.What if someone who'd playing my game has an "uber rig" and wants to pump 500 FPS out of my game? Without precise timing, that would lead to the game running at crazy speeds. Even at 60 FPS, that would be a 16.67ms delay, not 16ms. If it were consistently off by that much, a it wouldn't be a big deal, but low precision timers are usually all over the place. It could be off by almost twice as much at times.Thanks for the link though, I'll check it out.   ;Quote:Original post by ChaosenemyWhat if someone who'd playing my game has an "uber rig" and wants to pump 500 FPS out of my game?Ideally you would like that machine to simulate your game with the same accuracy as a machine that can only run it at 60 FPS.  Right?  So you set the logic of your game to update 60 times a second, and in between updates, you interpolate between the current logic state and the previous logic state to get the appearance of high frame rates.Quote:Even at 60 FPS, that would be a 16.67ms delay, not 16ms. If it were consistently off by that much, a it wouldn't be a big deal, but low precision timers are usually all over the place. It could be off by almost twice as much at times.Its not that the timer counters get off 0.67ms every time you query it, its just that the value returned from the query may be off by plus or minus some precision.   ;Quote:Original post by _fastcallQuote:Original post by ChaosenemyWhat if someone who'd playing my game has an "uber rig" and wants to pump 500 FPS out of my game?Ideally you would like that machine to simulate your game with the same accuracy as a machine that can only run it at 60 FPS.  Right?  So you set the logic of your game to update 60 times a second, and when its not time to update the logic, you interpolate between the current logic state and the previous logic state to get the appearance of high frame rates.That's actually an interesting idea. Only problem I see is it introduces a slight "input lag" due to the fact that the user is now constantly 1 frame behind.But even then... without a precise timing mechanism, how could you interpolate between the frames correctly? ;)Maybe some sort of really complex algorithm to measure CPU speed between frames. You could have a seperate thread wait between refresh rate interrupts from the monitor and see how many instructions could be processed in that time period and find like an average over time.The mind boggles =\   ;  Ironically, OpenGL does have (other than D3D) such a functionality as an extension. The ARB version is not currently widely supported, but the identical EXT version is supported on reasonably recent cards (all nVidia cards during the last 5-6 years, and at least all ATI cards starting with "HD").And, again ironically, QueryPerformanceCounter() indeed does not work perfectly (even though it might incidentially work for you). It is probably the worst, most unreliable way of measuring time, as it builds on RDTSC on the vast majority of systems. As such, its result does not even necessarily correlate with time at all (which is a funny thing for a time function!).One thing to note when using the timer query extension is that glQueryCounterEXT will signal a query object with the current time when all rendering commmands that have been previously submitted have been finalized. This is an important detail, since it means that if one wants a reliable, unbiased result, one should probably call that function immediately before wglSwapBuffers and read the query object after wglSwapBuffers returns. Otherwise one would have to wait for the query to become available, which is not desirable, and it probably doesn't meaasure what one wants to know either.   ;Quote:Original post by samothIronically, OpenGL does have (other than D3D) such a functionality as an extension. The ARB version is not currently widely supported, but the identical EXT version is supported on reasonably recent cards (all nVidia cards during the last 5-6 years, and at least all ATI cards starting with "HD").And, again ironically, QueryPerformanceCounter() indeed does not work perfectly (even though it might incidentially work for you). It is probably the worst, most unreliable way of measuring time, as it builds on RDTSC on the vast majority of systems. As such, its result does not even necessarily correlate with time at all (which is a funny thing for a time function!).One thing to note when using the timer query extension is that glQueryCounterEXT will signal a query object with the current time when all rendering commmands that have been previously submitted have been finalized. This is an important detail, since it means that if one wants a reliable, unbiased result, one should probably call that function immediately before wglSwapBuffers and read the query object after wglSwapBuffers returns. Otherwise one would have to wait for the query to become available, which is not desirable, and it probably doesn't meaasure what one wants to know either.Time is frustrating.   