Flipping the Surfaces

[Previous] [Next]

Page flipping is an important capability that enhances the look of graphics applications. The hidden surface on which writing occurs is known as the back buffer. The process of switching the view from the currently displayed buffer (what shows on the screen) to the view rendered (drawn) to the back buffer is known as page flipping. Page flipping uses multiple surfaces to render on one surface while displaying another. By using multiple buffers in this way, you'll ensure that the transitions between frames are smooth, with no tearing. Tearing occurs when an animated image is being changed as it's drawn.

Figure 3-2 shows what happens visually in tearing. To the eye, it looks as if the top part of the square was rendered and then the lower part was rendered offset to the right. However, the programmer was attempting to render three complete images of the square to make it appear to move across the screen.

click to view at full size.

Figure 3-2 Tearing (frames 1_3)

Although no simple scene like this would be a problem with today's display hardware, if you want to render complex 3D scenes this effect can definitely be visually disconcerting. To prevent tearing, all you need to do is not update the display buffer while the image is being drawn to the display. By making your changes during the display's vertical blanking interval (the time it takes the beam to move from the bottom to the top of the display after drawing a frame), you can guarantee that a complete frame has been drawn. During this short interval, you can change the complete memory without worrying about tearing since the electron guns in the display are turned off and being repositioned to the top for the next frame.

The vertical blanking interval lasts only a few milliseconds, but by using the double buffering mode, you can copy the entire back buffer to the front buffer (the display the user sees) so that it can be scanned. This process requires changing only a few registers on the display card, so it can be performed during the vertical blanking interval. Again, no tearing will occur if you use this technique.

DirectDraw Complex Surfaces and Flipping Chains

DirectDraw flipping surfaces are called complex surfaces. A complex surface is a set of surfaces that can be created with a single call to the IDirectDraw7::CreateSurface method.

You can call IDirectDraw7::CreateSurface to create front and back buffers, which are the minimum flipping structures needed to flip pages. Using the IDirectDraw7::Flip method of the front buffer surface rotates the memory of all the surfaces. This rotation ensures that the memory used for the back buffer is associated with the front buffer and the memory associated with the front buffer is moved to the back buffer. Rather than rely on just a front buffer and a back buffer, you can create other intermediate buffers and use them to create a "ring," or a set of multiple buffers to be cycled through.

The DDSCAPS_FLIP flag indicates that a surface is part of a flipping chain. Using the DDSCAPS_FLIP flag requires that you also include the DDSCAPS_COMPLEX flag.

If you specify 2 for the value of the dwBackBufferCount member of the DDSURFACEDESC2 structure, two back buffers are created, and each call to the IDirectDraw7::Flip method rotates the surfaces in a circular pattern, providing a triple-buffered flipping environment. This rotation requires more memory but avoids the situation that double-buffered programs can encounter, in which the program is briefly stalled because both buffers are busy.

The code used to flip from the front to the back buffer is illustrated in the CD3DFramework7::ShowFrame function below. This routine handles flipping for a full-screen mono mode, a full-screen stereo mode (for 3D head-mounted displays or 3D-capable monitor presentations), and a windowed mode. For either full-screen mono or stereo mode, we use the IDirectDrawSurface7::Flip method to switch between surfaces. For rendering to a window, we use the IDirectDrawSurface7::Blt method and pass the variable m_rcScreenRect defining the rectangular screen area (the window's interior) we'll be blitting to and the variable m_pddsBackBuffer to define the back buffer we rendered to and want to flip to the front for viewing.

 //------------------------------------------------------------------- // Name: ShowFrame // Desc: Shows the frame on the primary surface, via a blit or a flip //------------------------------------------------------------------- HRESULT CD3DFramework7::ShowFrame() {     if( NULL == m_pddsFrontBuffer )         return D3DFWERR_NOTINITIALIZED;     if( m_bIsFullscreen )     {         // We're in full-screen mode, so perform a flip.         if (m_bIsStereo)         {             return m_pddsFrontBuffer->Flip( NULL,                                              DDFLIP_WAIT |                                              DDFLIP_STEREO);         }         else         {             return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT );         }     }     else     {         // We're in windowed mode, so perform a blit.         return m_pddsFrontBuffer->Blt( &m_rcScreenRect,                                         m_pddsBackBuffer,                                        NULL, DDBLT_WAIT, NULL );     } } 



Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net