OpenGL component transparent until first render


#1

Hello, everyone. I could not find a solution for this issue in the forums, let me ask in case anyone knows how to solve it.

The issue:
I have a tabbedComponent, and I set an OpenGLAppComponent as the content (non-owned) of each tab. When switching from one tab to another, the OpenGL component is transparent (I can see whatever window is behind my window) for a fraction of a second, until the first call to render happens. See attached screenshot:

I assume this is caused by the fact that the change of tabs happens in the message thread (just as the call to repaint the window itself, the tabbed component, etc), while the render of the inner component happens in the OpenGL thread. For the duration in between those 2 actions in different threads, the inner component is transparent and the window behind it can be seen.

The question:
How can I avoid this issue, and have a plain white background instead, until the first call to render happens?

Additional information:
-In one of the tabs, the content of the tab is directly an OpenGLAppComponent. In this case, the whole inner part of the tab is transparent.
-In the other tab, there is a regular Component, that has a child OpenGLAppComponent. In this case, the parts that are drawn by the regular component are shown well (as seen in the screenshot), only the area that belongs to the OpenGLAppComponent is shown as transparent.
-This issue only happens when transitioning from a tab that has an OpenGLAppComponent to another: if I change the content of one tab to be a regular Component (no OpenGL involved), the issue does not happen at all.
-Every component involved in this window has the opaqueFlag set to true.

I would sincerely appreciate any additional insight in order to understand the problem better, and any solution or workaround you could think of.


#2

I’m afraid this may not be possible to avoid as the opengl area is a native window which, as you say, is drawn on another thread.

One way to workaround it though is to render all of your window with opengl. Also I would avoid using OpenGLAppComponent for such use-cases.

In summary:

  1. add an OpenGLContext context member variable to your top-level component
  2. In your constructor of your top-level component, call context.attachTo (*this); and in your destructor call context.detach(). Also call context.setRenderer (...) and set the renderer to whatever component will be doing the native opengl rendering (or set the renderer to be your top-level component and simply forward the rendering callbacks to whatever components in your app need to do some native GL drawing).
  3. As JUCE components are always drawn in front of the native GL drawing, you need to ensure that the component in the tab where you want to do native drawing is not opaque but 100% transparent. Also, any components behind that also need to be transparent.

Hope this helps!