Not being able to trigger a context creation is awkward.
In any platform, you have the usual:
- create context
- perform OpenGL work
- destroy context
Since Juce doesn’t allow the step 1, we have to rely on hoping the framework will sometime call us back, but it’s not clear when it’ll do so and in what thread/state.
I think being able to trigger step 1 from outside is a minimum. If you think it’s too “hacky”, please at least make it protected so only “power” user will be able to do so.
Also, not being able to hook into the rendering thread is too restrictive, but can be worked against (even if it’s ugly for the code required to do so).
Being imposed on the refreshing rate is not a good design. I don’t want to render my scene at 60fps, if I’m doing video rendering work at 25fps.
Worst, I usually render my scene only on a specific event (if something changed in the scene for example), and with the current design I can’t do so.
Concerning the OpenGL rendering thread, you should at least allow the user to start his own thread (again, with a protected overload), or split the OpenGLRenderingThread to call “threadJustStarted(Context &)” before entering the main thread loop, so we can put initialization in there, “threadWait(Context &)” for the wait time, and so on.
Ideally, please change the newContextCreated method signature with a bool saying if it’s inside the rendering thread or not.
Having initialization in the “renderOpenGL()” method is ugly IMHO.
Same should happen for “threadAboutToStop(Context &)”.
In fact, the more I think about it, the more I think the current design is not clean. You’re trying to mix two different behaviour in a single interface.
You might prefer to have a “OpenGLComponent” and a “OpenGLThreadedComponent”.
In that case, the corresponding documentation should say:
/** In an OpenGLComponent, the context is usually created on-the-fly when first needed.
It can be recreated, in case the underlying peer require so.
You can force context creation by calling the "createContext()" method in your child class, in case you actually need it.
A timer can be started to trigger calling renderOpenGL().
Buffer swaps are done automatically. */
/** In a OpenGLThreadComponent, due to some limitation with some platform, a context is first created on the message thread.
Then, it's recreated again in the rendering thread.
You can force context creation by calling the "createContext()" method in your child class, but you need to respect the rule above (else it'll probably fail).
You need to provide a rendering thread that'll call renderOpenGL() at regular interval.
Buffer swaps are done automatically */