Integration into an Existing OpenGL Application

Introduction

This tutorial creates a standalone window, using the basic operating system features: A Win 32 window on Windows, a X11 window on Linux and a Cocoa view on OSX. Then, we create a simple OpenGL rendering context and draw a rotating cube into that window. The standalone window renders like that:

../../../_images/wf_integration_into_an_existing_opengl_application_base_cube.png

The basic OpenGL application built by the tutorial.

Then, we create and setup a HOOPS Luminate window so that it can co-exist and render into the same window as our application, using the existing window application context. This illustrates how HOOPS Luminate can be used to enrich an existing application graphics or how it can be used to replace parts of a graphic pipeline.

This capability is very important as it allows a smooth integration of HOOPS Luminate into an existing OpenGL application, without breaking any legacy graphics layer, that could be difficult to rewrite from scratch otherwise.

Adding the HOOPS Luminate Window

The tutorial is divided into 4 steps:

  1. Creation of the window for the considered OS.

  2. Creation of the OpenGL context.

  3. Creation of the HOOPS Luminate window to work in this environment (with a simple scene setup).

  4. Rendering of both the original OpenGL code AND HOOPS Luminate for the same frame.

The HOOPS Luminate window uses an auxiliary RED::WindowRenderInfo to source the application OpenGL parameters:

RED_RC rc;
RED::Object* window;

RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
if( !resmgr )
    RC_TEST( RED_FAIL );

RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();

RED::WindowRenderInfo winfo;
winfo.SetBufferSwapping( false );

#if defined( _WIN32 )

winfo.SetHostingContext( hdc, hrc );
window = RED::Factory::CreateREDWindow( *resmgr, hwnd, width, height, &winfo, rc );

#elif defined( _LIN32 )

winfo.SetHostingContext( xwin, glxctx );
window = RED::Factory::CreateREDWindow( *resmgr, (void*)xwin, display, screen, visual, width, height, &winfo, rc );

#elif defined( _MAC32 )

winfo.SetHostingContext( ctx );
window = RED::Factory::CreateREDWindow( *resmgr, (void*)OSXGetWindowView( ns_window ), width, height, &winfo, rc );

#endif

if( !window )
    RC_TEST( RED_FAIL );

RC_TEST( rc );

Note

We have chosen to disable the window buffer swapping so that this is the source application that’ll control the window buffer swapping. We also disable any buffer clear from the HOOPS Luminate window’s default VRL, so that we can draw the HOOPS Luminate OpenGL after the application’s own OpenGL.

Then, we setup a default scene and here goes the rendering code:

RC_TEST( iwindow->RestoreHostState( hdc, hrc ) );

if( wglMakeCurrent( hdc, hrc ) == false )
    RC_TEST( RED_DRV_FAIL );

if( MyBeautifulCube() != 0 )
    RC_TEST( RED_FAIL );

RC_TEST( iwindow->RestoreREDState( hdc, hrc ) );

RC_TEST( iresmgr->EndState() );
RC_TEST( iwindow->FrameDrawing() );
iresmgr->BeginState();

::SwapBuffers( hdc );

We only quote the Windows OS source code version. Please refer to the source code directly for the Linux and MacOS versions. As detailed in the Integration into an External OpenGL Window chapter of the documentation, we need to isolate the application OpenGL code from the HOOPS Luminate OpenGL code. This is performed by the RED::IWindow::RestoreREDState and RED::IWindow::RestoreHostState calls.

As a result, we have the mix of the application OpenGL code and HOOPS Luminate scene rendered both in the same color and depth buffers, as illustrated below:

../../../_images/wf_integration_into_an_existing_opengl_application_final.png

The final view with the mix of HOOPS Luminate scene with the application OpenGL scene.