Rendering to an offscreen buffer

Offscreen rendering is a key feature in REDsdk. It's achieved by using auxiliary "viewpoint render lists". These objects are created directly from the RED::IWindow, using RED::IWindow::CreateVRL. A VRL is an offscreen buffer, as detailed here: Viewpoint render lists. The default VRL of a window renders onscreen while all auxiliary VRLs render offscreen.

In this example, we'll define a simple rendering pipeline with one auxiliary VRL. This VRL owns a scene graph that is rendered to a texture. This texture is then used as a source image in a shader applied to a geometry in the main scene of the main camera:

The second tutorial step with a moving cube rendered offscreen

Setup the auxiliary rendering pipeline

RED::Object* auxvrl;
RC_TEST( iwindow->CreateVRL( auxvrl, 1024, 1024, RED::FMT_RGBA, iresmgr->GetState() ) );
RED::IViewpointRenderList* iauxvrl = auxvrl->As< RED::IViewpointRenderList >();
RC_TEST( iauxvrl->InsertViewpoint( auxcamera, iresmgr->GetState() ) );

The creation of the VRL is quite easy as illustrated by the code above. Here, as we intend to generate a 2D texture out of it - that'll use the RED::TGT_TEX_2D rendering target - we pay attention to setting up Power-Of-Two-Dimensions for the VRL.

Then, the link between this VRL and the main scene is 2 steps:

1: Setup a render image on that VRL:

RED::Object* auximage;
RC_TEST( iresmgr->CreateImage2D( auximage, iresmgr->GetState() ) );
RED::IImage2D* iauximage2D = auximage->As< RED::IImage2D >();
RC_TEST( iauximage2D->SetRenderImage( auxvrl, 1024, 1024, 0, 0, RED::TGT_TEX_2D, iresmgr->GetState() ) );

2: Use that image somewhere in the rendering. Here, we use it directly as the diffuse texture source for the rendering of our cube in the main scene:

RC_TEST( iresmgr->CreateMaterial( matr, iresmgr->GetState() ) );
imatr = matr->As< RED::IMaterial >();
RC_TEST( imatr->SetupGenericDiffuseMaterial( false, RED::Color::WHITE, auximage, RED::Matrix::IDENTITY, RED::MCL_TEX0,
                                             &RED::LayerSet::ALL_LAYERS, NULL, resmgr, iresmgr->GetState() ) );
RED::Object* root, *cube;
RC_TEST( icamera->GetRootShape( root ) );
RED::IShape* iroot = root->As< RED::IShape >();
RC_TEST( iroot->GetChildByID( cube, RED::Object::GetIDFromString( "cube" ) ) );
RED::IShape* icube = cube->As< RED::IShape >();
RC_TEST( icube->SetMaterial( matr, iresmgr->GetState() ) );

Then, the contents of that auxiliary VRL can be defined normally, as for any other camera which is set into a VRL for the rendering. In this specific example, we setup a red animated cube to be rendered.