summaryrefslogtreecommitdiffstats
path: root/src/d3dframe.cpp
diff options
context:
space:
mode:
authoradiblol <adiblol@1tbps.org>2012-03-08 19:32:05 +0100
committeradiblol <adiblol@1tbps.org>2012-03-08 19:32:05 +0100
commita4c804b49ec872b71bd5a0167c3ad45704a3cc30 (patch)
tree8c931235247d662ca46a99695beb328fdfc8e8a8 /src/d3dframe.cpp
downloadcolobot-a4c804b49ec872b71bd5a0167c3ad45704a3cc30.tar.gz
colobot-a4c804b49ec872b71bd5a0167c3ad45704a3cc30.tar.bz2
colobot-a4c804b49ec872b71bd5a0167c3ad45704a3cc30.zip
Initial commit, Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
Diffstat (limited to 'src/d3dframe.cpp')
-rw-r--r--src/d3dframe.cpp607
1 files changed, 607 insertions, 0 deletions
diff --git a/src/d3dframe.cpp b/src/d3dframe.cpp
new file mode 100644
index 0000000..a1189d1
--- /dev/null
+++ b/src/d3dframe.cpp
@@ -0,0 +1,607 @@
+//-----------------------------------------------------------------------------
+// File: D3DFrame.cpp
+//
+// Desc: Class functions to implement a Direct3D app framework.
+//
+// Copyright (c) 1995-1999 by Microsoft, all rights reserved
+//-----------------------------------------------------------------------------
+#define STRICT
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+#include "D3DFrame.h"
+#include "D3DUtil.h"
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CD3DFramework7()
+// Desc: The constructor. Clears static variables
+//-----------------------------------------------------------------------------
+CD3DFramework7::CD3DFramework7()
+{
+ m_hWnd = NULL;
+ m_bIsFullscreen = FALSE;
+ m_bIsStereo = FALSE;
+ m_dwRenderWidth = 0L;
+ m_dwRenderHeight = 0L;
+
+ m_pddsFrontBuffer = NULL;
+ m_pddsBackBuffer = NULL;
+ m_pddsBackBufferLeft = NULL;
+
+ m_pddsZBuffer = NULL;
+ m_pd3dDevice = NULL;
+ m_pDD = NULL;
+ m_pD3D = NULL;
+ m_dwDeviceMemType = NULL;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: ~CD3DFramework7()
+// Desc: The destructor. Deletes all objects
+//-----------------------------------------------------------------------------
+CD3DFramework7::~CD3DFramework7()
+{
+ DestroyObjects();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: DestroyObjects()
+// Desc: Cleans everything up upon deletion. This code returns an error
+// if any of the objects have remaining reference counts.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::DestroyObjects()
+{
+ LONG nDD = 0L; // Number of outstanding DDraw references
+ LONG nD3D = 0L; // Number of outstanding D3DDevice references
+
+ if( m_pDD )
+ {
+ HRESULT err = m_pDD->SetCooperativeLevel( m_hWnd, DDSCL_NORMAL );
+ char s[100];
+ sprintf(s, "SetCooperativeLevel error=%d\n", err);
+ OutputDebugString(s);
+ }
+
+ // Do a safe check for releasing the D3DDEVICE. RefCount must be zero.
+ if( m_pd3dDevice )
+ if( 0 < ( nD3D = m_pd3dDevice->Release() ) )
+ DEBUG_MSG( _T("Error: D3DDevice object is still referenced!") );
+ m_pd3dDevice = NULL;
+
+ SAFE_RELEASE( m_pddsBackBuffer );
+ SAFE_RELEASE( m_pddsBackBufferLeft );
+ SAFE_RELEASE( m_pddsZBuffer );
+ SAFE_RELEASE( m_pddsFrontBuffer );
+ SAFE_RELEASE( m_pD3D );
+
+ if( m_pDD )
+ {
+ // Do a safe check for releasing DDRAW. RefCount must be zero.
+ if( 0 < ( nDD = m_pDD->Release() ) )
+ DEBUG_MSG( _T("Error: DDraw object is still referenced!") );
+ }
+ m_pDD = NULL;
+
+ // Return successful, unless there are outstanding DD or D3DDevice refs.
+ return ( nDD==0 && nD3D==0 ) ? S_OK : D3DFWERR_NONZEROREFCOUNT;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: Initialize()
+// Desc: Creates the internal objects for the framework
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::Initialize( HWND hWnd, GUID* pDriverGUID,
+ GUID* pDeviceGUID, DDSURFACEDESC2* pMode,
+ DWORD dwFlags )
+{
+ HRESULT hr;
+
+ // Check params. Note: A NULL mode is valid for windowed modes only.
+ if( ( NULL==hWnd ) || ( NULL==pDeviceGUID ) ||
+ ( NULL==pMode && (dwFlags&D3DFW_FULLSCREEN) ) )
+ return E_INVALIDARG;
+
+ // Setup state for windowed/fullscreen mode
+ m_hWnd = hWnd;
+ m_bIsStereo = FALSE;
+ m_bIsFullscreen = ( dwFlags & D3DFW_FULLSCREEN ) ? TRUE : FALSE;
+
+ // Support stereoscopic viewing for fullscreen modes which support it
+ if( ( dwFlags & D3DFW_STEREO ) && ( dwFlags & D3DFW_FULLSCREEN ) )
+ if( pMode->ddsCaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT )
+ m_bIsStereo = TRUE;
+
+ // Create the D3D rendering environment (surfaces, device, viewport, etc.)
+ if( FAILED( hr = CreateEnvironment( pDriverGUID, pDeviceGUID, pMode,
+ dwFlags ) ) )
+ {
+ DestroyObjects();
+ return hr;
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateEnvironment()
+// Desc: Creates the internal objects for the framework
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::CreateEnvironment( GUID* pDriverGUID, GUID* pDeviceGUID,
+ DDSURFACEDESC2* pMode, DWORD dwFlags )
+{
+ HRESULT hr;
+
+ // Select the default memory type, for whether the device is HW or SW
+ if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice) )
+ m_dwDeviceMemType = DDSCAPS_VIDEOMEMORY;
+ else if( IsEqualIID( *pDeviceGUID, IID_IDirect3DTnLHalDevice) )
+ m_dwDeviceMemType = DDSCAPS_VIDEOMEMORY;
+ else
+ m_dwDeviceMemType = DDSCAPS_SYSTEMMEMORY;
+
+ // Create the DDraw object
+ hr = CreateDirectDraw( pDriverGUID, dwFlags );
+ if( FAILED( hr ) )
+ return hr;
+
+ // Create the front and back buffers, and attach a clipper
+ if( dwFlags & D3DFW_FULLSCREEN )
+ hr = CreateFullscreenBuffers( pMode );
+ else
+ hr = CreateWindowedBuffers();
+ if( FAILED( hr ) )
+ return hr;
+
+ // Create the Direct3D object and the Direct3DDevice object
+ hr = CreateDirect3D( pDeviceGUID );
+ if( FAILED( hr ) )
+ return hr;
+
+ // Create and attach the zbuffer
+ if( dwFlags & D3DFW_ZBUFFER )
+ hr = CreateZBuffer( pDeviceGUID );
+ if( FAILED( hr ) )
+ return hr;
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: EnumZBufferFormatsCallback()
+// Desc: Simply returns the first matching enumerated z-buffer format
+//-----------------------------------------------------------------------------
+static HRESULT WINAPI EnumZBufferFormatsCallback( DDPIXELFORMAT* pddpf,
+ VOID* pContext )
+{
+ DDPIXELFORMAT* pddpfOut = (DDPIXELFORMAT*)pContext;
+
+ if( pddpfOut->dwRGBBitCount == pddpf->dwRGBBitCount )
+ {
+ (*pddpfOut) = (*pddpf);
+ return D3DENUMRET_CANCEL;
+ }
+
+ return D3DENUMRET_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateDirectDraw()
+// Desc: Create the DirectDraw interface
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::CreateDirectDraw( GUID* pDriverGUID, DWORD dwFlags )
+{
+ // Create the DirectDraw interface, and query for the DD7 interface
+ if( FAILED( DirectDrawCreateEx( pDriverGUID, (VOID**)&m_pDD,
+ IID_IDirectDraw7, NULL ) ) )
+ {
+ DEBUG_MSG( _T("Could not create DirectDraw") );
+ return D3DFWERR_NODIRECTDRAW;
+ }
+
+ // Set the Windows cooperative level
+ DWORD dwCoopFlags = DDSCL_NORMAL;
+ if( m_bIsFullscreen )
+ dwCoopFlags = DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN;
+
+ // By defualt, set the flag to allow D3D to optimize floating point calcs
+ if( 0L == ( dwFlags & D3DFW_NO_FPUSETUP ) )
+ dwCoopFlags |= DDSCL_FPUSETUP;
+
+ if( FAILED( m_pDD->SetCooperativeLevel( m_hWnd, dwCoopFlags ) ) )
+ {
+ DEBUG_MSG( _T("Couldn't set coop level") );
+ return D3DFWERR_COULDNTSETCOOPLEVEL;
+ }
+
+ // Check that we are NOT in a palettized display. That case will fail,
+ // since the framework doesn't use palettes.
+ DDSURFACEDESC2 ddsd;
+ ddsd.dwSize = sizeof(ddsd);
+ m_pDD->GetDisplayMode( &ddsd );
+ if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
+ return D3DFWERR_INVALIDMODE;
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateFullscreenBuffers()
+// Desc: Creates the primary and (optional) backbuffer for rendering.
+// Windowed mode and fullscreen mode are handled differently.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::CreateFullscreenBuffers( DDSURFACEDESC2* pddsd )
+{
+ HRESULT hr;
+
+ // Get the dimensions of the screen bounds
+ // Store the rectangle which contains the renderer
+ SetRect( &m_rcScreenRect, 0, 0, pddsd->dwWidth, pddsd->dwHeight );
+ m_dwRenderWidth = m_rcScreenRect.right - m_rcScreenRect.left;
+ m_dwRenderHeight = m_rcScreenRect.bottom - m_rcScreenRect.top;
+
+ // Set the display mode to the requested dimensions. Check for
+ // 320x200x8 modes, and set flag to avoid using ModeX
+ DWORD dwModeFlags = 0;
+
+ if( (320==m_dwRenderWidth) && (200==m_dwRenderHeight) &&
+ (8==pddsd->ddpfPixelFormat.dwRGBBitCount) )
+ dwModeFlags |= DDSDM_STANDARDVGAMODE;
+
+ if( FAILED( m_pDD->SetDisplayMode( m_dwRenderWidth, m_dwRenderHeight,
+ pddsd->ddpfPixelFormat.dwRGBBitCount,
+ pddsd->dwRefreshRate, dwModeFlags ) ) )
+ {
+ DEBUG_MSG( _T("Can't set display mode") );
+ return D3DFWERR_BADDISPLAYMODE;
+ }
+
+ // Setup to create the primary surface w/backbuffer
+ DDSURFACEDESC2 ddsd;
+ ZeroMemory( &ddsd, sizeof(ddsd) );
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE |
+ DDSCAPS_FLIP | DDSCAPS_COMPLEX;
+ ddsd.dwBackBufferCount = 1;
+
+ // Support for stereoscopic viewing
+ if( m_bIsStereo )
+ {
+ ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+ ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_STEREOSURFACELEFT;
+ }
+
+ // Create the primary surface
+ if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
+ {
+ DEBUG_MSG( _T("Error: Can't create primary surface") );
+ if( hr != DDERR_OUTOFVIDEOMEMORY )
+ return D3DFWERR_NOPRIMARY;
+ DEBUG_MSG( _T("Error: Out of video memory") );
+ return DDERR_OUTOFVIDEOMEMORY;
+ }
+
+ // Get the backbuffer, which was created along with the primary.
+ DDSCAPS2 ddscaps = { DDSCAPS_BACKBUFFER, 0, 0, 0 };
+ if( FAILED( hr = m_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
+ &m_pddsBackBuffer ) ) )
+ {
+ DEBUG_ERR( hr, _T("Error: Can't get the backbuffer") );
+ return D3DFWERR_NOBACKBUFFER;
+ }
+
+ // Increment the backbuffer count (for consistency with windowed mode)
+ m_pddsBackBuffer->AddRef();
+
+ // Support for stereoscopic viewing
+ if( m_bIsStereo )
+ {
+ // Get the left backbuffer, which was created along with the primary.
+ DDSCAPS2 ddscaps = { 0, DDSCAPS2_STEREOSURFACELEFT, 0, 0 };
+ if( FAILED( hr = m_pddsBackBuffer->GetAttachedSurface( &ddscaps,
+ &m_pddsBackBufferLeft ) ) )
+ {
+ DEBUG_ERR( hr, _T("Error: Can't get the left backbuffer") );
+ return D3DFWERR_NOBACKBUFFER;
+ }
+ m_pddsBackBufferLeft->AddRef();
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateWindowedBuffers()
+// Desc: Creates the primary and (optional) backbuffer for rendering.
+// Windowed mode and fullscreen mode are handled differently.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::CreateWindowedBuffers()
+{
+ HRESULT hr;
+
+ // Get the dimensions of the viewport and screen bounds
+ GetClientRect( m_hWnd, &m_rcScreenRect );
+ ClientToScreen( m_hWnd, (POINT*)&m_rcScreenRect.left );
+ ClientToScreen( m_hWnd, (POINT*)&m_rcScreenRect.right );
+ m_dwRenderWidth = m_rcScreenRect.right - m_rcScreenRect.left;
+ m_dwRenderHeight = m_rcScreenRect.bottom - m_rcScreenRect.top;
+
+ // Create the primary surface
+ DDSURFACEDESC2 ddsd;
+ ZeroMemory( &ddsd, sizeof(ddsd) );
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+
+ if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
+ {
+ DEBUG_MSG( _T("Error: Can't create primary surface") );
+ if( hr != DDERR_OUTOFVIDEOMEMORY )
+ return D3DFWERR_NOPRIMARY;
+ DEBUG_MSG( _T("Error: Out of video memory") );
+ return DDERR_OUTOFVIDEOMEMORY;
+ }
+
+ // If in windowed-mode, create a clipper object
+ LPDIRECTDRAWCLIPPER pcClipper;
+ if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
+ {
+ DEBUG_MSG( _T("Error: Couldn't create clipper") );
+ return D3DFWERR_NOCLIPPER;
+ }
+
+ // Associate the clipper with the window
+ pcClipper->SetHWnd( 0, m_hWnd );
+ m_pddsFrontBuffer->SetClipper( pcClipper );
+ SAFE_RELEASE( pcClipper );
+
+ // Create a backbuffer
+ ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
+ ddsd.dwWidth = m_dwRenderWidth;
+ ddsd.dwHeight = m_dwRenderHeight;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
+
+ if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
+ {
+ DEBUG_ERR( hr, _T("Error: Couldn't create the backbuffer") );
+ if( hr != DDERR_OUTOFVIDEOMEMORY )
+ return D3DFWERR_NOBACKBUFFER;
+ DEBUG_MSG( _T("Error: Out of video memory") );
+ return DDERR_OUTOFVIDEOMEMORY;
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateDirect3D()
+// Desc: Create the Direct3D interface
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::CreateDirect3D( GUID* pDeviceGUID )
+{
+ // Query DirectDraw for access to Direct3D
+ if( FAILED( m_pDD->QueryInterface( IID_IDirect3D7, (VOID**)&m_pD3D ) ) )
+ {
+ DEBUG_MSG( _T("Couldn't get the Direct3D interface") );
+ return D3DFWERR_NODIRECT3D;
+ }
+
+ // Create the device
+ if( FAILED( m_pD3D->CreateDevice( *pDeviceGUID, m_pddsBackBuffer,
+ &m_pd3dDevice) ) )
+ {
+ DEBUG_MSG( _T("Couldn't create the D3DDevice") );
+ return D3DFWERR_NO3DDEVICE;
+ }
+
+ // Finally, set the viewport for the newly created device
+ D3DVIEWPORT7 vp = { 0, 0, m_dwRenderWidth, m_dwRenderHeight, 0.0f, 1.0f };
+
+ if( FAILED( m_pd3dDevice->SetViewport( &vp ) ) )
+ {
+ DEBUG_MSG( _T("Error: Couldn't set current viewport to device") );
+ return D3DFWERR_NOVIEWPORT;
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CreateZBuffer()
+// Desc: Internal function called by Create() to make and attach a zbuffer
+// to the renderer
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::CreateZBuffer( GUID* pDeviceGUID )
+{
+ HRESULT hr;
+
+ // Check if the device supports z-bufferless hidden surface removal. If so,
+ // we don't really need a z-buffer
+ D3DDEVICEDESC7 ddDesc;
+ m_pd3dDevice->GetCaps( &ddDesc );
+ if( ddDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )
+ return S_OK;
+
+ // Get z-buffer dimensions from the render target
+ DDSURFACEDESC2 ddsd;
+ ddsd.dwSize = sizeof(ddsd);
+ m_pddsBackBuffer->GetSurfaceDesc( &ddsd );
+
+ // Setup the surface desc for the z-buffer.
+ ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | m_dwDeviceMemType;
+ ddsd.ddpfPixelFormat.dwSize = 0; // Tag the pixel format as unitialized
+
+ // Get an appropiate pixel format from enumeration of the formats. On the
+ // first pass, we look for a zbuffer dpeth which is equal to the frame
+ // buffer depth (as some cards unfornately require this).
+ m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback,
+ (VOID*)&ddsd.ddpfPixelFormat );
+ if( 0 == ddsd.ddpfPixelFormat.dwSize )
+ {
+ // Try again, just accepting any 16-bit zbuffer
+ ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
+ m_pD3D->EnumZBufferFormats( *pDeviceGUID, EnumZBufferFormatsCallback,
+ (VOID*)&ddsd.ddpfPixelFormat );
+
+ if( 0 == ddsd.ddpfPixelFormat.dwSize )
+ {
+ DEBUG_MSG( _T("Device doesn't support requested zbuffer format") );
+ return D3DFWERR_NOZBUFFER;
+ }
+ }
+
+ // Create and attach a z-buffer
+ if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsZBuffer, NULL ) ) )
+ {
+ DEBUG_MSG( _T("Error: Couldn't create a ZBuffer surface") );
+ if( hr != DDERR_OUTOFVIDEOMEMORY )
+ return D3DFWERR_NOZBUFFER;
+ DEBUG_MSG( _T("Error: Out of video memory") );
+ return DDERR_OUTOFVIDEOMEMORY;
+ }
+
+ if( FAILED( m_pddsBackBuffer->AddAttachedSurface( m_pddsZBuffer ) ) )
+ {
+ DEBUG_MSG( _T("Error: Couldn't attach zbuffer to render surface") );
+ return D3DFWERR_NOZBUFFER;
+ }
+
+ // For stereoscopic viewing, attach zbuffer to left surface as well
+ if( m_bIsStereo )
+ {
+ if( FAILED( m_pddsBackBufferLeft->AddAttachedSurface( m_pddsZBuffer ) ) )
+ {
+ DEBUG_MSG( _T("Error: Couldn't attach zbuffer to left render surface") );
+ return D3DFWERR_NOZBUFFER;
+ }
+ }
+
+ // Finally, this call rebuilds internal structures
+ if( FAILED( m_pd3dDevice->SetRenderTarget( m_pddsBackBuffer, 0L ) ) )
+ {
+ DEBUG_MSG( _T("Error: SetRenderTarget() failed after attaching zbuffer!") );
+ return D3DFWERR_NOZBUFFER;
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: RestoreSurfaces()
+// Desc: Checks for lost surfaces and restores them if lost. Note: Don't
+// restore render surface, since it's just a duplicate ptr.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::RestoreSurfaces()
+{
+ // Restore all surfaces (including video memory vertex buffers)
+ m_pDD->RestoreAllSurfaces();
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: Move()
+// Desc: Moves the screen rect for windowed renderers
+//-----------------------------------------------------------------------------
+VOID CD3DFramework7::Move( INT x, INT y )
+{
+ if( TRUE == m_bIsFullscreen )
+ return;
+
+ SetRect( &m_rcScreenRect, x, y, x + m_dwRenderWidth, y + m_dwRenderHeight );
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: FlipToGDISurface()
+// Desc: Puts the GDI surface in front of the primary, so that dialog
+// boxes and other windows drawing funcs may happen.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::FlipToGDISurface( BOOL bDrawFrame )
+{
+ if( m_pDD && m_bIsFullscreen )
+ {
+ m_pDD->FlipToGDISurface();
+
+ if( bDrawFrame )
+ {
+ DrawMenuBar( m_hWnd );
+ RedrawWindow( m_hWnd, NULL, NULL, RDW_FRAME );
+ }
+ }
+
+ return S_OK;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: ShowFrame()
+// Desc: Show the frame on the primary surface, via a blt or a flip.
+//-----------------------------------------------------------------------------
+HRESULT CD3DFramework7::ShowFrame()
+{
+ if( NULL == m_pddsFrontBuffer )
+ return D3DFWERR_NOTINITIALIZED;
+
+ if( m_bIsFullscreen )
+ {
+ // We are in fullscreen 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 are in windowed mode, so perform a blit.
+ return m_pddsFrontBuffer->Blt( &m_rcScreenRect, m_pddsBackBuffer,
+ NULL, DDBLT_WAIT, NULL );
+ }
+}
+
+
+