Managing Multiple Windows and External OpenGL Contexts

OpenGL in a Standalone Application

This paragraph details the relationship between HOOPS Luminate and OpenGL, and the way OpenGL contexts are managed by HOOPS Luminate when it operates alone in an application. The picture below illustrates the way contexts are created and managed by HOOPS Luminate:

../../../../_images/opengl_context_standalone.png

OpenGL context management in a standalone HOOPS Luminate application

First, HOOPS Luminate is a multiple OpenGL contexts application. It uses one separate OpenGL context for each rendering buffer it needs to work with (on-screen windows and off-screen buffers). As you can see in the schema above, there’s a default HOOPS Luminate OpenGL context. This context is a ‘pivot’ context that is created during the initialization of the first HOOPS Luminate window. All other contexts will share their resources with it on creation, so that we can ensure that HOOPS Luminate manages only one pool of shared data for the application.

All RED::IViewpointRenderList objects have their own OpenGL contexts. These contexts can be accessed through RED::IViewpointRenderList::GetOpenGLInfo. Returned values types depend of course on the operating system in use for the application.

Using External OpenGL Contexts in an Application

As we have seen, a HOOPS Luminate window can be initialized so that it uses the OpenGL context of an existing 3rd party application to draw in the context that does not belong to it. This can be achieved by using the RED::WindowRenderInfo class that lets the caller specify the ‘hosting’ context of a window thanks to: RED::WindowRenderInfo::SetHostingContext. A practical example can be found here: Integration into an Existing OpenGL Application.

There’s no more to say if one window only is used in the application, but in the case of multiple windows, we must be sure that all the contexts in use (by both the hosting application and by HOOPS Luminate) are shared. On Windows this is usually not a problem as HOOPS Luminate will share all supplied hosting contexts with its default internal OpenGL context. On Linux and MacOS, the problem is a bit different as the sharing context is specified at the context construction time.

On Windows, the context sharing can occur after the context has been created. the wglShareLists call can be used to make sure that all contexts can be shared, if some basic rules are enforced:

// Given 4 contexts A, B, C, D:
wglSharelists( A, B );    // OK
wglShareLists( A, C );    // OK
wglShareLists( C, D );    // OK

// Given 4 contexts A, B, C, D:
wglShareLists( A, B );    // OK
wglShareLists( C, A );    // KO ( A and B are shared, so they can be used only as first argument of wglShareLists ).
wglShareLists( C, B );    // KO

The only tricky part here is to ensure that if a context is already shared with another one it can be only used as the first parameter of wglShareLists. If a call fails, then the opposite call will work unless both parameters are already shared themselves.

On Linux and MacOS, the sharing context is specified at the context construction time. Therefore, the application must ensure that all the contexts it supplies to HOOPS Luminate are shared before it sends them to HOOPS Luminate. This leads to a different context organization:

../../../../_images/opengl_context_shared.png

Context sharing with application owned contexts, on Linux and MacOS

The first window hosting context supplied to HOOPS Luminate will act as the ‘pivot’ context. All other windows of the application should have their context shared with this one. HOOPS Luminate’s default context will be initialized by sharing with the first supplied window hosting context. Internal HOOPS Luminate VRLs will either use their own proprietary contexts created and shared with the HOOPS Luminate default context (the sharing constraints described above don’t apply on Linux and MacOS) or will use OpenGL FramebufferObjects (FBOs for short) that rely only on the default HOOPS Luminate OpenGL context.