Draw OpenGLComponent *over* non-OpenGL component

opengl

#1

I can’t seem to find a way to draw openGL components over a non-OpenGL component.
Like I have an OpenGL line renderer that I want to draw over a background image rendered in paint(Graphics& g).

The way I do it now is I render the total background image in a top level component’s OpenGL context then draw special child OpenGL objects using the same OpenGL context on top of that.
This seems a little messy but maybe it’s the right way for now?


#2

This is a limitation of JUCE currently.

That’s exactly the right way to do this. This is also the trick we use at ROLI in our NOISE app.


#3

Good to know thanks.


#4

Check this out,

Very helpful :grinning:


#5

I’m not sure how this solves the problem. I can’t render OpenGL (even opaquely) over the parent’s background (drawn with paint(Graphics& g)).

This looks like it renders an image of whatever’s behind the OpenGL component but still draws that image using OpenGL. Can copyTexture() draw over things drawn with paint(Graphics& g)?


#6

Maybe I’m misunderstanding the question here, but if what you’re trying to do is render some native GL over a background that’s drawn with paint() (and underneath other components also drawn normally), isn’t that exactly what our teapot demo is doing?


#7

The teapot is drawn over a black background. Say I want to draw over a red background which is not rendered in OpenGL. I can’t set the OpenGLRenderer’s paint to fillAll with red because that draws over the teapot. I also can’t do this in the MainWindow’s paint because everything under the OpenGLRenderer is covered.

After looking at this a bit more it seems what happens is an OpenGLRenderer always draws opaquely over its parents.
Then, paint() in the OpenGLRenderer and its children always paint over anything drawn with OpenGL.

So I misspoke before and it is possible to draw an OpenGLRenderer opaquely over things drawn with paint. What I really want to do is render that OpenGL transparently over a background like the teapot with a red background instead.


#8

Yes, it can do all of that very easily.

In OpenGLDemo.h demo (not OpenGLAppDemo.h), enable the “Draw 2D graphics in background” tick box to see an example.


#9

It looks like those 2D graphics are drawn using the same OpenGLContext in the OpenGLRenderer during the renderOpenGL pass. But if I were to draw those shapes in the MainWindow’s paint() function, we wouldn’t be able to see it. If we did that in the OpelGLDemo’s paint function, they would be on top of the teapot.

The only way I can get OpenGLRenderer components to intermingle with regular components rendered in paint is by having the regular “painting” components on top of things rendered in OpenGL. Like the code editor in OpenGLDemo.cpp.


#10

take a look at how the OpenGLContext “draws” into a graphics context in that 2D function.
In fact, just take a look at how when you switch to that OpenGL demo, the rendering engine changes and the whole application starts drawing into an OpenGL context.

Also, take a look at this:
https://docs.juce.com/develop/classOpenGLContext.html#aaa4cf6bbdb662b106cd44c203b8abb1a


#11

Yes the 2D stars are drawn from the renderOpenGL() function into a Graphics object which refers to the OpenGLContext. However, the problem is with how graphics drawn with paint() and graphics drawn with renderOpenGL() intermingle. I can layer things drawn with paint() over things drawn with renderOpenGL(), but not vice-versa.

This causes a problem when I want to have a top-level component with a background and render openGL components over it. The only solution I can come up with is a top-level OpenGLRenderer that draws the background from renderOpenGL() and then I’m able to render with either renderOpenGL() or paint() to layer over it. This works fine but I did wonder if it was the best solution.


#12

see line 260, line 323, and line 395.


#13

Read the code and I’m more convinced that caching the background myself with a top-level OpenGLRenderer and rendering it in renderOpenGL is the best (maybe only?) solution.

Though from your post I’m not sure if you’re agreeing with me or offering another solution.


#14

I was just just trying to point out how the OpenGLContext calls paintComponent() AFTER renderOpenGL(), which calls paint() on the component the context is attached to, as well as on all the children of that component. if you’re going to use OpenGLContext, you’ll need to abide by the rules it uses for rendering.


Requested improvements to OpenGL shader support in JUCE
#15

Which is kind of what @ttg suggested you do, reusing some code that does that nicely for you.


#16

Yeah I appreciated the code but it was the same solution I had when I posed the question. Good to know other people do it the same way though.