Hello jucers,
been wondering… How do you even make a fluent animation in JUCE? That’s such a basic thing I am really surprised not to find any questions about it. I’ll explain what I mean…
My application was a little bit laggy even in release mode, so in the end I decide to break it down to utter basics…
And I ended up with this simple AnimatedAppComponent:
//#define HIGH_RES_TIMER
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainContentComponent : public AnimatedAppComponent
#ifdef HIGH_RES_TIMER
, public HighResolutionTimer
#endif
{
public:
//==============================================================================
MainContentComponent() : img(Image::PixelFormat::RGB, 120, 60, true) {
setSize (400, 200);
setFramesPerSecond (60);
#ifdef HIGH_RES_TIMER
HighResolutionTimer::startTimer(16);
#endif
}
~MainContentComponent()
{
}
void step() {
static int xpos = 0;
static int radius = 1.5f;
static bool ascending = true;
Graphics g(img);
g.fillAll(Colours::black);
g.setColour(Colours::white);
g.fillEllipse(xpos - radius, 30, radius * 2, radius * 2);
xpos += (ascending) ? 1 : -1;
if (xpos == 0 || xpos == img.getWidth())
ascending = !ascending;
}
void update() override
{
// This function is called at the frequency specified by the setFramesPerSecond() call
// in the constructor. You can use it to update counters, animate values, etc.
#ifndef HIGH_RES_TIMER
step();
#endif
}
#ifdef HIGH_RES_TIMER
void hiResTimerCallback() {
step();
}
#endif
void paint (Graphics& g) override
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
g.drawImage(img, juce::Rectangle<float>(0, 0, getWidth(), getHeight()));
}
void resized() override
{
}
private:
//==============================================================================
Image img;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
It’s just a ball bouncing from left to right in a really small image. The simplest thing you can think of…
Note that performance is not an issue. The frame rate is right what it should be and the CPU load is very low (about 7%). But obviously the timing is not right. Some frames take longer and some are faster. You could call it a jitter, or micro stuttering…
Of course the simple explanation is that the basic message based timer is just not that precise to be used for animation timing. Well, fair enough. So I decided to try the HighResolutionTimer (see the HIGH_RES_TIMER macro). But it does not help at all. I would even say it’s worse (though thats only my impression).
I think that this is such a basic question there has to be some best practice for that. How would you go about it?
Thanks
//For this test I am using 64 bit Windows 7

