Migrating to new OpenGL classes


#1

I have a JUCE v.1.53 application that makes extensive use of OpenGLComponents. I’m in the process of upgrading to the latest version of JUCE, but I’ve been having trouble getting OpenGL rendering to behave correctly.

I’ve tried two approaches so far:

  1. Turn each OpenGLComponent into a Component and OpenGLRenderer, and attach each one to its own OpenGLContext. This led to the components being rendered, but CPU load was very high when the program was idle (>50% on a dual-core Linux box).

  2. Attach the MainWindow’s content component to an OpenGLContext, with setComponentPaintingEnabled equal to “true”. This led (somewhat expectedly) to none of the sub-components being rendered and (unexpectedly) a high CPU load when idle.

It would be extremely helpful if someone had a working OpenGL application I can use as a model (besides the JUCE demo, which is too basic). I’d also appreciate a quick explanation of how to replicate the functionality of an OpenGLComponent using the new classes. It would be nice to better understand the rationale behind the recent upgrades, so I don’t have to stumble onto a solution through trial-and-error.

Forgive me if my knowledge of OpenGL contexts sounds naive. The previous version of JUCE made OpenGL ridiculously simple, so I didn’t have to dive into the details.

Thanks for any advice!


#2
  1. I’m not a specialist of the older OpenGLComponent, but each new OpenGLContext have its own drawing thread.
    Perhaps your Linux-Box GPU driver do not like multi-threaded / multi-context.
    You should check witch thread use more CPU: Juce message thread or one of your OpenGLContext thread.
    If the OpenGLContext thread is responsible, prefer VBO, PBO, shader usage and context sharing instead of old glBegin/glEnd fixed pipeline functions.
    It could reduce CPU/Driver operations and memory bandwidth consumption who could be multiplied by the number of your OpenGLContext.

  2. Take care that Component attached to an OpenGLContext could not have children Component attached to OpenGLContext.

Good luck.


#3

The problem is definitely with the Juce Message Thread, which is using 24% CPU when the program is idle.

At the moment I have 4 components with their own OpenGLContext. Each of these components is also an OpenGLRenderer and a Timer, and uses the renderOpenGL() method to draw itself. The contexts have “setComponentPaintingEnabled” set to “false.”

In each renderOpenGL() method, the component gets the MessageManagerLock before making any OpenGL calls, as in the JuceDemo.

The application also seg faults upon closing, even though all of the contexts have been detached.

What else can I try? Any code examples would be greatly appreciated.


#4

OK, that’s your problem. You’ve told four rendering threads to all fight over the main thread. The demo only uses the main thread for component stuff. If you can avoid it, do - that’s the point of a background rendering component.

If you have to lock (try really hard to find another design though) do it for the absolute minimum time.

Bruce


#5

I was experiencing similarly high CPU loads before I added the locking. While it may not be the right thing to do, it definitely isn’t the source of the problem.

Any other suggestions?


#6

OK, looks like this is also a problem with the JuceDemo.

At least on Linux, the OpenGL demo uses 24% CPU as long as it’s active.

In the demo from JUCE 1.53, the OpenGL demo only uses 2% CPU.

Has anyone else experienced this? Unless there’s an easy fix, I’ll have to stick with JUCE 1.53. I need OpenGL for my application.


#7

You can’t compare the new GL demo with the 1.53 one! The old one did nothing but render some basic GL, but the new one also demonstrates the 2D overlay rendering stuff, which involves syncing with the message queue, using GL to render components into a frame buffer, etc etc. Of course it’ll use more CPU!


#8

Fair enough. If I replace the demo’s entire “renderOpenGL()” method with this:

 void renderOpenGL()
{
    glClearColor (0.25f, 0.25f, 0.25f, 0.0f);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

the CPU load is comparable to the 1.53 demo.

However, switching from using the Software Renderer to the OpenGL Renderer in any of the other demos invariably increases processor load, sometimes as much as 200% (this is on a Mac now, with yesterday’s tip). Is this expected?


#9

Whether or not the GL renderer is faster depends on what you’re drawing. For some things (e.g. big transformed images), it’ll be vastly faster. But if you have many small things to draw, then it might be slower. YMMV, basically.