📄 d3dapp.cpp
字号:
return TRUE;
}
break;
case WM_SYSCOMMAND:
// Prevent moving/sizing and power loss in fullscreen mode
switch( wParam )
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_KEYMENU:
case SC_MONITORPOWER:
if( FALSE == m_bWindowed )
return 1;
break;
}
break;
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDM_TOGGLESTART:
// Toggle frame movement
m_bFrameMoving = !m_bFrameMoving;
DXUtil_Timer( m_bFrameMoving ? TIMER_START : TIMER_STOP );
break;
case IDM_SINGLESTEP:
// Single-step frame movement
if( FALSE == m_bFrameMoving )
DXUtil_Timer( TIMER_ADVANCE );
else
DXUtil_Timer( TIMER_STOP );
m_bFrameMoving = FALSE;
m_bSingleStep = TRUE;
break;
case IDM_CHANGEDEVICE:
// Prompt the user to select a new device or mode
if( m_bActive && m_bReady )
{
Pause(TRUE);
if( FAILED( hr = UserSelectNewDevice() ) )
return 0;
Pause(FALSE);
}
return 0;
case IDM_TOGGLEFULLSCREEN:
// Toggle the fullscreen/window mode
if( m_bActive && m_bReady )
{
if( FAILED( ToggleFullscreen() ) )
{
DisplayErrorMsg( D3DAPPERR_RESIZEFAILED, MSGERR_APPMUSTEXIT );
return 0;
}
}
return 0;
case IDM_EXIT:
// Recieved key/menu command to exit app
SendMessage( hWnd, WM_CLOSE, 0, 0 );
return 0;
}
break;
case WM_CLOSE:
Cleanup3DEnvironment();
DestroyMenu( GetMenu(hWnd) );
DestroyWindow( hWnd );
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: Initialize3DEnvironment()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CD3DApplication::Initialize3DEnvironment()
{
HRESULT hr;
D3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter];
D3DDeviceInfo* pDeviceInfo = &pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice];
D3DModeInfo* pModeInfo = &pDeviceInfo->modes[pDeviceInfo->dwCurrentMode];
// Prepare window for possible windowed/fullscreen change
AdjustWindowForChange();
// Set up the presentation parameters
ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) );
m_d3dpp.Windowed = pDeviceInfo->bWindowed;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleType;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dpp.EnableAutoDepthStencil = m_bUseDepthBuffer;
m_d3dpp.AutoDepthStencilFormat = pModeInfo->DepthStencilFormat;
m_d3dpp.hDeviceWindow = m_hWnd;
if( m_bWindowed )
{
m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
m_d3dpp.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
}
else
{
m_d3dpp.BackBufferWidth = pModeInfo->Width;
m_d3dpp.BackBufferHeight = pModeInfo->Height;
m_d3dpp.BackBufferFormat = pModeInfo->Format;
}
// Create the device
hr = m_pD3D->CreateDevice( m_dwAdapter, pDeviceInfo->DeviceType,
m_hWndFocus, pModeInfo->dwBehavior, &m_d3dpp,
&m_pd3dDevice );
if( SUCCEEDED(hr) )
{
// When moving from fullscreen to windowed mode, it is important to
// adjust the window size after recreating the device rather than
// beforehand to ensure that you get the window size you want. For
// example, when switching from 640x480 fullscreen to windowed with
// a 1000x600 window on a 1024x768 desktop, it is impossible to set
// the window size to 1000x600 until after the display mode has
// changed to 1024x768, because windows cannot be larger than the
// desktop.
if( m_bWindowed )
{
SetWindowPos( m_hWnd, HWND_NOTOPMOST,
m_rcWindowBounds.left, m_rcWindowBounds.top,
( m_rcWindowBounds.right - m_rcWindowBounds.left ),
( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
SWP_SHOWWINDOW );
}
// Store device Caps
m_pd3dDevice->GetDeviceCaps( &m_d3dCaps );
m_dwCreateFlags = pModeInfo->dwBehavior;
// Store device description
if( pDeviceInfo->DeviceType == D3DDEVTYPE_REF )
lstrcpy( m_strDeviceStats, TEXT("REF") );
else if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
lstrcpy( m_strDeviceStats, TEXT("HAL") );
else if( pDeviceInfo->DeviceType == D3DDEVTYPE_SW )
lstrcpy( m_strDeviceStats, TEXT("SW") );
if( pModeInfo->dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING &&
pModeInfo->dwBehavior & D3DCREATE_PUREDEVICE )
{
if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
lstrcat( m_strDeviceStats, TEXT(" (pure hw vp)") );
else
lstrcat( m_strDeviceStats, TEXT(" (simulated pure hw vp)") );
}
else if( pModeInfo->dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING )
{
if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
lstrcat( m_strDeviceStats, TEXT(" (hw vp)") );
else
lstrcat( m_strDeviceStats, TEXT(" (simulated hw vp)") );
}
else if( pModeInfo->dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING )
{
if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
lstrcat( m_strDeviceStats, TEXT(" (mixed vp)") );
else
lstrcat( m_strDeviceStats, TEXT(" (simulated mixed vp)") );
}
else if( pModeInfo->dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING )
{
lstrcat( m_strDeviceStats, TEXT(" (sw vp)") );
}
if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
{
lstrcat( m_strDeviceStats, TEXT(": ") );
lstrcat( m_strDeviceStats, pAdapterInfo->d3dAdapterIdentifier.Description );
}
// Store render target surface desc
LPDIRECT3DSURFACE8 pBackBuffer;
m_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
pBackBuffer->Release();
// Set up the fullscreen cursor
if( m_bShowCursorWhenFullscreen && !m_bWindowed )
{
HCURSOR hCursor;
#ifdef _WIN64
hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR );
#else
hCursor = (HCURSOR)GetClassLong( m_hWnd, GCL_HCURSOR );
#endif
D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor );
m_pd3dDevice->ShowCursor( TRUE );
}
// Initialize the app's device-dependent objects
hr = InitDeviceObjects();
if( SUCCEEDED(hr) )
{
hr = RestoreDeviceObjects();
if( SUCCEEDED(hr) )
{
m_bActive = TRUE;
return S_OK;
}
}
// Cleanup before we try again
InvalidateDeviceObjects();
DeleteDeviceObjects();
SAFE_RELEASE( m_pd3dDevice );
}
// If that failed, fall back to the reference rasterizer
if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
{
// Let the user know we are switching from HAL to the reference rasterizer
DisplayErrorMsg( hr, MSGWARN_SWITCHEDTOREF );
// Select the default adapter
m_dwAdapter = 0L;
pAdapterInfo = &m_Adapters[m_dwAdapter];
// Look for a software device
for( UINT i=0L; i<pAdapterInfo->dwNumDevices; i++ )
{
if( pAdapterInfo->devices[i].DeviceType == D3DDEVTYPE_REF )
{
pAdapterInfo->dwCurrentDevice = i;
pDeviceInfo = &pAdapterInfo->devices[i];
m_bWindowed = pDeviceInfo->bWindowed;
break;
}
}
// Try again, this time with the reference rasterizer
if( pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice].DeviceType ==
D3DDEVTYPE_REF )
{
hr = Initialize3DEnvironment();
}
}
return hr;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CD3DApplication::Resize3DEnvironment()
{
HRESULT hr;
// Release all vidmem objects
if( FAILED( hr = InvalidateDeviceObjects() ) )
return hr;
// Reset the device
if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dpp ) ) )
return hr;
// Store render target surface desc
LPDIRECT3DSURFACE8 pBackBuffer;
m_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
pBackBuffer->Release();
// Set up the fullscreen cursor
if( m_bShowCursorWhenFullscreen && !m_bWindowed )
{
HCURSOR hCursor;
#ifdef _WIN64
hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR );
#else
hCursor = (HCURSOR)GetClassLong( m_hWnd, GCL_HCURSOR );
#endif
D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor );
m_pd3dDevice->ShowCursor( TRUE );
}
// Initialize the app's device-dependent objects
hr = RestoreDeviceObjects();
if( FAILED(hr) )
return hr;
// If the app is paused, trigger the rendering of the current frame
if( FALSE == m_bFrameMoving )
{
m_bSingleStep = TRUE;
DXUtil_Timer( TIMER_START );
DXUtil_Timer( TIMER_STOP );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ToggleFullScreen()
// Desc: Called when user toggles between fullscreen mode and windowed mode
//-----------------------------------------------------------------------------
HRESULT CD3DApplication::ToggleFullscreen()
{
// Get access to current adapter, device, and mode
D3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter];
D3DDeviceInfo* pDeviceInfo = &pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice];
D3DModeInfo* pModeInfo = &pDeviceInfo->modes[pDeviceInfo->dwCurrentMode];
// Need device change if going windowed and the current device
// can only be fullscreen
if( !m_bWindowed && !pDeviceInfo->bCanDoWindowed )
return ForceWindowed();
m_bReady = FALSE;
// Toggle the windowed state
m_bWindowed = !m_bWindowed;
pDeviceInfo->bWindowed = m_bWindowed;
// Prepare window for windowed/fullscreen change
AdjustWindowForChange();
// Set up the presentation parameters
m_d3dpp.Windowed = pDeviceInfo->bWindowed;
m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleType;
m_d3dpp.AutoDepthStencilFormat = pModeInfo->DepthStencilFormat;
m_d3dpp.hDeviceWindow = m_hWnd;
if( m_bWindowed )
{
m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
m_d3dpp.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
}
else
{
m_d3dpp.BackBufferWidth = pModeInfo->Width;
m_d3dpp.BackBufferHeight = pModeInfo->Height;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -