OpenGL Context Issues

opengl

#1

Hello All,

Seeking some advice on how best to render multiple windows using JUCE and OpenGL please.

I’m trying to render a single 3D scene from multiple viewpoints, where each rendered view occupies a separate window (so that the user can easily re-arrange them). So I can’t just divide up the viewport of a single GL surface.

The first problem I’ve run into, is that the JUCE OpenGLContext appears to be permanently bound to a particular component. It seems that, if I want to have multiple OpenGL windows, I need to have an OpenGLContext for each. But this has some issues:

  • The 3D scene is potentially complex, so I don’t want to have to duplicate GPU resources (eg: vertex buffers) between the different contexts. I know that JUCE exposes the ability to share resources between contexts, but this isn’t ideal, as I believe this doesn’t allow the ability to share containers (such as FBOs), either when implemented with the call to wglShareLists for Windows, or as a parameter to glXCreateContext on Linux.

  • The JUCE OpenGLContext doesn’t seem to allow you to request a core/debug profile context on Windows/Linux (for Windows, the context setup code uses wglChoosePixelFormatARB, but not wglCreateContextAttribsARB).

  • Each instance of OpenGLContext creates its own render thread, which I don’t need or want, and seemingly, a bunch of other stuff too (the memory cost of each instance is quite steep). Even without the overhead of OpenGLContext, simply switching between OpenGL contexts is an overhead that I’d prefer to avoid. I really don’t want to have the GPU juggling multiple sets of GL state, since all my views have essentially the same GL state.

What I really want to do, is have a single GL context, that I switch between view windows, rendering each one in full, before moving onto the next window:

wglMakeCurrent(DeviceContextWindow1, OpenGLRenderContext);
Set MVP matrix for viewpoint 1.
RenderScene
wglMakeCurrent(DeviceContextWindow2, OpenGLRenderContext);
Set MVP matrix for viewpoint 2.
RenderScene
etc

Since I can’t seem to use juce::OpenGL context to achieve this, I looked into creating my own native GL context, and having that render directly into a JUCE window. I managed to get some way towards this by calling getPeer() on a JUCE component, then getNativeHandle() on that, and then setting up my own OpenGL context (with Windows native calls ChoosePixelFormat, SetPixelFormat, wglCreateContext, wglMakeCurrent).

Then, in my component’s paint() function, I’m able to directly call OpenGL functions to render an image. Unfortunately however, while this image is generated OK, it immediately gets overwritten with the component’s background colour by the blitToWindow() call in HWNDComponentPeer::performPaint().

Is there an easy way to suppress that final blit? Some kind of mask function?

Or should I be looking at something more like an OpenGL equivalent to Direct2DLowLevelGraphicsContext? That class seems to be undocumented (as is its base class: LowLevelGraphicsContext).

Thanks

Alex


#2

Hi Alex,

I unfortunately can’t answer your question but we have been running into a similar issue and I was wondering if you found a solution in the meantime?

Thanks!


#3

You could use a single OpenGL context attached to the toplevel component as adviced by Fabian in this thread: OpenGL interface renderer with OpenGLRenderer component broken - OpenGL Demo misleading
This means that the whole interface is rendered with OpenGL and you can do your own stuff in multiple sub components. This works pretty well for me.

Regards,

Jan