Fix window resize/fullscreen handling and make consistent between DX12 and Vulkan (Windows & SDL)

This commit is contained in:
Stephen Saunders 2022-11-11 21:51:31 -05:00
parent f5745b4ab6
commit 7a7571f88a
5 changed files with 54 additions and 18 deletions

View file

@ -204,15 +204,6 @@ void DeviceManager_DX12::ReportLiveObjects()
bool DeviceManager_DX12::CreateDeviceAndSwapChain()
{
UINT windowStyle = deviceParms.startFullscreen
? ( WS_POPUP | WS_SYSMENU | WS_VISIBLE )
: deviceParms.startMaximized
? ( WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE )
: ( WS_OVERLAPPEDWINDOW | WS_VISIBLE );
RECT rect = { 0, 0, LONG( deviceParms.backBufferWidth ), LONG( deviceParms.backBufferHeight ) };
AdjustWindowRect( &rect, windowStyle, FALSE );
RefCountPtr<IDXGIAdapter> targetAdapter;
if( deviceParms.adapter )
@ -248,12 +239,25 @@ bool DeviceManager_DX12::CreateDeviceAndSwapChain()
isNvidia = IsNvDeviceID( aDesc.VendorId );
}
/*
// SRS - Don't center window here for DX12 only, instead use portable initialization in CreateWindowDeviceAndSwapChain() within win_glimp.cpp
// - Also, calling SetWindowPos() triggers a window mgr event that overwrites r_windowX / r_windowY, which may be undesirable to the user
UINT windowStyle = deviceParms.startFullscreen
? ( WS_POPUP | WS_SYSMENU | WS_VISIBLE )
: deviceParms.startMaximized
? ( WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE )
: ( WS_OVERLAPPEDWINDOW | WS_VISIBLE );
RECT rect = { 0, 0, LONG( deviceParms.backBufferWidth ), LONG( deviceParms.backBufferHeight ) };
AdjustWindowRect( &rect, windowStyle, FALSE );
if( MoveWindowOntoAdapter( targetAdapter, rect ) )
{
SetWindowPos( ( HWND )windowHandle, deviceParms.startFullscreen ? HWND_TOPMOST : HWND_NOTOPMOST,
rect.left, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE );
}
*/
HRESULT hr = E_FAIL;
RECT clientRect;

View file

@ -1062,7 +1062,7 @@ sysEvent_t Sys_GetEvent()
case SDL_KEYDOWN:
if( ev.key.keysym.sym == SDLK_RETURN && ( ev.key.keysym.mod & KMOD_ALT ) > 0 )
{
// DG: go to fullscreen on current display, instead of always first display
/* DG: go to fullscreen on current display, instead of always first display
int fullscreen = 0;
if( ! renderSystem->IsFullScreen() )
{
@ -1071,7 +1071,10 @@ sysEvent_t Sys_GetEvent()
fullscreen = -2;
}
cvarSystem->SetCVarInteger( "r_fullscreen", fullscreen );
// DG end
// DG end */
// SRS - Until Borderless Fullscreen is implemented properly, use same implementation as on Windows
cvarSystem->SetCVarBool( "r_fullscreen", !renderSystem->IsFullScreen() );
// SRS end
PushConsoleEvent( "vid_restart" );
continue; // handle next event
}

View file

@ -135,8 +135,6 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c
return false;
}
glConfig.isFullscreen = parms.fullScreen;
return true;
}

View file

@ -1065,6 +1065,29 @@ static bool GLW_GetWindowDimensions( const glimpParms_t parms, int& x, int& y, i
return true;
}
static bool GetCenteredWindowDimensions( int& x, int& y, int& w, int& h )
{
// get position and size of default display for windowed mode (parms.fullScreen = 0)
int displayX, displayY, displayW, displayH, displayHz = 0;
if( !GetDisplayCoordinates( 0, displayX, displayY, displayW, displayH, displayHz ) )
{
return false;
}
// find the centered position not exceeding display bounds
const int centreX = displayX + displayW / 2;
const int centreY = displayY + displayH / 2;
const int left = centreX - w / 2;
const int right = left + w;
const int top = centreY - h / 2;
const int bottom = top + h;
x = std::max( left, displayX );
y = std::max( top, displayY );
w = std::min( right - left, displayW );
h = std::min( bottom - top, displayH );
return true;
}
bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, const char* windowTitle )
{
@ -1074,6 +1097,15 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c
return false;
}
// SRS - if in windowed mode, start with centered windowed on default display, afterwards use r_windowX / r_windowY
if( parms.fullScreen == 0 )
{
if( !GetCenteredWindowDimensions( x, y, w, h ) )
{
return false;
}
}
int stylebits;
int exstyle;
@ -1136,8 +1168,6 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c
SetForegroundWindow( win32.hWnd );
SetFocus( win32.hWnd );
glConfig.isFullscreen = parms.fullScreen;
return true;
}

View file

@ -179,7 +179,6 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
switch( uMsg )
{
case WM_WINDOWPOSCHANGED:
// RB: FIXME this messes with with the window size in a really bad way
// SRS - Needed by ResizeImages() to resize before the start of a frame
// SRS - Aspect ratio constraints are controlled by WIN_Sizing() above
if( renderSystem->IsInitialized() && win32.hDC != NULL )
@ -193,8 +192,9 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
glConfig.nativeScreenHeight = rect.bottom - rect.top;
// save the window size in cvars if we aren't fullscreen
// SRS - also check renderSystem state to make sure WM doesn't fool us when exiting fullscreen
int style = GetWindowLong( hWnd, GWL_STYLE );
if( ( style & WS_POPUP ) == 0 )
if( ( style & WS_POPUP ) == 0 && !renderSystem->IsFullScreen() )
{
r_windowWidth.SetInteger( glConfig.nativeScreenWidth );
r_windowHeight.SetInteger( glConfig.nativeScreenHeight );
@ -212,8 +212,9 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
RECT r;
// save the window origin in cvars if we aren't fullscreen
// SRS - also check renderSystem state to make sure WM doesn't fool us when exiting fullscreen
int style = GetWindowLong( hWnd, GWL_STYLE );
if( ( style & WS_POPUP ) == 0 )
if( ( style & WS_POPUP ) == 0 && !renderSystem->IsFullScreen() )
{
xPos = ( short ) LOWORD( lParam ); // horizontal position
yPos = ( short ) HIWORD( lParam ); // vertical position