Step 7: Running the Rendering Loop

After initializing the application, the WinMain function in D3dmain.cpp sets up the message loop. The code monitors the message queue until there are no pressing messages and then calls the RenderLoop function. RenderLoop is defined in D3dmain.cpp. WinMain maintains a count of the number of times RenderLoop can fail; if it fails more than three times, the application quits.

The RenderLoop function renders the next frame in the scene and updates the window.

The first task in the RenderLoop function is to restore any lost DirectDraw surfaces, if possible. It calls the IDirectDrawSurface::IsLost method to identify lost surfaces and IDirectDrawSurface::Restore to restore them. Then RenderLoop clears the back buffer and, if enabled, the z-buffer, by calling the IDirect3DRMViewport::Clear method.

Now RenderLoop calls the RenderScene function implemented by the sample application calling D3dmain.cpp. A sample's RenderScene function can take into account a complex series of special cases, or it can be as simple as the implementation in Oct1.c. Then, the RenderScene function executes the execute buffer by calling IDirect3DDevice::BeginScene, IDirect3DDevice::Execute, and IDirect3DDevice::EndScene, retrieves any new execute data by calling IDirect3DExecuteBuffer::GetExecuteData, updates the screen extents, and then calls a local TickScene function that changes the viewing position by calling the IDirect3DDevice::SetMatrix method.

Finally, the RenderLoop function calls the D3DAppRenderExtents helper function to keep track of the changed sections of the front and back buffers and blits or flips the back buffer to the front buffer.