In OpenGL, everything works with the main loop (as far as I know). This is a problem if you want to draw an object for given time. For now, what I do is the following: I measure the approximate FPS of my application and set up a counter that I decrease at every iteration in the main loop. When the counter reaches 0, I stop drawing. So for example if I want to draw an object for 2s on the screen, and my FPS is 30, I set up the counter to 60 and draw the object until the counter reaches 0.
This works OK, but it’s not great. For example, it makes it hard to write something like
drawObjectFor(object, time) since the object is sometimes “far” from the main loop. Is there a better way to do that?
Your FPS may (and usually will) vary, so counting frames is not a great idea.
Assume this example to see how this could bite you:
Your application runs vsynced to 60 FPS, and your frame time is 16.58ms. That means to have the object on screen for 2 seconds, you will have to draw your object for 120 frames. Easy, let’s go!
Drawing the object adds 0.1 ms, giving a total frame time of 16.68ms. Oh sh*t. Now you have 30 FPS, and your object shows for 4 seconds…
Use proper time to decide whether or not to draw your object. When you’ve reached the conclusion that your object’s time is up, just set a flag so you won’t draw it (or, remove it from the scenegraph, if you have one, or delete it, or whatever).
This can be done in a variety of ways:
SetTimer, which will post a message to your window’s message queue. When you receive the WM_TIMER notification, set the object’sdo_drawflag (or whatever you want to call it) to false.WaitFor(Single|Multiple)Objectsomewhere once every frame, do aCreateWaitableTimer, and wait on this as well. You can useMsgWaitForMultipleObjectsExto do the message pumping and waiting in one go, and check APCs at the same time.GetTickCountonce, add 2000, and do anif(new_count <= old_count + 2000) draw_object(). While the accuracy ofGetTickCountis abysmal (several dozens of milliseconds), this does not matter at all when waiting for 2 seconds.timerfdand anepollto check readiness, or set thetimerfdit to nonblocking and see whether reading from it returns EAGAINclock_gettimeand do it manually (as withGetTickCount)setitimer