Sign in to follow this  

enumerating adapters and display modes?

This topic is 2041 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

I am confused about enumerating adapters/display modes, and switching to/from fullscreen/windowed in a multi-monitor environment.

First of all, how should my game start up? I haven't really played any PC games since around 2004 - back when most people had 1 monitor and it was 4:3 aspect ratio. Back then, a game would start up in fullscreen, 640x480 (because just about any monitor/adapter would support it), and you could change to a higher resolution through the menus.

What is the typical way this is handled these days? I can't just pick a typically-supported low resolution, because I don't know if the monitor is widescreen. It would look pretty amateur to start up in a 4:3 aspect ratio on a 16:9 monitor and have the image be stretched.

Also, what choices do you display in your graphics options? Suppose I have two monitors - monitor 1 and monitor 2. Let's say the user has gone into windowed mode, and drags the window around. How do I know which monitor the window is on? (It could even be spanning 2 monitors). I would have to be able to hide display modes that the current monitor can't display.

I suppose I could just download the demo of a modern game and look at their graphics options.

Share this post


Link to post
Share on other sites
So, first things first:

Your application should never change the display mode unless I ask it to. This is 2012, you don't need to start your game at 640x480. Launch it at the resolution my screen is currently running at, as that's my preferred resolution. The number of games that, even today, start the game by default in a reduced resolution is significant. It irritates me greatly, especially since I'm on a multi-monitor system and it FUCKS UP the windows on the secondary monitor.

You should assume decent defaults, optionally you could run a performance test on first startup that makes a decent guess at the appropriate settings. Make sure to inform the customer of this though, don't just start changing resolutions and running demos to test performance.

Allow the user to change the settings. Either in game or a launcher control panel.

Support Full-screen Windowed mode. This is a window (typically WS_POPUP) that is NOT WS_EX_TOPMOST and does not involve a resolution change. It's a windowed application that takes up the entire desktop. GetDesktopWindow, GetWindowRect can be used to appropriately size the window.

You should always start up on the primary display unless I specify otherwise. If your application is in windowed mode and they drag it around then there are messages you can trap to change it to the appropriate device, although the windowed device is typically virtualized somewhat so its not that big of an issue.

All modern APIs (read DX) support mechanisms for querying the display modes, bit depths, texture modes, and anti-aliasing techniques supported by the card. You can use this to tailor your presented options correctly. Edited by Washu

Share this post


Link to post
Share on other sites
I have a dialog box that enumerates available display modes and asks the user to choose one from a combobox. It also has a checkbox for fullscreen and a checkbox to save settings. At startup I check for saved display settings and attempt to use them; if that fails, or if settings are not found, I display the dialog. I intentionally don't have default display settings, forcing the dialog the first time the game is run.

The only thing is that I only consider the primary display device. My desk is too small for two monitors, so I haven't gotten around to supporting it in the dialog.

Share this post


Link to post
Share on other sites
Thanks for bringing me into the modern age, lol.

@washu: starting on the primary display at the current resolution solves all my problems! I didn't think it would be that simple.

Why do you recommend "fullscreen windowed" mode? Does it make your game play nicely with alt-tab?

Share this post


Link to post
Share on other sites
Yes. A game that is fullscreen-windowed can be trivially alt tabbed between say a "guide" and the game. Or if you have other windows open on other screens your are not constantly changing resolution/flickering every time you alt+tab in and out of the game.

From the player's perspective it makes a lot more sense. They not longer go "what the fuck? I hit some key on my keyboard and the entire game vanished, where did it go?" Edited by Washu

Share this post


Link to post
Share on other sites
Ok, so if I am going to start up in fullscreen windowed mode, do I still give the user the option to go to windowed mode? If so, what would my app do, just change the window style so that the title bar and borders are displayed?

Currently I am starting off with a WS_POPUP window. When the user hits 'W', I run the following code:


SetWindowLongPtr(g_hWnd, GWL_STYLE, WS_OVERLAPPED);
SetWindowPos(g_hWnd, HWND_TOP, curWindowPosX, curWindowPosY, windowedWidth, windowedHeight, SW_SHOW);

(curWindowPosX and curWindowPosY are both set to 50, and never changed. windowedWidth and windowedHeight are set to 640 and 480 respectively).

But it seems to have no effect. And if I click the window after running that code, it disappears. Any advice on how to switch to a true windowed mode from a fullscreen windowed mode? Edited by codeToad

Share this post


Link to post
Share on other sites
[quote name='codeToad' timestamp='1336603923' post='4938806']
Ok, so if I am going to start up in fullscreen windowed mode, do I still give the user the option to go to windowed mode? If so, what would my app do, just change the window style so that the title bar and borders are displayed?[/quote]
Yes, you should ideally still allow for traditional windowed mode, as some people prefer it that way as well.
[quote]
Currently I am starting off with a WS_POPUP window. When the user hits 'W', I run the following code:


SetWindowLongPtr(g_hWnd, GWL_STYLE, WS_OVERLAPPED);
SetWindowPos(g_hWnd, HWND_TOP, curWindowPosX, curWindowPosY, windowedWidth, windowedHeight, SW_SHOW);

(curWindowPosX and curWindowPosY are both set to 50, and never changed. windowedWidth and windowedHeight are set to 640 and 480 respectively).

But it seems to have no effect. And if I click the window after running that code, it disappears. Any advice on how to switch to a true windowed mode from a fullscreen windowed mode?
[/quote]
Try something more like:
[code]#include <windows.h>
#include <atlbase.h>
#include <atlwin.h>

class MyWindow : public CWindowImpl<MyWindow, CWindow, CWinTraits<WS_POPUP, 0>>
{
public:
DECLARE_WND_CLASS_EX(NULL, CS_OWNDC | CS_HREDRAW | CS_VREDRAW, reinterpret_cast<HBRUSH>(BLACK_BRUSH));

MyWindow() {
auto desktop = ::GetDesktopWindow();
RECT bounds;
::GetWindowRect(desktop, &bounds);

Create(0, bounds, _T("COOKIES!"));
}

private:
BEGIN_MSG_MAP(MyWindow)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy);
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown);
END_MSG_MAP()


LRESULT OnKeyDown(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& result) {
if(wParam == VK_RETURN) {
RECT bounds = {50, 50, 800, 600};
LONG_PTR p = GetWindowLongPtr(GWL_STYLE);
if(!(p & WS_POPUP)) {
auto desktop = ::GetDesktopWindow();
::GetWindowRect(desktop, &bounds);
}
p ^= WS_OVERLAPPEDWINDOW;
p ^= WS_POPUP;
SetWindowLongPtr(GWL_STYLE, p);
SetWindowPos(0, bounds.left, bounds.top, bounds.right, bounds.bottom, SWP_NOZORDER | SWP_NOOWNERZORDER);
} else {
result = FALSE;
}
return 0;
}

LRESULT OnDestroy(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& result) {
PostQuitMessage(0);
return 0;
}
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int nCmdShow) {
MyWindow w;
w.ShowWindow(nCmdShow);
w.UpdateWindow();

MSG msg;
while(GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}[/code]

Which works fine for me. Edited by Washu

Share this post


Link to post
Share on other sites
Thanks for the code, Washu.

It took me hours to realize that I was using "WS_OVERLAPPED" where I should've used WS_OVERLAPPEDWINDOW. [img]http://public.gamedev.net//public/style_emoticons/default/ohmy.png[/img]

I will still take a look at your code, though. Looks like it has a nice, clean architecture.

Share this post


Link to post
Share on other sites
[quote name='codeToad' timestamp='1336617196' post='4938859']
Thanks for the code, Washu.

It took me hours to realize that I was using "WS_OVERLAPPED" where I should've used WS_OVERLAPPEDWINDOW. [img]http://public.gamedev.net//public/style_emoticons/default/ohmy.png[/img]

I will still take a look at your code, though. Looks like it has a nice, clean architecture.
[/quote]
It's more than that. You should not simply pass in WS_OVERLAPPED or WS_OVERLAPPEDWINDOW, as other window styles are often appended internally. This is why my code uses xor-assignment to add/remove the appropriate flags from the ACTUAL window style code. Edited by Washu

Share this post


Link to post
Share on other sites
Ok, I finally got my app working in the case of going to windowed mode, dragging the window to another monitor, and going fullscreen again. Thanks a ton for all your help, Washu.

But I do have one more question for you. Isn't there a big performance cost involved in doing "fullscreen windowed" mode? According to the DX documentation, rendering in windowed mode is done by a blit, but in fullscreen mode, rendering is done by a flip. (See [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx"]http://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx[/url], and do a search for "blit").

It seems like a heavy price to pay for a nicer alt-tab behavior.

BTW - I don't think the performance difference will be noticeable in my game, since it will be very simple. But I do want to use the best coding practices.

Share this post


Link to post
Share on other sites
In windows 7, targetting D3D10 and D3D11 the cost of rendering in fixed mode is probably fairly negligible. To give you an idea, I run SWTOR (and i ran the GW2 weekend beta event for pre-order customers) in Full Screen windowed mode, with max settings. I didn't notice much of a performance difference between them and fullscreen exclusive mode.

If you're targetting Windows XP/Direct3D9, then it is entirely possible that there is a significantly greater performance hit.

Share this post


Link to post
Share on other sites

This topic is 2041 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this