Integration into an External OpenGL Window

We’ve seen that a HOOPS Luminate window could be initialized using an existing OpenGL rendering context (Integrating a HOOPS Luminate Window into an Existing OpenGL Window). Now we need more details on the process that describe how we can render into this window, in addition to the existing applicaiton native OpenGL code.

Mixing HOOPS Luminate OpenGL Code with Application OpenGL Code

../../../../_images/window_external_opengl_context.png

Two mixed code rendering workflows

In the illustration above, we see two cases:

  1. The application renders before HOOPS Luminate,

  2. The application renders after HOOPS Luminate.

Using one or the other solution does not matter. Both are possible, and the application should choose which one fits best its needs. A few comments on how to proceed. Using OpenGL, the application has its own rendering context setup. HOOPS Luminate does the same and it has its own rendering context being setup internally during the draw.

In order to mix both OpenGL codes, the application needs to isolate itself or it needs to isolate HOOPS Luminate so that each can use OpenGL calls without affecting the context set by the other. This is the purpose of the RED::IWindow::RestoreREDState and RED::IWindow::RestoreHostState calls: a call to RED::IWindow::RestoreREDState will push all possible OpenGL attributes on the stack. Then HOOPS Luminate can render and it’ll modify attributes on the stack. On the other hand, a call to RED::IWindow::RestoreHostState will pop all possible OpenGL attributes from the stack, so that the application can retrieve all the settings it had left before using HOOPS Luminate. After the RED::IWindow::RestoreHostState, the application can draw safely.

All HOOPS Luminate methods must be encapsulated by a set of RestoreREDState / RestoreHostState methods to properly operate with external OpenGL contexts. All the restore RED or Host state calls should occur from the rendering thread. Note that restore operations apply for each external context used by HOOPS Luminate, so if several windows in the application are using external contexts, RestoreREDState / RestoreHostState should occur for each window in turn, at the time it needs to be rendered.

So, the application can draw first, or HOOPS Luminate can draw first. This don’t matter. However, it’s important to find out who is going to clear the rendering buffers and who is going to swap the rendering buffer! In the left schema pictured above, the application draws first. Therefore, it should clear the window. HOOPS Luminate draws last, so it can be set to do the buffer swapping job. In the right schema above, HOOPS Luminate draws first, so it should clear the window, and as the application renders last, it can do the buffer swapping operation. There are no constraints here.

Both the clearance and buffer swap operations are controlled from the HOOPS Luminate API:

  • See RED::IViewpointRenderList::SetMustClear to enable or disable VRL clear. The default VRL of the window is the one that can use an external OpenGL context. Auxiliary VRLs are just offscreen buffer, and invisible to the application.

  • See RED::WindowRenderInfo::SetBufferSwapping to enable or disable buffer swapping done by a HOOPS Luminate window.

HWND, HDC, HGLRC Access

HOOPS Luminate internally uses operating system specific objects to draw into a window or into an auxiliary buffer. The RED::IViewpointRenderList offers method to query the OpenGL parameters used by HOOPS Luminate to render, and also to modify them whenever needed:

  • On calling RED::IViewpointRenderList::GetOpenGLInfo, the device context, OpenGL context and Framebuffer object ID of the rendering buffer identified by the VRL are returned.

  • On calling RED::IViewpointRenderList::UpdateOpenGLInfo, these parameters can be modified. Note that you can access the set of parameters, modify just one and then update HOOPS Luminate with the change to consider. Please refer to the method documentation for details on releasing memory for these objects.