So I am about to enter the world of GUI and graphics programming, and I am looking at the best way to incorporate procedural graphics into JUCE.
If I configure the most basic component, let’s say a standard hello world component and run it, I couldn’t be happier with the CPU load. It barely registers.
But, If I add a timer to the component, even with nothing occurring in the paint function, and call repaint() at 60 hz, immediately the load jumps to ~40%. (according to htop).
Comment out repaint() and we’re down to an acceptable 1%.
Bring back in repaint(), have a paint function that draws an ellipse, and now my CPU is grumbling at ~60%
Am I doing something wrong, is this acceptable/standard? Should I be looking at drawing with OpenGL (or other methodology) if I wish to be doing any kind of animation at all?
Here’s the code, as simple as it gets:
class MainComponent : public Component, private Timer
int totalUpdates = 0;
int posX = 0;
setSize (600, 400);
posX = totalUpdates % getWidth();
void timerCallback() override
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.setColour (Colours::white);
// g.drawEllipse (posX, 0, 50, 50, 2);
void resized() override
// This is called when the MainComponent is resized.
// If you add any child components, this is where you should
// update their positions.
Also you might want to look into enabling OpenGL if you want to do that kind of graphics that continuously repaints itself with a timer. I think the generally recommended approach with Juce if you don’t use OpenGL is to repaint only when really necessary. (That can be a real pain to actually implement, though…And if I’ve myself often just resorted to using timers that do the repaint call. But I usually use a more conservative time interval for the timer.)
You can quite easily enable OpenGL to be used for any Component in Juce. The paint code doesn’t even need to change. But since using OpenGL that way is quite high level, it might not always work optimally. You will just have to test it out to see if it works and helps. edit2 : now that I’ve investigated this a bit further, it seems it’s not helpful at all for regular paint() code. You really do need to write actual OpenGL code to get any benefits.
edit : I am now testing the Juce OpenGLContext in my plugin. Enabling it actually increases the CPU usage, while also taking GPU resources… So clearly these things are not so simple.
Yeah one issue with OpenGL in JUCE is the renderer still performs the edge-table rasterization of geometry, using the OpenGLContext simply caches the results to GL textures. Makes re-using the caches super quick but the rasterization process doesn’t change from the software renderer. If you have components that are calling repaint often you can still see a pretty decent CPU load for that reason