GLUT Timer Functions

  • Follow


Hi

Im using the standard GLUT timer function to control my image refresh 
rate -- only trouble is that as soon as the timer is setup and repeating 
nicely the CPU activity hits 100% regardless of the frame rate selected (I 
was hoping to keep the CPU usage lower by cutting back on the refresh rate).

I know the application isnt really using up 100% CPU as I have tried a 
comparison with using keyboard input to drive the frame refresh and the 
usage is neglible at the typematic rate (which is higher than the frame rate 
Im trying for).

Also, there does not seem to be an accurate relationship between the timer 
function ms value and reality (at least below 100ms) is this usual.

Anybody with any information as to how best to use the GLUT timer function, 
the problems Im having make it unusable. Alternatively, if there is a better 
way to get some timing into my OpenGL application then I would be grateful 
for the advice.

Cheers
Steve 


0
Reply Steve 4/12/2005 5:29:20 PM

Steve wrote:

> Hi
> 
> Im using the standard GLUT timer function to control my image
> refresh rate -- only trouble is that as soon as the timer is
> setup and repeating nicely the CPU activity hits 100%
> regardless of the frame rate selected (I was hoping to keep the
> CPU usage lower by cutting back on the refresh rate).

The CPU usage showed in the Windows Task Manager is anything but
accurate. Just redraw as often as possible by issuing
glutSwapBuffers in the idle handler function and put a Sleep(1);
right after it.

Wolfgang
-- 

0
Reply Wolfgang 4/12/2005 6:44:33 PM


Wolfgang Draxinger wrote:
>> Im using the standard GLUT timer function to control my image
>> refresh rate -- only trouble is that as soon as the timer is
>> setup and repeating nicely the CPU activity hits 100%
>> regardless of the frame rate selected (I was hoping to keep the
>> CPU usage lower by cutting back on the refresh rate).
> 
> The CPU usage showed in the Windows Task Manager is anything but
> accurate. Just redraw as often as possible by issuing
> glutSwapBuffers

Do you mean glutPostRedisplay()?

> in the idle handler function and put a Sleep(1); 
> right after it.

Yes, don't use a timer function to do animation, use the idle callback.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
0
Reply Jon 4/12/2005 7:13:11 PM

Jon Harrop wrote:

> Do you mean glutPostRedisplay()?

of course.

Wolfgang
-- 

0
Reply Wolfgang 4/12/2005 7:38:07 PM

"Jon Harrop" <usenet@jdh30.plus.com> wrote in message 
news:425c1db4$0$27870$ed2619ec@ptn-nntp-reader03.plus.net...
> Wolfgang Draxinger wrote:
>>> Im using the standard GLUT timer function to control my image
>>> refresh rate -- only trouble is that as soon as the timer is
>>> setup and repeating nicely the CPU activity hits 100%
>>> regardless of the frame rate selected (I was hoping to keep the
>>> CPU usage lower by cutting back on the refresh rate).
>>
>> The CPU usage showed in the Windows Task Manager is anything but
>> accurate. Just redraw as often as possible by issuing
>> glutSwapBuffers

Im not sure I want to redraw as often as possible as it is unecessary for my 
application, however when I switch from free running to timed updates I get 
no saving in CPU activity.

I know a saving is possible because when I use keyboard input as the "timer" 
I get the desired lower frame rate _and_ lower CPU utilisation.

>
> Do you mean glutPostRedisplay()?
>
>> in the idle handler function and put a Sleep(1);
>> right after it.

This might be the key to what Im trying to do, however I need around 10Hz 
refresh but would like to experiment up to 25Hz.

>
> Yes, don't use a timer function to do animation, use the idle callback.

Every time Ive used the idle callback the CPU activity goes to 100%.

>
> -- 
> Dr Jon D Harrop, Flying Frog Consultancy
> http://www.ffconsultancy.com 


0
Reply Steve 4/12/2005 7:41:07 PM

Steve wrote:

> 
> "Jon Harrop" <usenet@jdh30.plus.com> wrote in message
> news:425c1db4$0$27870$ed2619ec@ptn-nntp-reader03.plus.net...
>> Wolfgang Draxinger wrote:
>>>> Im using the standard GLUT timer function to control my image
>>>> refresh rate -- only trouble is that as soon as the timer is
>>>> setup and repeating nicely the CPU activity hits 100%
>>>> regardless of the frame rate selected (I was hoping to keep the
>>>> CPU usage lower by cutting back on the refresh rate).
>>>
>>> The CPU usage showed in the Windows Task Manager is anything but
>>> accurate. Just redraw as often as possible by issuing
>>> glutSwapBuffers
> 
> Im not sure I want to redraw as often as possible as it is unecessary for
> my application, however when I switch from free running to timed updates I 
> get no saving in CPU activity.

Is there a reason to let you CPU idle instead of using its full power?

0
Reply Rolf 4/12/2005 7:48:51 PM

"Rolf Magnus" <ramagnus@t-online.de> wrote in message 
news:d3h8ij$9i9$00$1@news.t-online.com...
> Steve wrote:
>
>>
>> "Jon Harrop" <usenet@jdh30.plus.com> wrote in message
>> news:425c1db4$0$27870$ed2619ec@ptn-nntp-reader03.plus.net...
>>> Wolfgang Draxinger wrote:
>>>>> Im using the standard GLUT timer function to control my image
>>>>> refresh rate -- only trouble is that as soon as the timer is
>>>>> setup and repeating nicely the CPU activity hits 100%
>>>>> regardless of the frame rate selected (I was hoping to keep the
>>>>> CPU usage lower by cutting back on the refresh rate).
>>>>
>>>> The CPU usage showed in the Windows Task Manager is anything but
>>>> accurate. Just redraw as often as possible by issuing
>>>> glutSwapBuffers
>>
>> Im not sure I want to redraw as often as possible as it is unecessary for
>> my application, however when I switch from free running to timed updates 
>> I
>> get no saving in CPU activity.
>
> Is there a reason to let you CPU idle instead of using its full power?

For this one application yes, theres no point having the CPU churn for the 
sake of it in any case.

> 


0
Reply Steve 4/12/2005 7:51:40 PM

Rolf Magnus wrote:
> Is there a reason to let you CPU idle instead of using its full power?

Now that I'm developing on a laptop, I appreciate low usage. :-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
0
Reply Jon 4/12/2005 8:01:34 PM

Rolf Magnus wrote:
> 
> 
> Is there a reason to let you CPU idle instead of using its full power?
> 

Of course. He might want to bring other apps to
the front or something. Not everything is a
video game.

Whatever...the advice give by JH si good. Don't
use timers, use the idle function. A call to
clock() and glutPostRedisplay() every now and again
will do what you need.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/12/2005 8:55:48 PM

fungus wrote:

> Rolf Magnus wrote:
>> 
>> 
>> Is there a reason to let you CPU idle instead of using its full power?
>> 
> 
> Of course. He might want to bring other apps to
> the front or something.

Then he could lower the priority of his process. After all, that's what
priorities are there for. So the process doesn't take CPU power that is
needed for other ones.

0
Reply Rolf 4/12/2005 11:15:32 PM

Rolf Magnus wrote:
>>>
>>>Is there a reason to let you CPU idle instead of using its full power?
>>>
>>
>>Of course. He might want to bring other apps to
>>the front or something.
> 
> Then he could lower the priority of his process. After all, that's what
> priorities are there for. So the process doesn't take CPU power that is
> needed for other ones.
> 

I've got other processes running at the lowest
possible prority (seti@home), you cant set your
process lower than them and I don't want you
stealing a single CPU cycle. If you do then your
program will be uninstalled from my machine.



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/13/2005 2:53:20 AM

fungus wrote:
> Whatever...the advice give by JH si good. Don't
> use timers, use the idle function.

Given that newbies make the mistake of using timers a lot, I'm surprised
more isn't written about this in books, FAQs etc. I wrote it in my book,
but that's hardly mainstream. :-)

Just doing a web search now, a lot of sites seem to give the wrong advice...

-- 
Dr Jon D Harrop, Flying Frog Consultancy
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
0
Reply Jon 4/13/2005 7:34:08 AM

"Rolf Magnus" <ramagnus@t-online.de> wrote in message 
news:d3hkm4$vp7$00$1@news.t-online.com...
> fungus wrote:
>
>> Rolf Magnus wrote:
>>>
>>>
>>> Is there a reason to let you CPU idle instead of using its full power?
>>>
>>
>> Of course. He might want to bring other apps to
>> the front or something.
>
> Then he could lower the priority of his process. After all, that's what
> priorities are there for. So the process doesn't take CPU power that is
> needed for other ones.

Im more interested in ensuring that the application gets only the CPU cycles 
it needs rather than run at 100% even in a nice way. Both the timer function 
and idle methods seem to cause the CPU to churn unecessarily over what can 
only be unproductive code.

> 


0
Reply Steve 4/13/2005 8:57:32 AM

"Jon Harrop" <usenet@jdh30.plus.com> wrote in message 
news:425ccb5d$0$94531$ed2619ec@ptn-nntp-reader01.plus.net...
> fungus wrote:
>> Whatever...the advice give by JH si good. Don't
>> use timers, use the idle function.
>
> Given that newbies make the mistake of using timers a lot, I'm surprised
> more isn't written about this in books, FAQs etc. I wrote it in my book,
> but that's hardly mainstream. :-)

For GLUT this would appear to be the case, however in other situations 
timers produce a low overhead method of accurately synchronising or 
throttling application activity. Coming from a loosely embedded background 
where timers are used all the time effectively I'm surprised at the way GLUT 
timer functions work.

As for the idle function as an alternative to the timers, on its own this is 
still unproductive code running repeatedly even if it yields gracefully to 
other applications. To overcome this you would need to do a timed sleep; 
however Im not sure I want to block the single application (GLUT main loop?) 
thread and in any case this is a question of using a timer to block a task 
rather than using a timer to drive a task.

Im obviously not understanding something, your perseverance would be 
appreciated.

>
> Just doing a web search now, a lot of sites seem to give the wrong 
> advice...
>
> -- 
> Dr Jon D Harrop, Flying Frog Consultancy
> Objective CAML for Scientists
> http://www.ffconsultancy.com/products/ocaml_for_scientists 


0
Reply Steve 4/13/2005 9:08:23 AM

Steve wrote:
> For GLUT this would appear to be the case, however in other situations
> timers produce a low overhead method of accurately synchronising or
> throttling application activity.

Yes.

> Coming from a loosely embedded background 
> where timers are used all the time effectively I'm surprised at the way
> GLUT timer functions work.

I don't think glut's timers were designed to be this accurate, and I don't
think they were designed to drive fluid animations. They certainly aren't
the same kind of thing you'd expect to find in an embedded environment.

> As for the idle function as an alternative to the timers, on its own this
> is still unproductive code running repeatedly even if it yields gracefully
> to other applications. To overcome this you would need to do a timed
> sleep; however Im not sure I want to block the single application (GLUT
> main loop?) thread and in any case this is a question of using a timer to
> block a task rather than using a timer to drive a task.

The idle callback is yielding and then asking glut to redisplay (call the
display function to render a new frame of animation). I wouldn't call this
"unproductive code running repeatedly" as it is required (the same
functionality would have to be executed inside glut if it were not written
here) and it is only run once per frame, AFAIK.

Certainly, the following OCaml program uses virtually no CPU here (Linux,
freeglut and nVidia):

let () =
  ignore (Glut.init Sys.argv);
  ignore (Glut.createWindow "OpenGL Demo");
  GlClear.color (0.1, 0.3, 0.1);
  Glut.displayFunc (fun () -> GlClear.clear [ `color ]; Gl.flush ());
  Glut.idleFunc (Some (fun () -> Unix.sleep 1; Glut.postRedisplay(); ));
  Glut.mainLoop ()

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
0
Reply Jon 4/13/2005 9:28:34 AM

"Jon Harrop" <usenet@jdh30.plus.com> wrote in message 
news:425ce62f$0$94531$ed2619ec@ptn-nntp-reader01.plus.net...
> Steve wrote:
>> For GLUT this would appear to be the case, however in other situations
>> timers produce a low overhead method of accurately synchronising or
>> throttling application activity.
>
> Yes.
>
>> Coming from a loosely embedded background
>> where timers are used all the time effectively I'm surprised at the way
>> GLUT timer functions work.
>
> I don't think glut's timers were designed to be this accurate, and I don't
> think they were designed to drive fluid animations. They certainly aren't
> the same kind of thing you'd expect to find in an embedded environment.

I would add that they appear to be software derived also which would explain 
why the CPU activity hits 100% for a 1% application. Im guessing that they 
software poll the clock and fire when a threshold is exceeded.

>
>> As for the idle function as an alternative to the timers, on its own this
>> is still unproductive code running repeatedly even if it yields 
>> gracefully
>> to other applications. To overcome this you would need to do a timed
>> sleep; however Im not sure I want to block the single application (GLUT
>> main loop?) thread and in any case this is a question of using a timer to
>> block a task rather than using a timer to drive a task.
>
> The idle callback is yielding and then asking glut to redisplay (call the
> display function to render a new frame of animation). I wouldn't call this
> "unproductive code running repeatedly" as it is required (the same
> functionality would have to be executed inside glut if it were not written
> here) and it is only run once per frame, AFAIK.

Apologies if I am incorrect in this but Im pretty sure the idle function 
causes CPU churn.

As soon as an idle function is registered even if it does nothing but say 
increment a counter for example, this free runs utilising all available free 
CPU time. I reckon that it is replacing some self blocking idle loop within 
GLUT which correctly forces low CPU if there is nothing to do. It would only 
run once per frame if you were calling GLUTpostRedisplay in the idle 
function which would unblock the glut main loop.

Blocking the idle loop with a call to sleep is a case of using a system 
timer to do the same effective job that I was hoping could be done with GLUT 
timers.

>
> Certainly, the following OCaml program uses virtually no CPU here (Linux,
> freeglut and nVidia):
>
> let () =
>  ignore (Glut.init Sys.argv);
>  ignore (Glut.createWindow "OpenGL Demo");
>  GlClear.color (0.1, 0.3, 0.1);
>  Glut.displayFunc (fun () -> GlClear.clear [ `color ]; Gl.flush ());
>  Glut.idleFunc (Some (fun () -> Unix.sleep 1; Glut.postRedisplay(); ));
>  Glut.mainLoop ()

I assume 1 frame per second and low CPU due to the idle function self 
blocking.

>
> -- 
> Dr Jon D Harrop, Flying Frog Consultancy
> http://www.ffconsultancy.com 


0
Reply Steve 4/13/2005 9:48:51 AM

Steve wrote:
> 
> Apologies if I am incorrect in this but Im pretty sure the idle function 
> causes CPU churn.
> 

The documentation says:

"If enabled, the idle callback is  continu-
ously called when events are not being received."


I suggest the following idle func:

if (!veryBusy) {
   sleep(1);
}
else {
   glutPostRedisplay();
}


> Im obviously not understanding something, your perseverance 
> would be appreciated.

You're not understanding that GLUT is a cheap
hack to get OpenGL up and running easily, not
the basis of a realtime OS.  :-)



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/13/2005 12:50:29 PM

"fungus" <openglMY@SOCKSartlum.com> wrote in message 
news:AA87e.31621$US.20308@news.ono.com...
> Steve wrote:
>>
>> Apologies if I am incorrect in this but Im pretty sure the idle function 
>> causes CPU churn.
>>
>
> The documentation says:
>
> "If enabled, the idle callback is  continu-
> ously called when events are not being received."

Yes I remember reading that and it is also what Im seeing in my test code 
which is why I responded to the earlier post.

On its own the idle function is not a solution to the problem I posted, 
however if you combine it with a timer block (i.e. sleep) then it provides a 
work around to GLUT timer function CPU churn. I imagine the effect is of 
replacing a software derived timer with a hardware derived timer hence the 
low CPU utilisation with the sleep timer method.

Only trouble is if there are any side effects, I presume that blocking the 
idle function also blocks the glut main loop which in turn renders the 
application unresponsive to keyboard and mouse input etc.

>
>
> I suggest the following idle func:
>
> if (!veryBusy) {
>   sleep(1);
> }
> else {
>   glutPostRedisplay();
> }

Is usleep() the best timed blocking method for sub 1s frame intervals? The 
logic would be:

idle_func()
{
glutPostRedisplay();
usleep(100000);
}

giving a maximum update rate of 10Hz but slower during busy periods. Still 
worried about keyboard input responsiveness though.

>
>
>> Im obviously not understanding something, your perseverance would be 
>> appreciated.
>
> You're not understanding that GLUT is a cheap
> hack to get OpenGL up and running easily, not
> the basis of a realtime OS.  :-)

I am beginning to see the light, however the timer performance issue seems 
to be the only problem so far. It cant be that difficult to get hardware 
derived timer functions or can it?

Thanks FTB.
--
Steve

>
>
>
> -- 
> <\___/>
> / O O \
> \_____/  FTB.    For email, remove my socks. 


0
Reply Steve 4/13/2005 3:29:43 PM

Steve wrote:
> 
> Only trouble is if there are any side effects, I presume that blocking the 
> idle function also blocks the glut main loop which in turn renders the 
> application unresponsive to keyboard and mouse input etc.
> 

Ummmm...yes, but it's only for 0.001 seconds so
you're not going to notice.

> idle_func()
> {
> glutPostRedisplay();
> usleep(100000);
> }
> 
> giving a maximum update rate of 10Hz but slower during busy periods. Still 
> worried about keyboard input responsiveness though.
> 

So....er, maybe you could do it like this:

idle_func()
{
  if (++count == 100) {
    glutPostRedisplay();
  }
  usleep(1000);
}

You wouldn't count frames of course, you'd
call clock() and look at how much time has
passed.

I leave that code as an exercise for the reader.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/13/2005 4:07:24 PM

"fungus" <openglMY@SOCKSartlum.com> wrote in message 
news:2tb7e.31656$US.30801@news.ono.com...
> Steve wrote:
>>
>> Only trouble is if there are any side effects, I presume that blocking 
>> the idle function also blocks the glut main loop which in turn renders 
>> the application unresponsive to keyboard and mouse input etc.
>>
>
> Ummmm...yes, but it's only for 0.001 seconds so
> you're not going to notice.

sleep(1) = 1 second does it not?

Im just guessing that the application becomes unresponsive to user input, 
but it seems a likley outcome of the idle function is on the same thread as 
the GLUT main control loop.

>
>> idle_func()
>> {
>> glutPostRedisplay();
>> usleep(100000);
>> }
>>
>> giving a maximum update rate of 10Hz but slower during busy periods. 
>> Still worried about keyboard input responsiveness though.
>>
>
> So....er, maybe you could do it like this:
>
> idle_func()
> {
>  if (++count == 100) {
>    glutPostRedisplay();
>  }
>  usleep(1000);
> }

Of course, that would do the trick. The keyboard input handler in the glut 
main control loop (if blocked by sleeping the idle function) would be 
reactivated every 1ms giving plenty of time for the application to be 
responsive to user input.

>
> You wouldn't count frames of course, you'd
> call clock() and look at how much time has
> passed.

And whats more this scheme will be light on CPU but reasonably accurate on 
timing.

Nice talking this through with you FTB, I think you just solved my 
problem... thanks.

Its a pity that you have to jump through hoops just to replace GLUT timer 
functions. The fact you have to use a system timer (sleep) to do so is a bit 
galling seeing as GLUT could have done the same in the first place.

Do you agree that the GLUT timer function must be software derived (or maybe 
there is something funny going on with Cygwin which I am using for 
development). I assume so otherwise they could realistically be used for 
animation control which experienced OGL programmers dismiss outright.

>
> I leave that code as an exercise for the reader.
>
>
> -- 
> <\___/>
> / O O \
> \_____/  FTB.    For email, remove my socks. 


0
Reply Steve 4/13/2005 4:59:27 PM

In article <425ce62f$0$94531$ed2619ec@ptn-nntp-reader01.plus.net>,
 Jon Harrop <usenet@jdh30.plus.com> wrote:

>I don't think glut's timers were designed to be this accurate, and I don't
>think they were designed to drive fluid animations. They certainly aren't
>the same kind of thing you'd expect to find in an embedded environment.

I've got a simple interactive OpenGL animation program running under 
SuSE 9.1, using glutTimerFunc to run 25 frames per second. It's a simple 
2D animation, so it shouldn't be taxing my hardware at all. My "top" 
display shows it using less than 1% CPU.

So it *is* possible to use glut's timers to do fluid animation, with 
minimal CPU overhead.
0
Reply Lawrence 4/25/2005 4:03:46 AM

"Lawrence D'Oliveiro" <ldo@geek-central.gen.new_zealand> wrote in message 
news:ldo-C1719A.16034625042005@lust.ihug.co.nz...
> In article <425ce62f$0$94531$ed2619ec@ptn-nntp-reader01.plus.net>,
> Jon Harrop <usenet@jdh30.plus.com> wrote:
>
>>I don't think glut's timers were designed to be this accurate, and I don't
>>think they were designed to drive fluid animations. They certainly aren't
>>the same kind of thing you'd expect to find in an embedded environment.
>
> I've got a simple interactive OpenGL animation program running under
> SuSE 9.1, using glutTimerFunc to run 25 frames per second. It's a simple
> 2D animation, so it shouldn't be taxing my hardware at all. My "top"
> display shows it using less than 1% CPU.
>
> So it *is* possible to use glut's timers to do fluid animation, with
> minimal CPU overhead.

Could be the difference between Linux and Win32 libs, your findings are more 
what I would expect but am not getting on Win32. Even with a single 1 sec 
timer func and no work at all the CPU goes to 100% which indicates software 
derived timers on Win32.



0
Reply Steve 4/25/2005 9:50:41 PM

Steve wrote:
>>
>>So it *is* possible to use glut's timers to do fluid animation, with
>>minimal CPU overhead.
> 
> Could be the difference between Linux and Win32 libs, your findings are more 
> what I would expect but am not getting on Win32. Even with a single 1 sec 
> timer func and no work at all the CPU goes to 100% which indicates software 
> derived timers on Win32.
> 

Could be, but timers are a still a bad way to do it.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/26/2005 7:38:48 AM

In article <gembe.34572$dr.30204@news.ono.com>,
 fungus <openglMY@SOCKSartlum.com> wrote:

>Steve wrote:
>>>
>>>So it *is* possible to use glut's timers to do fluid animation, with
>>>minimal CPU overhead.
>> 
>> Could be the difference between Linux and Win32 libs, your findings are more 
>> what I would expect but am not getting on Win32. Even with a single 1 sec 
>> timer func and no work at all the CPU goes to 100% which indicates software 
>> derived timers on Win32.
>
>Could be, but timers are a still a bad way to do it.

Why is it bad? You want a time notification, use a timer.
0
Reply Lawrence 4/26/2005 9:34:13 AM

Lawrence D�Oliveiro wrote:

>>Could be, but timers are a still a bad way to do it.
> 
> Why is it bad? You want a time notification, use a timer.

A "time notification" isn't what you want.

a) It causes temporal aliasing (it's not
synchronous to your rendering loop).

b) It's harder to program (or this thread
wouldn't exist).


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/26/2005 9:59:13 AM

In article <Uhobe.38078$US.7599@news.ono.com>,
 fungus <openglMY@SOCKSartlum.com> wrote:

>Lawrence D�Oliveiro wrote:
>
>>>Could be, but timers are a still a bad way to do it.
>> 
>> Why is it bad? You want a time notification, use a timer.
>
>A "time notification" isn't what you want.
>
>a) It causes temporal aliasing (it's not
>synchronous to your rendering loop).

The routine you install with glutTimerFunc updates your model and calls 
glutPostRedisplay, which triggers a call to your rendering routine as 
installed with glutDisplayFunc. So it is synchronous.

>b) It's harder to program (or this thread wouldn't exist).

But it's what the beginning OpenGL tutorials recommend you use. I got my 
examples from the Red Book.
0
Reply Lawrence 4/26/2005 10:13:41 AM

Lawrence D�Oliveiro wrote:
> In article <Uhobe.38078$US.7599@news.ono.com>,
>  fungus <openglMY@SOCKSartlum.com> wrote:
> 
> 
>>Lawrence D�Oliveiro wrote:
>>
>>
>>>>Could be, but timers are a still a bad way to do it.
>>>
>>>Why is it bad? You want a time notification, use a timer.
>>
>>A "time notification" isn't what you want.
>>
>>a) It causes temporal aliasing (it's not
>>synchronous to your rendering loop).
> 
> 
> The routine you install with glutTimerFunc updates your model and calls 
> glutPostRedisplay, which triggers a call to your rendering routine as 
> installed with glutDisplayFunc. So it is synchronous.
> 

In a perfect world, where the renderer can
keep up with the timer events, yes. In the
real world our computers chug, swap to pagefiles,
run software renderers, etc. Updating the model
while the other one is still rendering will
cause headaches. In practice the idle function
works much better because you can understand
what's going on.

>>b) It's harder to program (or this thread wouldn't exist).
> 
> 
> But it's what the beginning OpenGL tutorials recommend you use. I got my 
> examples from the Red Book.

And they were written by god?

I'm not saying it's impossible to do, I'm
sure you personally get away with it, but as
advice to a newbie it's wrong.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/26/2005 10:46:54 AM

In article <C_obe.38084$US.10399@news.ono.com>,
 fungus <openglMY@SOCKSartlum.com> wrote:

>Lawrence D�Oliveiro wrote:
>
>> But it's what the beginning OpenGL tutorials recommend you use. I got my 
>> examples from the Red Book.
>
>And they were written by [a] god?

Yes!

>I'm not saying it's impossible to do, I'm
>sure you personally get away with it, but as
>advice to a newbie it's wrong.

If it's wrong for newbies, then what's it doing in the most 
authoritative tutorial?

I think maybe it's best to leave the newbie advice to the well-known 
tutorials. They can always progress to your level later.
0
Reply Lawrence 4/26/2005 10:12:54 PM

"Lawrence D�Oliveiro" <ldo@geek-central.gen.new_zealand> wrote in message 
news:ldo-E1CD12.10125427042005@lust.ihug.co.nz...
> In article <C_obe.38084$US.10399@news.ono.com>,
> fungus <openglMY@SOCKSartlum.com> wrote:
>
>>Lawrence D�Oliveiro wrote:
>>
>>> But it's what the beginning OpenGL tutorials recommend you use. I got my
>>> examples from the Red Book.
>>
>>And they were written by [a] god?
>
> Yes!
>
>>I'm not saying it's impossible to do, I'm
>>sure you personally get away with it, but as
>>advice to a newbie it's wrong.
>
> If it's wrong for newbies, then what's it doing in the most
> authoritative tutorial?
>
> I think maybe it's best to leave the newbie advice to the well-known
> tutorials. They can always progress to your level later.

This newbie is still confused that you have to use a sleep (a system timer) 
in the idle function rather than a true (GLUT provided) timer to avoid 100% 
CPU activity.

Why does CPU activity go to 100% whenever you use even the simplest timer on 
a slow interval on Win32?

If possible it would be useful if you could post the skeleton of your timer 
loop so I can compile it up on Win32 and see if it produces the same max CPU 
activity. Just say no if this is too much of an imposition.

Steve 


0
Reply Steve 4/26/2005 11:27:50 PM

Lawrence D�Oliveiro wrote:
>
> [...] 
> 
> The routine you install with glutTimerFunc updates your model and calls 
> glutPostRedisplay, which triggers a call to your rendering routine as 
> installed with glutDisplayFunc. So it is synchronous.

Depends on how glutPostRedisplay is implemented... if it just (as the
name suggests) posts a message into a queue, there is no way to say
when exactly the rendering will occur.

As for the timer: I don't know how it is implemented in Windows, but
if it utilizes any windows timer messages, you're in _big_ trouble...

>>b) It's harder to program (or this thread wouldn't exist).
> 
> 
> But it's what the beginning OpenGL tutorials recommend you use. I got my 
> examples from the Red Book.

Which may be the easiest way to get your animation up and running in a
very short time...

To do it "right", don't use the GLUT infrastructure. Instead use SDL or
some other OS-independent framework (or the Windowing system's own API)
and implement a "main loop" which decouples rendering and animation
updates (and dispatches messages) consistently.
You only have to write it once and can reuse it in all your animations.

But this is too off-topic to be introduced in the Red Book, which of
course focuses on OpenGL.

cu, Markus Seeger
0
Reply Markus 4/27/2005 12:37:52 AM

In article <W7Abe.20375$G8.15127@text.news.blueyonder.co.uk>,
 "Steve" <steve_mowbray@hotmail.com> wrote:

>If possible it would be useful if you could post the skeleton of your timer 
>loop so I can compile it up on Win32 and see if it produces the same max CPU 
>activity. Just say no if this is too much of an imposition.

Sure, here's the complete routine I pass to glutTimerFunc:

static void HandleAnimate
  (
    int Unused
  )
  /* period task which updates the movement of the points. */
  {
    uint i;
    uint NewParticlesToAdd = MaxNewParticlesPerSecond / FramesPerSecond;
    LastMouse[0] = ThisMouse[0];
    LastMouse[1] = ThisMouse[1];
    LastMouse[2] = ThisMouse[2];
    LastMouse[3] = ThisMouse[3];
    ThisMouse[0] = MousePos[0];
    ThisMouse[1] = MousePos[1];
    ThisMouse[2] = MousePos[2];
    ThisMouse[3] = MousePos[3];
    LastMouseD[0] = ThisMouseD[0];
    LastMouseD[1] = ThisMouseD[1];
    LastMouseD[2] = ThisMouseD[2];
    ThisMouseD[0] = ThisMouse[0] - LastMouse[0];
    ThisMouseD[1] = ThisMouse[1] - LastMouse[1];
    ThisMouseD[2] = ThisMouse[2] - LastMouse[2];
    for (i = 0; i < MaxParticles; ++i)
      {
        if (ParticleExists[i])
          {
            GLfloat * const Pos = ParticlePos[i];
            GLfloat * const Velocity = ParticleVelocity[i];
            Pos[0] += Velocity[0];
            Pos[1] += Velocity[1];
            Pos[2] += Velocity[2];
            Velocity[0] += Gravity[0];
            Velocity[1] += Gravity[1];
            Velocity[2] += Gravity[2];
            if (Pos[0] < WindowLeft || Pos[0] >= WindowRight)
              {
                Pos[0] -= (1.0 + BounceFactor) * Velocity[0];
                Velocity[0] = - Velocity[0] * BounceFactor;
                ++ParticleAge[i];
              } /*if*/
            if (Pos[1] < WindowBottom || Pos[1] >= WindowTop)
              {
                Pos[1] -= (1.0 * BounceFactor) * Velocity[1];
                Velocity[1] = - Velocity[1] * BounceFactor;
                ++ParticleAge[i];
              } /*if*/
            if (ParticleAge[i] >= MaxBounce)
              {
                ParticleExists[i] = false; /* kill particle */
              } /*if*/
          }
        else if (!MouseDown && NewParticlesToAdd != 0)
          {
            RestartParticle(i);
            --NewParticlesToAdd;
          } /*if*/
      } /*for*/
    NewParticleHue += HueCyclesPerSecond / FramesPerSecond;
    if (NewParticleHue >= 1.0)
      {
        NewParticleHue -= 1.0;
      } /*if*/
    NewParticleSaturation += SaturationCyclesPerSecond / FramesPerSecond;
    if (NewParticleSaturation >= 1.0)
      {
        NewParticleSaturation -= 1.0;
      } /*if*/
    glutPostRedisplay();
    glutTimerFunc(1000 / FramesPerSecond, HandleAnimate, 0);
  } /*HandleAnimate*/
0
Reply Lawrence 4/27/2005 5:23:09 AM

Lawrence D�Oliveiro wrote:
>>If possible it would be useful if you could post the skeleton of your timer 
>>loop so I can compile it up on Win32 and see if it produces the same max CPU 
>>activity. Just say no if this is too much of an imposition.
> 
> 
> Sure, here's the complete routine I pass to glutTimerFunc:
> 

This is a perfect demonstration of how not
to use timers. The trap is that you start
dumping all your code in the timer func.

If you use timers they should limit themselves
to calling glutPostRedisplay() and nothing more.
All update code should go into the render callback.


>     uint NewParticlesToAdd = MaxNewParticlesPerSecond / FramesPerSecond;

Wrong - you don't know how much time has passed
since the last update. Timers aren't garanteed to
happen regularly, all you know is that "at least"
the amount of time has passed.

>     for (i = 0; i < MaxParticles; ++i)
>       {
>         if (ParticleExists[i])
>           {

Sure...why not mess with the data while the main
thread is still rendering it.

>             GLfloat * const Pos = ParticlePos[i];
>             GLfloat * const Velocity = ParticleVelocity[i];
>             Pos[0] += Velocity[0];
>             Pos[1] += Velocity[1];
>             Pos[2] += Velocity[2];

Nope. You should be adding "velocity*ElapsedTime".
On slow machines your animations will run more
slowly.


....etc.



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/27/2005 9:07:27 AM

Lawrence D�Oliveiro <ldo@geek-central.gen.new_zealand> wrote in message news:<ldo-9B7BA5.17230927042005@lust.ihug.co.nz>...
> In article <W7Abe.20375$G8.15127@text.news.blueyonder.co.uk>,
>  "Steve" <steve_mowbray@hotmail.com> wrote:
> 
> >If possible it would be useful if you could post the skeleton of your timer 
> >loop so I can compile it up on Win32 and see if it produces the same max CPU 
> >activity. Just say no if this is too much of an imposition.
> 
> Sure, here's the complete routine I pass to glutTimerFunc:
>
{snipped code} 
>   } /*HandleAnimate*/


Thanks Lawrence - it was worthwhile to check that you were doing
pretty much the same as me and getting low CPU on Linux. I have
stripped back the GLUT timer function to do nothing in the following
which _still_ uses 100% CPU in either MSVS build or CygWin build for
Win32.

However, you should check the solution given elsewhere in this thread
to use the idle function and sleep, which has solved my general
problem but left me mystified about the Win32 GLUT timer performance.

(Also note that running Windows media player prior to running my GLUT
timer based opengl apps considerably improves the timing accuracy for
some reason but tha would be another question for another time)


#include "stdafx.h"

#include <GL/glut.h>


void reshape_func(int width, int height)
{
}

void keyboard_func(unsigned char key, int x, int y)
{
}

void redisplay_func(void)
{
}

void idle_func(void)
{
}

void timer_func(int timer_index)
{
	glutTimerFunc(1000, timer_func, 0);
}

int _tmain(int argc, _TCHAR* argv[])
{
	glutInit(&argc, argv);
	glutInitWindowSize(100, 100);
	glutInitWindowPosition(100, 100);
	
	glutCreateWindow("timer test");
	
	glutDisplayFunc(redisplay_func);
	glutKeyboardFunc(keyboard_func);
	glutReshapeFunc(reshape_func);
//	glutIdleFunc(idle_func);

	glutTimerFunc(1000, timer_func, 0);

	glutMainLoop();
	
	return 0;
}
0
Reply steve_mowbray 4/27/2005 8:37:13 PM

In article <nDIbe.34739$dr.23199@news.ono.com>,
 fungus <openglMY@SOCKSartlum.com> wrote:

>If you use timers they should limit themselves
>to calling glutPostRedisplay() and nothing more.
>All update code should go into the render callback.

No, updating must be time-dependent. The render callback could be called 
more than once per frame, e.g. if a new part of the window has been 
uncovered, so it could end up doing extra updating in this case, if your 
advice were followed.

>On slow machines your animations will run more
>slowly.

On my machine, it's already using less than 1% CPU. A machine that's 
slow enough for your advice to make sense, I wouldn't want to use.
0
Reply Lawrence 4/27/2005 11:25:31 PM

> No, updating must be time-dependent.

No, it doesn't. All you want to do is to know the correct time when 
starting to render a frame. Also remember that there is latency of 
atleast one frame because of displaying the backbuffer, in practise the 
latency is much much more so no matter what you do the time will be 
wrong. Unless you extrapolate it, but then you cannot really use that in 
a situation where you get user input and expect again to be correct. 
It's one or the another.

When you are doing things like physics simulation, you want to update 
the simulation in "ticks", which are granularity units of time so that 
no matter what performance the client system has everyone gets the same 
simulation.

 > The render callback could be called
> more than once per frame, e.g. if a new part of the window has been 
> uncovered, so it could end up doing extra updating in this case, if your 
> advice were followed.

That's why the render callback should be something fast instead of 
rendering the whole frame. With OpenGL, good luck with that. But then 
again, you ar inventing a problem where none exists in practise.

> On my machine, it's already using less than 1% CPU. A machine that's 
> slow enough for your advice to make sense, I wouldn't want to use.

You'll know better eventually and grasp what is he trying to signal, for 
now I would stop this discussion and get things working one way or 
another. Don't be surprised that code that works on your computer might 
not work so well on another (this applies to me aswell as everyone ;)

Regards,
kellopeli :)
0
Reply kellopeli 4/28/2005 4:18:09 AM

> sleep(1) = 1 second does it not?

1 ms
0
Reply kellopeli 4/28/2005 4:19:48 AM

Lawrence D�Oliveiro wrote:
> 
> No, updating must be time-dependent. The render callback could be called 
> more than once per frame, e.g. if a new part of the window has been 
> uncovered, so it could end up doing extra updating in this case, if your 
> advice were followed.
> 

For "correct" results, updating must be done in fixed
sized steps. I do these steps in my render function
so I know I always do the correct amount.

What mechanism do you use to compensate when your timer
message gets delayed?

>>On slow machines your animations will run more
>>slowly.
> 
> On my machine, it's already using less than 1% CPU. A machine that's 
> slow enough for your advice to make sense, I wouldn't want to use.

The problem is you're talking about *your* program
running on *your* computer/OS.... then generalising
your case to all other programs.

In a more general world, timers are a bad idea.



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/28/2005 8:48:24 AM

fungus wrote:

>>     uint NewParticlesToAdd = MaxNewParticlesPerSecond / FramesPerSecond;
> 
> Wrong - you don't know how much time has passed
> since the last update. Timers aren't garanteed to
> happen regularly, all you know is that "at least"
> the amount of time has passed.

Same is true for sleep-like functions.

>>     for (i = 0; i < MaxParticles; ++i)
>>       {
>>         if (ParticleExists[i])
>>           {
> 
> Sure...why not mess with the data while the main
> thread is still rendering it.

"main thread"? I have seen no threads. What are you talking about?

0
Reply Rolf 4/28/2005 9:14:18 AM

kellopeli wrote:

>> sleep(1) = 1 second does it not?
> 
> 1 ms

http://www.opengroup.org/onlinepubs/007908799/xsh/sleep.html
0
Reply Rolf 4/28/2005 9:42:23 AM

Rolf Magnus wrote:
>fungus wrote:
>>
>>Wrong - you don't know how much time has passed
>>since the last update. Timers aren't garanteed to
>>happen regularly, all you know is that "at least"
>>the amount of time has passed.
> 
> 
> Same is true for sleep-like functions.
> 

How about functions which actually look at
the clock instead of relying on the OS task
switcher for "timing"?



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/28/2005 9:49:15 AM

In article <vr1ce.34937$dr.29202@news.ono.com>,
 fungus <openglMY@SOCKSartlum.com> wrote:

>The problem is you're talking about *your* program
>running on *your* computer/OS.... then generalising
>your case to all other programs.
>
>In a more general world, timers are a bad idea.

It's not that I don't trust you--I'm sure you must have a great deal of 
expertise in your particular area. But when it comes to listening to you 
or listening to the Red Book--I think the Red Book is a little more 
relevant to my needs at the moment. Thanks for trying to help anyway.
0
Reply Lawrence 4/28/2005 10:03:37 AM

fungus wrote:

> Rolf Magnus wrote:
>>fungus wrote:
>>>
>>>Wrong - you don't know how much time has passed
>>>since the last update. Timers aren't garanteed to
>>>happen regularly, all you know is that "at least"
>>>the amount of time has passed.
>> 
>> 
>> Same is true for sleep-like functions.
>> 
> 
> How about functions which actually look at
> the clock instead of relying on the OS task
> switcher for "timing"?

Those would have the problem that the OP is encountering. A program only
relying on them would need 100% CPU all the time.

0
Reply Rolf 4/28/2005 10:19:32 AM

Lawrence D�Oliveiro wrote:
> 
> 
> It's not that I don't trust you--I'm sure you must have a great deal of 
> expertise in your particular area. But when it comes to listening to you 
> or listening to the Red Book--I think the Red Book is a little more 
> relevant to my needs at the moment. Thanks for trying to help anyway.

I think that's more because timers make
tutorial code simpler rather then for
any good technical reason.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/28/2005 10:20:45 AM

Rolf Magnus wrote:
> 
>>How about functions which actually look at
>>the clock instead of relying on the OS task
>>switcher for "timing"?
> 
> Those would have the problem that the OP is encountering. A program only
> relying on them would need 100% CPU all the time.
> 

Now we *really are* going around in circles.

A solution to the "100% CPU" problem was given
in about the third post in the thread (and the
OP reported that it worked).


Accurate timing of an animation is not somthing
which will be solved using GLUT functions, you
need some proper timing code for that.

-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/28/2005 10:28:09 AM

Lawrence D�Oliveiro wrote:
> It's not that I don't trust you--I'm sure you must have a great deal of
> expertise in your particular area. But when it comes to listening to you
> or listening to the Red Book--I think the Red Book is a little more
> relevant to my needs at the moment. Thanks for trying to help anyway.

Listen to fungus and not to the Red Book on this one. The Red Book is
excellent, but it does contain several bits of bad advice which are just
contrived examples to demonstrate functionality and are definitely not
things that you should consider doing in practice.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
0
Reply Jon 4/28/2005 12:25:49 PM

>>>sleep(1) = 1 second does it not?
>>
>>1 ms
> 
> http://www.opengroup.org/onlinepubs/007908799/xsh/sleep.html

Sorry, I was thinking of ::Sleep() not ::sleep() my bad, but then again, 
I don't rely on ad-hocs so I cannot be expected to remember all minute 
details so maybe I shouldn't post if not 100% sure.. :)

0
Reply kellopeli 4/28/2005 1:28:15 PM

Jon Harrop wrote:
> The Red Book is excellent, but it does contain several
> bits of bad advice which are just contrived examples to
> demonstrate functionality and are definitely not
> things that you should consider doing in practice.
> 

The Red Book exists to teach OpenGL, not to teach
accurate timing.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 4/28/2005 2:01:24 PM

46 Replies
533 Views

(page loaded in 0.317 seconds)

Similiar Articles:












7/23/2012 10:04:14 AM


Reply: