Jump to content
  • Advertisement
Sign in to follow this  
login name

Video mdes, resoultions & fullscreen on modern screens

This topic is 602 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Just a short question. When going fullscreen nowadays on modern tft/lcd/led/whatever screens, do you still change video mode when going for fullscreen, or do you just open maximized borderless window? I remember moons ago, when glut had "game mode", which was just maximized borderless window, it was considered as unsatisfying for most "serious" games. But todays monitors, unlike old CRTs, does not really like anything else but their native resolution.

Personally, in my code, I go just for undecorated, maximized window, as fullscreen, but today I red some old literature and got reminded of it, so just as a reflection, I wonder what is your practice and/or opinion? Do you go for some fixed resolution, or do you let your games run on whatever user resolution might be? I suppose it is same problem as web developers meet today with all the variety of devices and resolutions avialable, and what they address with "responsive" web-design techinques.

Share this post


Link to post
Share on other sites
Advertisement

I see some games offering both types of fullscreen as an option to the user now:
- Windowed (bordered window)

- Fullscreen (full mode switching)

- Fullscreen Window (borderless window)

 

Proper mode switching can give slightly better performance and control over the buffer swapping (aka present), but yeah, can look a bit worse on LCD's as it will use the monitor's internal re-scaler, and depending on the OS/drivers, can flicker or take time when switching between the game and a background app.

The borderless window proves much quicker transitions when the user alt+tabs to another app, and gives you control over the rescaling. e.g. you can render at 720p and use a bicubic upsampling filter to the native resolution :wink:

Share this post


Link to post
Share on other sites

If you have more than one monitor then you can quickly learn to hate mode switching games with a deep passion.

QFE.

There's nothing worse than realising that your second monitor is dark and useless just because a game decided to mode switch and capture all displays. Or to have the game mode switch back out every time you interact with the second monitor.

Having at least an optional borderless window mode is a must in this day and age.

Share this post


Link to post
Share on other sites

Thank you guys for this topic!

This topic just saved me a lot of time (I was only aware of FullScreen/Windowed modes), and in current implementation decided to make fullscreen only. I found that debugging is not fun at all in fullscreen, and needed rolling back to 2-mode support.

But now I am happy again! =)

If you have more than one monitor then you can quickly learn to hate mode switching games with a deep passion.

I found simple workaround:

I have 3 monitors. Windows 10 enumerates them as 3-2-1.

Second is the main display with left up corner coordinates 0.0, so when I play in full screen game (Heroes 3), even if mode is changed, the left monitor (3) can show films in fullscreen without problems. But the right monitor is almost useless.

Share this post


Link to post
Share on other sites

Borderless windowed fullscreen is actually pretty easy to implement. You get the dimensions of the monitor, change the window style to remove the border, resize the window, and then just update it and windows will take care of the rest.

  SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP);
  int width  = GetSystemMetrics(SM_CXSCREEN);
  int height = GetSystemMetrics(SM_CYSCREEN);
  SetWindowPos(hWnd, 0, 0, 0, width, height, SWP_SHOWWINDOW);

If you want to allow the user to specify which monitor then there's a bit of additional work to find the coordinates and dimensions of that display, but hopefully that shouldn't be too difficult.

Share this post


Link to post
Share on other sites

I found a little bit strange behavior when I do Present(0,0) in borderless mode (when a window fills entire monitor):
I got only 60 fps.

After some testing, I found that if I place another application’s window over my game window, FPS grows over 60.

Another workaround is to create main window 1 pixel smaller, so for 1920x1080 monitor, the window size would be 1920x1079 (back buffer is 1920x1080).

The only downside is 1-pixel wide desktop line.

If anyone has solved this problem, please share your experience! :)
(My config: Win10, 660 GTX, DX11)

This is a window initialization code:

MainWnd::MainWnd(HINSTANCE hInstance, unsigned display)
{
	registerWndClass(hInstance);
	createWindow(hInstance, display);
}

void MainWnd::registerWndClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;
	wcex.cbSize        = sizeof(WNDCLASSEX);
	wcex.style         = 0;
	wcex.lpfnWndProc   = WndProc;
	wcex.cbClsExtra    = 0;
	wcex.cbWndExtra    = 0;
	wcex.hInstance     = hInstance;
	wcex.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
	wcex.hCursor       = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = NULL; // No need to paint anything
	wcex.lpszMenuName  = nullptr; //No menu
	wcex.lpszClassName = gWndClassName;
	wcex.hIconSm       = nullptr;

	_check_GLE(RegisterClassEx(&wcex)) << "Failed to register MainWnd class";
}

void MainWnd::createWindow(HINSTANCE hInstance, unsigned display)
{
	const auto rect = MGL::GetDesktopCoordinates(display);

	m_hWnd = CreateWindow(gWndClassName, L"Tech4: Game", WS_POPUP, rect.x, rect.y, 
rect.dx, rect.dy-1, NULL, NULL, hInstance, (void*)this);

	_check_GLE(m_hWnd) << "Failed to create window";

	ShowWindow(m_hWnd, SW_SHOW);
}

This is Spy++ flags of the window:
RheP0dK.png
 

Edited by Happy SDE

Share this post


Link to post
Share on other sites

[Maybe it would be useful for someone]:

It is possible to create child window 1x1 pixel size, in this case main window will render without vsync in borderless mode:

class OnePixelChildWindow
{
public:
    void Create(HINSTANCE hInstance, HWND hParent, int x, int y);

private:
    void registerClass(HINSTANCE hInstance);
    void createWindow (HINSTANCE hInstance, HWND hParent, int x, int y);
};


void OnePixelChildWindow::Create(HINSTANCE hInstance, HWND hParent, int x, int y)
{
	registerClass(hInstance);
	createWindow (hInstance, hParent, x, y);
}

void OnePixelChildWindow::registerClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;
	wcex.cbSize        = sizeof(WNDCLASSEX);
	wcex.style         = 0;
	wcex.lpfnWndProc   = DefWindowProc;
	wcex.cbClsExtra    = 0;
	wcex.cbWndExtra    = 0;
	wcex.hInstance     = hInstance;
	wcex.hIcon         = NULL;
	wcex.hCursor       = NULL;
	wcex.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
	wcex.lpszMenuName  = nullptr; //No menu
	wcex.lpszClassName = L"Tech4_1x1";
	wcex.hIconSm       = nullptr;

	_check_GLE(RegisterClassEx(&wcex)) << "Failed to register MainWnd class";
}

void OnePixelChildWindow::createWindow(HINSTANCE hInstance, HWND hParent, int x, int y)
{
	HWND hWnd = CreateWindow(L"Tech4_1x1", nullptr, WS_POPUP , x, y, 1, 1, hParent, NULL, hInstance, nullptr);
	_check_GLE(hWnd) << "Failed to create window";

	ShowWindow(hWnd, SW_SHOW);
}

The main window is needed to set focus to itself after child was created:

void MainWnd::createWindow(HINSTANCE hInstance)
{
	const auto& rect = T4::GetAppCfg().m_currMonitorPos;
	m_hWnd = CreateWindow(gWndClassName, L"Tech4: Game", WS_POPUP, rect.x, rect.y, rect.dx, rect.dy, NULL, NULL, hInstance, (void*)this);
	_check_GLE(m_hWnd) << "Failed to create window";

	ShowWindow(m_hWnd, SW_SHOW);

	int x = rect.x + rect.dx - 1;
	int y = rect.y + rect.dy - 1;
	m_child.Create(hInstance, m_hWnd, x, y);

	SetFocus(m_hWnd);
}
Edited by Happy SDE

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!