Custom Display Passes

Display passes are special callbacks that are responsible for rendering the scene in a viewport. Using the Graphic Sequencer, it is possible to create your own pass in order to have complete control over the look of the scene in an OpenGL viewport. If you already have a rendering engine, it is possible to convert it to a display pass--this is how the DirectX 9 realtime viewing mode in Softimage v4.0 was implemented (see Where to Find XGS Examples for more information).

| Display callback and display pass plug-ins share the OpenGL state machine with Softimage. If a plug-in needs to change the OpenGL state, the plug-in should restore the original state when it is finished.

Identifying the pass to Softimage’s Plug-in Registrar

Like display callabcks, custom display passes take advantage of Softimage’s self-installing plug-in manager, so the first thing to do is tell the plug-in registrar about what’s contained in the .dll or .so. This is done in the XSILoadPlugin function, as shown below.

    XSI::CStatus XSILoadPlugin( XSI::PluginRegistrar& in_reg )
    {
       in_reg.PutAuthor( L"My Very Awesome Company inc." );
       in_reg.PutName( L"Example Display Callbacks" );
       in_reg.PutVersion( 1, 0 );

       // Here we tell the Plugin Registrar that this DLL exports
       // a display callback Called MyClearScreenBuffer
       in_reg.RegisterDisplayCallback( L"MyClearScreenBuffer" );

       // Tell the Plugin Registrar to look for a custom Display pass
       // exported by this DLL

       in_reg.RegisterDisplayPass( L"MyCustomPass" );

       …
    }

Initializing the Pass and Connecting to the Graphic Sequencer

After specifying the callback’s name, the plug-in manager will then look for five exported functions in.dll or .so.

    void MyCustomPass_Execute ( XSI::CRef, LPVOID * );
    void MyCustomPass_Init ( XSI::CRef, LPVOID * );
    void MyCustomPass_Term ( XSI::CRef, LPVOID * );
    void MyCustomPass_InitInstance ( XSI::CRef, LPVOID * );
    void MyCustomPass_TermInstance ( XSI::CRef, LPVOID * );

The _Init function registers the pass with Softimage, as shown below:

    void MyCustomPass_Init ( XSI::CRef in_pSequencerContext, LPVOID *in_pUserData )
    {

       // Softimage's plugin registrar calls this to initialize the display pass.
       // Now, we must register the display pass with the Graphic Sequencer

       XSI::GraphicSequencerContext l_vGraphicSequencerContext = in_pSequencerContext;

       // get the sequencer from the context object
       XSI::CGraphicSequencer in_pSequencer = l_vGraphicSequencerContext.GetGraphicSequencer ();

       in_pSequencer.RegisterDisplayCallback ( L"MyCustomPass", 0, XSI::siPass, XSI::siCustom, L"MyCustomPass" );

    }

In the example below, the _Execute function gets the selection list using the C++ API, renders the scene in HiddenLineRemoval, then render the selection using whatever material is connected to the RealtimePort (making a hybrid display mode).

    void MyCustomPass_Execute ( XSI::CRef in_pSequencerContext, LPVOID *in_pUserData )
    {
       XSI::GraphicSequencerContext l_vGraphicSequencerContext = in_pSequencerContext;
       assert ( l_vGraphicSequencerContext.IsValid() );
       XSI::CGraphicSequencer in_pSequencer = l_vGraphicSequencerContext.GetGraphicSequencer ();

       //
       // Grab the current selection list
       //

       using namespace XSI;
       Application app;
       Selection sel = app.GetSelection();
       CRefArray array(sel.GetArray());

       // Render the scene in hidden line
       in_pSequencer.RenderSceneUsingMode ( siHiddenLineRemoval, siRenderDefault );

       // Now render over the selection list using the material attached to the realtime port
       in_pSequencer.RenderListUsingMode ( array, siRealtimePortMaterial );

       return;
    }

Note that for the sake of simplicity, we are rendering the object using built-in passes (HiddenLine and RealtimePort). But you have much more flexibility when using RenderSceneUsingMaterial and provide your own shader:

    in_pSequencer->RenderSceneUsingMaterial ( L"MySuperShader", siRenderDefault );

Using custom display passes become very interesting when they are used in conjuncture with pixel buffers (accelerated offscreen OpenGL buffers). You can create your p-buffer, make it the current rendering context and use the Sequencer to render the scene. Then, you can composite this p-buffer with other buffers, use multipass, blur them. etc. Using this technique, you can do interesting things like realtime shadows, reflections or other scene-wide effects.

Autodesk Softimage v7.5