It sounds about right, here’s the general steps for the approach I took:
- 
We already had a “TopLevelWindow” class for our plugins that was used to handle certain settings like plugin size and such… this is the class I attached the OpenGLContextto
- 
I updated our TopLevelWindowto addOpenGLRendererto the classes it’s deriving from. I didn’t explicitly usesetComponentPaintingEnabled(false)because we allow component painting still. HOWEVER, make sure that any components that “fill” the window (including thisTopLevelWindow) usesetOpaque(true). This is what allows the OpenGL rendering to show through when using the other components described below.
- 
Made a RenderViewclass that inherits bothOpenGLRendererandComponent. These are able to be positioned anywhere in the UI, essentially. This are also markedsetOpaque(true). When these are opaque and theTopLevelWindowis opaque, you can skip drawing theRenderViewbackground and the OpenGL rendering you’re doing will show through the component painting!
- 
Added a Array<RenderView*> renderersmember to theTopLevelWindow. When theOpenGLRenderermethods are called likenewOpenGLContextCreated(),renderOpenGL(),openGLContextClosing()theTopLevelWindowreally just iterates that array and calls those methods for each item
- 
Before actually calling renderOpenGL(), we had to ensure that transparency was enabled (glEnable(GL_BLEND)and friends) and ensure that the viewport was set correctly. The viewport is based on supplyinggetLocalArea()withRenderView*, RenderView.getLocalBounds()and multiplying the result byOpenGLContext::getRenderingScale(). Our plugins allow for resizable windows, so we also had to take our own scale into account as well as that context scale.
- 
OPTIONAL: Our plugins have features that require adding, removing, and re-ordering the renderers at run-time. Because these operations would come from the main thread, I had to essentially make two OpenGLRenderer*queues and add methods that atomically let you add/remove renderers. The methods usestd::atomic_flagto ensure that only one thing is manipulating the queues at a time, letting us properly set up or tear down the target renderers. For example, if you were to add a renderer while the OpenGL loop is running, you couldn’t call itsrenderOpenGL()method until calling itsnewOpenGLContextCreated()method (assuming the renderer needs to allocate buffers etc., which is usually the case). Similarly, renderers in the removal queue have theirrenderOpenGL()callback called for the last time followed byopenGLContextClosing()and are then subsequently removed from therenderersarray.
- 
OPTIONAL: Finally, RenderViewused the same approach as above and held its own array/queues ofOpenGLRenderer*. This is mostly because of the previous point: we’ll draw a grid, and RTA display, and an EQ curve all in the same view. If you don’t need that (i.e. eachRenderViewreally just draws one thing) then you can just make a custom subclass ofRenderVieweach time and write your OpenGL drawing code in the subclass
Sorry if that’s long winded  but let me know if you have any other questions and I’ll try to answer them as best as I can! The whole process was very annoying for me so I’d like to help people out in this regard.
 but let me know if you have any other questions and I’ll try to answer them as best as I can! The whole process was very annoying for me so I’d like to help people out in this regard.
