Rendering the Scene

The RenderScene function renders the 3-D scene, just as you might suspect. The fundamental task performed by this function is submitting the single execute buffer used by this sample. However, the function also clears the back and z-buffers and demarcates the start and end of the scene (which in this case is a single execute).

When you clear the back and z-buffers, it's safe to specify the z-buffer clear flag even if we don't have an attached z-buffer. Direct3D will simply discard the flag if no z-buffer is being used.

For maximum efficiency we only want to clear those regions of the device surface and z-buffer which we actually rendered to in the last frame. This is the purpose of the array of rectangles and count passed to this function. It is possible to query Direct3D for the regions of the device surface that were rendered to by that execute. The application can then accumulate those rectangles and clear only those regions. However this is a very simple sample and so, for simplicity, we will just clear the entire device surface and z-buffer. You should probably implement a more efficient clearing mechanism in your application.

The RenderScene function must be called once and once only for every frame of animation. If you have multiple execute buffers comprising a single frame you must have one call to the IDirect3DDevice::BeginScene method before submitting those execute buffers. If you have more than one device being rendered in a single frame, (for example, a rear-view mirror in a racing game), call the IDirect3DDevice::BeginScene and IDirect3DDevice::EndScene methods once for each device.

When the RenderScene function returns DD_OK, the scene will have been rendered and the device surface will hold the contents of the rendering.

static HRESULT 
RenderScene(void) 
{ 
    HRESULT hRes; 
    D3DRECT d3dRect; 
 
    ASSERT(NULL != lpd3dViewport); 
    ASSERT(NULL != lpd3dDevice); 
    ASSERT(NULL != lpd3dExecuteBuffer); 
 
    // Clear both back and z-buffer. 
 
    d3dRect.lX1 = rSrcRect.left; 
    d3dRect.lX2 = rSrcRect.right; 
    d3dRect.lY1 = rSrcRect.top; 
    d3dRect.lY2 = rSrcRect.bottom; 
    hRes = lpd3dViewport->lpVtbl->Clear(lpd3dViewport, 1, &d3dRect, 
        D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER); 
    if (FAILED(hRes)) 
        return hRes; 
 
    // Start the scene. 
 
    hRes = lpd3dDevice->lpVtbl->BeginScene(lpd3dDevice); 
    if (FAILED(hRes)) 
        return hRes; 
 
    // Submit the execute buffer. 
 
    // We want Direct3D to clip the data on our behalf so we specify 
    // D3DEXECUTE_CLIPPED. 
 
    hRes = lpd3dDevice->lpVtbl->Execute(lpd3dDevice, lpd3dExecuteBuffer, 
        lpd3dViewport, D3DEXECUTE_CLIPPED); 
    if (FAILED(hRes)) 
    { 
        lpd3dDevice->lpVtbl->EndScene(lpd3dDevice); 
        return hRes; 
    } 
 
        // End the scene. 
 
    hRes = lpd3dDevice->lpVtbl->EndScene(lpd3dDevice); 
    if (FAILED(hRes)) 
        return hRes; 
 
    return DD_OK; 
}