📄 d3dframe.cpp
字号:
// 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 );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -