Jump to content

  • Log In with Google      Sign In   
  • Create Account


Resolution ( full screen vs windowed )


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 riuthamus   Crossbones+   -  Reputation: 4483

Like
0Likes
Like

Posted 01 November 2012 - 12:33 PM

So, we have been programming the ability to setup different resolutions and such. Our issue now is with the UI and screenlocking. When the game is first started we open it up in a 1280x720 ( windowed ) client. You can change this via the in game options menu but when you change it to fullscreen the UI does some silly things.

1) The ui becomes offset and to be able to interact with the UI elements you need to move the mouse to some odd place.
2) We have tried changing the type to stretch, to centered, to whatever and it seems to give the same effect
3) Normally, when you put any program into a FULLSCREEN mode your mouse is unable to leave it, but with our game... it can... why?

Any and all suggestions are welcome. If you need a picture to better explain this let me know and I will provide that as well. If you need some backstory on how we are doing the system let me know that as well. Thanks in advance.

Sponsor:

#2 NEXUSKill   Members   -  Reputation: 453

Like
1Likes
Like

Posted 01 November 2012 - 12:55 PM

Are you using any particular engine? sounds like only the visuals are being affected by the resize, you need to either update the UI hit areas or scale the mouse position to a standard resolution before checking collisions.

There are different ways a UI can adapt to stretching and they are all useful in their own cases, such as:
Remain unchanged, no scale or position alteration.
Maintain position relative to an anchor, a screen corner, center or side.
Fully scale with screen.
Probably others I'm not thinking of.
Game making is godlike

LinkedIn profile: http://ar.linkedin.com/pub/andres-ricardo-chamarra/2a/28a/272



#3 slayemin   Members   -  Reputation: 2147

Like
5Likes
Like

Posted 01 November 2012 - 12:59 PM

I've experienced the mouse problem. What I do is place a graphic on the screen which represents the mouse cursor. Then, I update the mouse cursor position based off of the change in the mouse position relative to the last frame. I think there's even a function which will give you the dx, dy for mouse. Then, all you have to do is make sure that the mouse cursor is constrained to the screen dimensions. The part you're going to have to decide on is how you're going to handle the right edge of the screen -- do you let the mouse hot spot move all the way to the edge of the screen and clip a part of the graphic, or do you always display the entire cursor icon? What if you have a GUI element, like a scroll bar, on the far edge of the screen?

As for the UI offsets, it sounds like you're not finding the edges of the client rect correctly. You're going to have to step into the debugger to see exactly what's happening with your GUI element positioning.

Eric Nevala

Indie Developer | Dev blog


#4 DpakoH   Members   -  Reputation: 927

Like
3Likes
Like

Posted 01 November 2012 - 01:16 PM

check this out, it is for xna, but the idea is important, maybe you can use it.

#5 Telanor   Members   -  Reputation: 1295

Like
0Likes
Like

Posted 01 November 2012 - 03:58 PM

The problem seems to be that directx is completely ignoring the resize and just staying with the original resolution. According to my monitor, its running in 1280x720 when in fullscreen, despite having been set to 1920x1080. This is the code that I'm using:

public static void ApplySettings()
{
	swapChain.SetFullscreenState(Settings.WindowMode == GameSettings.WindowModeSetting.Fullscreen, null);

	if(Settings.WindowMode != GameSettings.WindowModeSetting.Fullscreen)
		Form.ClientSize = new Size(Settings.DisplayMode.Width, Settings.DisplayMode.Height);
	
	Resize(Settings.DisplayMode.Width, Settings.DisplayMode.Height);
}

private static void Resize(int width, int height)
{
	BackBuffer.Dispose();
	LinearBackBuffer.Dispose();

	swapChain.ResizeBuffers(0, width, height, Format.Unknown, SwapChainFlags.AllowModeSwitch);
	Viewport = new Viewport(0, 0, width, height);
	Console.WriteLine("Viewport size: {0}x{1}", Viewport.Width, Viewport.Height);

	using(var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
	{
		BackBuffer = new RenderTargetView(device, resource);

		LinearBackBuffer = new RenderTargetView(device, resource, new RenderTargetViewDescription
		{
			Dimension = RenderTargetViewDimension.Texture2D,
			Format = Format.R8G8B8A8_UNorm
		});
	}

	if(OnResize != null)
		OnResize();
}


#6 Aeramor   Members   -  Reputation: 1079

Like
1Likes
Like

Posted 01 November 2012 - 04:56 PM

I hope you're not using an absolute scale for your mouse coordinates. That would make me a sad panda :( Arbitrary scale from 0-1(float) is practically mandatory.
On the resize issue particularly, you may be attempting to switch to a mode your monitor does not support. Before hard coding values for it to switch to make sure to get the list of available resolutions (and keep in mind just because it supports a resolution does not mean it supports your format/refresh rate). Also, add error checkers around all of this code.
As another aside, do NOT name your member variables as the same spelling (and capitalization) of your class names... Viewport, for example, is never explicitly used in your above code (except to print the size) and if this had been a clip instead of a full function I wouldn't have been able to tell if it was a local or member variable. :( And oh god no.. OnResize/OnResize()... that's just.. painful.

-Aeramor

CTO at Conjecture, Inc.


#7 Telanor   Members   -  Reputation: 1295

Like
0Likes
Like

Posted 01 November 2012 - 05:50 PM

We're not using absolute scale, but we decided not to use floats/percents since it makes a bit of a pain when designing the UI. The UI actually uses 1280x720 as its baseline. It scales itself according to the actual resolution.

As for the resolution being set, its not hard coded, I enumerated the list provided by Output.GetDisplayModeList. And its not like I'm requesting any weird setting. 1920x1080@60Hz is certainly supported by my monitor. And I should certainly hope the R8G8B8A8_UNorm_SRGB format is supported.

For error checking, I don't see where I can add any, this is C#/SharpDX. Unlike C++, ResizeBuffers has no return value. I imagine if it fails, it would inform me via an exception, which it hasn't.

The variable naming... well that's pretty much C# standard convention. I hate the _ or m prefixes, it just makes things harder to read. Visual Studio shows plain as day whats a variable and whats a type. Though I suppose I do have the convention on the event handler backwards

#8 Mike.Popoloski   Crossbones+   -  Reputation: 2868

Like
3Likes
Like

Posted 01 November 2012 - 07:28 PM

Make sure you're passing the AllowModeSwitch flag in your swap chain description. Without it, DXGI will simply use the desktop resolution.

EDIT:

Nevermind, I just noticed you're passing this to ResizeBuffers already, which is correct. However, it looks like you only set the client size of the window when in windowed mode. I'm pretty sure it's necessary that you also set the size of the window when in fullscreen mode. ResizeBuffers will only resize your backbuffer; it's probably get squashed back down to fit on the form surface.

Edited by Mike.Popoloski, 01 November 2012 - 07:33 PM.

Mike Popoloski | Journal | SlimDX

#9 Telanor   Members   -  Reputation: 1295

Like
0Likes
Like

Posted 01 November 2012 - 10:53 PM

I tried setting the client size in fullscreen mode as well, still comes out the same.

#10 Endurion   Crossbones+   -  Reputation: 3390

Like
1Likes
Like

Posted 01 November 2012 - 11:47 PM

Do you also resize the main window and change your main window styles to have no border when switching to full screen?
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#11 Telanor   Members   -  Reputation: 1295

Like
0Likes
Like

Posted 02 November 2012 - 12:53 AM

The code you see is all that's being run for resizing. The only window I have that I can resize is the RenderForm, which, as suggested, I tried resizing to no effect. Wouldn't removing the border only be for borderless fullscreen mode?

#12 Gavin Williams   Members   -  Reputation: 646

Like
2Likes
Like

Posted 02 November 2012 - 09:17 AM

1) The ui becomes offset and to be able to interact with the UI elements you need to move the mouse to some odd place.


The ui becoming offset could suggest that your viewport is wrong. So just for safety you could set the viewport straight after you change its size ..

Device11.ImmediateContext.Rasterizer.SetViewports(viewport);

But when you say that you need to move the mouse to some odd place. hmmm.. Can you put up some screenshots of that ? Is the place where you have to click where you would expect the element to be if it were being rendered in the correct place ? That might suggest that you ui code is wrong, either rendering or hit detection, but maybe not as well.

3) Normally, when you put any program into a FULLSCREEN mode your mouse is unable to leave it, but with our game... it can... why?


I can move my mouse to the second display when i switch to fullscreen mode, so I would say that it's normal behaviour. I used to know how to handle that issue with XNA, but I haven't yet worked it out with SlimDX. I think how I did it in XNA was actually just monitor the mouse position and limit it to the window bounds with a setmouseposition() function. I'll look into this for both of us.

However, it looks like you only set the client size of the window when in windowed mode. I'm pretty sure it's necessary that you also set the size of the window when in fullscreen mode. ResizeBuffers will only resize your backbuffer; it's probably get squashed back down to fit on the form surface.


I don't set the window position in fullscreen mode, and I'm pretty sure it works properly. Edit - checked this, and because I'm using SwapChainFlags.None it just adopts the desktop resolution. Just learnt something about resizing the 'front buffer' ... I tried setting the form manually, but that just won't work, it can and will ignore the width height values you pass in. Instead, use
swapChain.ResizeTargets()
Which will also resize your window, and fire a Resize event, so that your backbuffers can adjust.

Edited by Gavin Williams, 02 November 2012 - 10:19 AM.


#13 shadowomf   Members   -  Reputation: 315

Like
2Likes
Like

Posted 02 November 2012 - 10:29 AM

Even though not direcly an answer to your question maybe a tip:

Don't expect the user to know:
- that it's possible to switch to fullscreen
- that he can change the resolution of your application or know what changing the resolution will do
- what resolution is optimal for his/her computer

You won't belive how often I'm at some computer where the resolution is not selected correctly. Most of the time users don't use the native resolution of their display. Most of the time they don't even know what the native resolution is or how to change the desktop resolution. Sometimes someone else did set up their computer and choose thecorrect resolution, but how would they know what to select in your game?

If you're targeting causual users, just start your application in fullscreen mode with the current desktop resolution. This will work fine most of the time.
Of course it's allways good to provide a resolution as well as a windowed/fullscreen option.

Best luck with your project.

#14 Telanor   Members   -  Reputation: 1295

Like
1Likes
Like

Posted 02 November 2012 - 07:18 PM

I don't set the window position in fullscreen mode, and I'm pretty sure it works properly. Edit - checked this, and because I'm using SwapChainFlags.None it just adopts the desktop resolution. Just learnt something about resizing the 'front buffer' ... I tried setting the form manually, but that just won't work, it can and will ignore the width height values you pass in. Instead, use

swapChain.ResizeTargets()

Which will also resize your window, and fire a Resize event, so that your backbuffers can adjust.


Well, I'm not sure if you were saying to do this or not, but I tried calling ResizeTarget and letting that in turn call my Resize method. So both ResizeTarget and ResizeBuffers end up being called. My monitor is now properly reporting 1920x1080 as the resolution and the mouse positioning is working correctly. No where have I seen any examples or documentation that stated BOTH of these needed to be called.

This is what worked for me in the end:

public static void ApplySettings()
{
	swapChain.SetFullscreenState(Settings.WindowMode == GameSettings.WindowModeSetting.Fullscreen, null);

	if(Settings.WindowMode != GameSettings.WindowModeSetting.Fullscreen)
	{
		Form.ClientSize = new Size(Settings.DisplayMode.Width, Settings.DisplayMode.Height);
		Resize(Settings.DisplayMode.Width, Settings.DisplayMode.Height);
	}
	else
	{
		var mode = Settings.DisplayMode;
		swapChain.ResizeTarget(ref mode);
	}
}

private static void Resize(int width, int height)
{
	BackBuffer.Dispose();
	LinearBackBuffer.Dispose();

	swapChain.ResizeBuffers(0, width, height, Format.Unknown, SwapChainFlags.AllowModeSwitch);
	Viewport = new Viewport(0, 0, width, height);
	Console.WriteLine("Viewport size: {0}x{1}", Viewport.Width, Viewport.Height);

	using(var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
	{
		BackBuffer = new RenderTargetView(device, resource);
		
		LinearBackBuffer = new RenderTargetView(device, resource, new RenderTargetViewDescription
		{
			Dimension = RenderTargetViewDimension.Texture2D,
			Format = Format.R8G8B8A8_UNorm
		});
	}

	if(OnResize != null)
		OnResize();
}

Edited by Telanor, 02 November 2012 - 07:20 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS