How to properly overlay two opengl contexts with transparency?

I’ve got a spectrum analyzer component and a response curve component that I want to overlay with the response curves/eq handles being on top.

I’ve created opengl contexts in each of the components but it appears that they are fighting each other and the strange thing is it’s tied to the mouse moving within the window… and when the knobsare adjusted so I suppose it’s the parameters, not the mouse.

The other issue I’m having is not being able to clear the frame buffer to transparent at the outset so only my curves will be layers on top.

I’ve searched here but didn’t find much so I thought I’d ask.

Thanks.

edit: I should also mention that Ive tried just using one context to render the two components beneath it but the performance was bad. The only way I could get it running smoothly was with two separate contexts, not sure if that’s normal.

ScreenRecorderProject88

I’ve managed to get rid of the flickering so if I can just figure out how to get transparency working with the spectrum analyzer opengl context I’ll be good to go… I really hope that’s possible.

I’ve made the analyzer window small to make sure both were rendering.

ScreenRecorderProject90

I’ve created opengl contexts in each of the components but it appears that they are fighting each other and the strange thing is it’s tied to the mouse moving within the window

Is it possible (for you) to use one openglContext instead of multiple contexts?

I believe this will only work using a single OpenGL context.

If both of the components (the spectrum and the response curve) are created using OpenGL rendering, you can blend them with:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  

And you will also need to specify color alpha to be transparent for some pixels in the fragment shader.

See this tutorial:

If you want to know how to render multiple OpenGL components using a single OpenGL Context, x-io Technologies’ x-IMU3 GUI is a great open-source example:

Yeah that’s the thing, they were both made with juce paths and fills. After working with it a bit longer I’m starting to realize this isn’t as simple as just adding my components to the parent PluginEditor and attaching a single opengl component to the parent. When I do that, it practically freezes the daw.

On their own, when I add a separate context to each component and add them to the parent, they render very quickly but there is the transparency issue.

I’m taking a look at that x-IMU3 example… not sure how to build it because I don’t see a solution or jucer file but looking at the code I can get a few ideas but I still need time to wrap my head around it.

I tried rendering each context offscreen and then compositing them afterwards but I couldn’t get it to work and it also sounds like it might be a lot of extra overhead anyways but I could be wrong.

I suppose I could rework the entire project and try to draw things with opengl all in one paint section of the parent component but that’s going to be a major undertaking for my experience level with this stuff but if I have to go down that path then so be it.

1 Like

I have heard it said somewhere on the forum that you actually do not want to attach the OpenGLContext to the PluginEditor. Instead, make a child component, MainComponent, and make this be the ONLY child of the PluginEditor. Then you can add all your other components to this MainComponent instead. Then only attach the OpenGLContext to the MainComponent instead of the PluginEditor.

Try that and see if that fixes your issue.

Also make sure:

  • Both of your components do NOT set setOpaque(true).
  • Your response curve component actually has a transparent background using something like g.setColour(juce::Colours::transparentBlack).

You should be able to accomplish what you want without a major rework. I now understand you are saying both of your Components are just regular JUCE Components and you just want them to be drawn using JUCE’s OpenGL renderer. This is defintiely possible.

I spent the morning trying this out with the MainComponent and it’s the same result as using one context in the plugineditor… the transparency between the components works because it’s all in one context but it chokes up my machine and the daw become unresponsive.

I’m looking around to see if I can find any examples online that pull off something similar but so far the only analyzer/response curve exampes I’ve found seem to either just use juce graphics or opengl written from the ground up.

I spoke too soon… it seems to work now but it takes a few seconds to load and then when it does, the image knobs are hidden and the fallback juce rotary sliders appear. If I close the window and reopen it, my image sliders return and the gui is more responsive for some reason so I guess I have some startup issues.

I’m going to profile to see if anything jumps out… but I’m happy this is heading in the right direction again. I am measuring fps and I’m getting about 20 but it feels like it might be more than that so maybe my fps calculation is off but it’s definitely usable.

I wonder how much room there is for multithreading in something like this because I know a lot of the tasks seem to share resources and I don’t understand much about thread safety.

ScreenRecorderProject92

1 Like

You may also see significant improvement when building in release mode instead of debug mode.

I doubt you will need/want to add more threads. If you’re using OpenGL, it already runs a dedicated thread for OpenGL rendering.

Hi there! Keep in mind that actually using OpenGL (that is, using low-level OpenGL instructions, drawing inside the renderOpenGL() callback, etc.), and merely attaching an OpenGLContext are not the same.

The latter lets you use the JUCE graphics classes (Path, etc.) but might not necessarily improve performance. For example, I have found that on Android it certainly helps but on MacOS it usually makes things worse. On Windows, it seems that Direct2D is what currently provides the greatest performance boost: https://forum.juce.com/t/direct2d-part-3/57410

3 Likes

Cool stuff, thanks guys… @aamf, that thread is interesting!

I was able to get my framerate up in the high 40’s by resampling/downsampling my curves, I can probably decimate even more without seeing any detrimental effects.

Here’s how I’m setting it up.

2 Likes