Calling the paint() function BEFORE openGL render in a component?

So I have a project where the OpenGL is working great and I have separate painting instructions in the paint function (using the setComponentPaintingEnabled(true) function). The issue is that it seems as though OpenGL renders the shaders and stuff inside renderOpenGL() and then goes on to doing the paint method. Is there any way to reverse this or re-engineer this?

Thanks!

You’d have to modify JUCE itself, as it’s currently hard-coded to put the OpenGLRenderer callbacks before the component painting.

The only other option would be disabling component painting and just creating a texture yourself of the component graphics. Then you could draw that texture first thing in your OpenGLRenderer rendering callback…

Gotcha. I also see that there’s a createOpenGLGraphicsContext() but the LowLevelGraphicsContext* functionality (that it returns) is limited. Is there a way to act on the graphics inside the renderer like in paint without creating a texture?

It seems like it could work, haven’t tried it myself though…

It would probably be something like:

void myOpenGLRenderer::renderOpenGL() 
{
    {
        std::unique_ptr<LowLevelGraphicsContext> lowLevelContext(
            createOpenGLGraphicsContext(
                *OpenGLContext::getCurrentContext(),
                someTopLevelComponent.getWidth(),
                someTopLevelComponent.getHeight() /** The width and height may need scaling based on 
                                                      OpenGLContext::getRenderingScale() **/
            )
        );

        Graphics g(*lowLevelContext);
        someTopLevelComponent.paintEntireComponent(g, false);
    }

    /** Continue with OpenGL rendering methods **/
}
2 Likes

Whoa cool! Thanks!!

Yeah I needed to scale it. I’m still playing around with it but it insists on being on top and covering up all the shader stuff even though I have this code at the beginning. Very interesting.

Are you able to see any of the shader stuff at all if you remove some components or “leave holes” in them?

When I say “leave holes”: if you mark an OpenGLContext attached component as opaque but don’t draw into it fully, you will see the contents of the OpenGLRenderer in the “holes”. We use this in our plugins to create multiple “render views”, but it may be useful for debugging your app.

If it’s not even shown through those then something else may be wrong. If it is shown underneath components though… I’m not exactly sure where the problem lies then :slight_smile: I know JUCE will disable depth testing when using the OpenGL-ified LowLevelGraphicsContext, but that shouldn’t be causing you issues AFAIK. They fiddle with the blending mode state as well in certain places…

What kind of graphics are you drawing over the component painting?

2 Likes

Yeah if I don’t draw anything into the new “g” graphics context, my other stuff still draws. But if I do g.fillAll() with a colour it covers everything up.

Sure! maybe it would be helpful to explain. Basically I’m drawing real-time 2D phase correlation squiggels with shaders. That all works fine but what I’m trying to do is “fill-all” a semi-transparent overlay on top every frame so as it draws, it slowly fades out. Similar to analog instruments. Now I have that working already using the paint() function where it fills all with the semi-transparent overlay but because it happens last in the pipeline, the initial drawing never shows in it’s real colour, it starts already slightly greyed out on every frame. That’s why I’m trying to figure out a way to fillAll earlier. Does that make sense?

The OpenGLHelpers::clear doesn’t work in this instance because it clears everything immediately.

Ah, gotcha! It sounds like it could perhaps be a blending issue…

JUCE will glDisable(GL_BLEND) in several places, you could try enabling it and setting the blend function/equation before you draw. I know we had to do that for our multi-render-view setup I had mentioned before, since our renderer programs need transparency to overlay multi-channel spectrum displays and such