FR: Allow users to draw OpenGL directly to the window handle

As a JUCE user, I really want to take advantage of native OpenGL and its performance.
To do that, I need the flexibility to create a custom rendering workflow for my needs. (eg: Complete control over what/how/when things happen).

JUCE’s frame rendering mechanisms aren’t helping me do strict OpenGL rendering - OpenGL is difficult enough as it is. The present implementation in JUCE has 3 disadvantages:

  1. It forces me to cooperate with the JUCE Component painting logic, even when I don’t need it.
  2. Continuous repainting takes a long time (eg: dealing with thread jobs, image caching)
  3. The present implementation takes up a lot more memory. (Forced to allocate a variety of things for Component painting logic, and image caching)

I really would prefer a custom method that allows me to directly render to the window/surface on the main thread.

The framework provides many classes and mechanisms that can almost get me there… lots of hacking required to get it sorted out as something separate from the current implementation.

It’s very frustrating that using OpenGL in JUCE implicitly requires threading and all this extra context management, especially because it can’t be reliably used in plugins for that very reason

Under the hood the OpenGLContext seems to make use of a lot of the mechanisms already there, like CachedComponentImage, LowLevelGraphicsContext, threads, etc… but it handles it in such a way that all you can really do on the user side is create an OpenGLContext and the whole thing is abstracted away from you from then on.

With all the talk of Vulkan/Metal (and the lack of changes to JUCE’s OpenGL module lately) I wonder if any changes like these will really make it into the OpenGL module, or if only future rendering engines will provide the needed flexibility…

I agree. The interoperability between JUCE’s OpenGL rendering wrapping is great on the assumption that you’re playing with Components. Otherwise, you’re basically chopped liver.

BGFX looks like a proper alternative if there’s little to no movement on opening up the JUCE GL wrapping and Vulkan wrapping: https://github.com/bkaradzic/bgfx

There still remain large(ish) downsides to using a custom renderer though, stuff that JUCE could be doing to render things more cleanly as a whole (eg: rendering glyphs into a GL texture acting as a font table, instead of an edge table).

In my applications for embedded platforms based on imx6 I had to use OpenGL outside of JUCE for similar reasons (like synchronization of repainting with video camera streaming, messages from FPGAs etc.) and also because on Linux JUCE support for OpenGLES is not present.
I just use getWindowHandle() and paint via OpenGLES everything what I need just directly. Maybe not elegant but not involving an additional abstract layer (of course there were many other issues which had to be solved).

On the other hand I really do not know how the current OpenGL support in JUCE could be improved taking into account that OpenGL itself is a messy thing, at least for me.

2 Likes

Could you just use an NSViewComponent with an NSOpenGLView? Not sure if there is a windows equivalent

I’m not versed in the macOS side of things to be able to say…

I know that on Windows you attach to the HWND (which is owned by the ComponentPeer in JUCE), create an HDC, and configure everything GL from there (like selecting the pixel format and buffers).

JUCE does that entire initialisation stage rather well.