After you've created the application window, created the DirectX objects, then initialized the scene, you're ready to render the scene. In most cases Windows applications monitor system messages in their message loop, and render frames whenever no messages are in queue. The Triangle sample is no different; it uses the following code for its message loop:
BOOL bGotMsg;
MSG msg;
PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
g_bReady = TRUE;
while( WM_QUIT != msg.message )
{
// Use PeekMessage() if the app is active, so we can use idle time to
// render the scene. Else, use GetMessage() to avoid eating CPU time.
if( g_bActive )
bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );
else
bGotMsg = GetMessage( &msg, NULL, 0U, 0U );
if( bGotMsg )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
// Render a frame during idle time (no messages are waiting)
if( g_bActive && g_bReady )
Render3DEnvironment();
}
}
This code uses a global flag variable, g_bActive, to keep track of when it's active, and another variable, g_bReady, to indicate that all system objects are ready to render a scene. The application sets g_bActive to FALSE whenever the window isn't visible, and it sets the g_bReady variable to FALSE whenever it needs to recreate the objects used to render the scene. (The latter situation is covered in Handle Window Resizing.)
If the application is active, it checks the message queue to see if there are any pending messages. If there are messages in queue, the code dispatches them like any other Windows application. Otherwise, it calls the Render3DEnvironment application-defined function to render a frame of the scene, which is the topic of Step 5: Render and Display the Scene.