Sign in to follow this  
majek

Print Screen/Fullscreen question

Recommended Posts

majek    115
Hello, I've just implemented a "toggle between windowed and fullscreen mode" option in my game, but I noticed something weird. When the app is in fullscreen mode and I hit the Print Screen key, the window appears to be in it's old location (before fullscreen mode was set). Here's an image to better explain: [img]http://img.majeks.com/files/2/bigcheese.jpg[/img] As you can see I'm setting the window position to (0, 0, ScreenWidth, ScreenHeight) so I don't know what could be causing this :(
bool Window::SetFullScreen(bool fullScreen)
{
	if (!p_Created) return false;
	p_FullScreen = fullScreen;
	
	if (p_FullScreen)
	{
		if (!p_Resolution->ChangeResolution(p_ClientWidth, p_ClientHeight)) return false;
	
		p_SavedClientLeft = p_ClientLeft;
		p_SavedClientTop = p_ClientTop;
		p_SavedClientWidth = p_ClientWidth;
		p_SavedClientHeight = p_ClientHeight;
	
		SetWindowLong(p_Handle, GWL_STYLE, WS_POPUP);
		SetWindowLong(p_Handle, GWL_EXSTYLE, NULL);
	
		p_Left = 0;
		p_Top = 0;
		p_ClientLeft = 0;
		p_ClientTop = 0;
		p_Width = p_Resolution->GetWidth();
		p_Height = p_Resolution->GetHeight();
		p_ClientWidth = p_Resolution->GetWidth();
		p_ClientHeight = p_Resolution->GetHeight();
	
		if (!SetWindowPos(p_Handle, HWND_TOPMOST, p_Left, p_Top, p_Width, p_Height, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW)) return false;
	}
	else
	{
		if (!p_Resolution->RestoreResolution()) return false;
	
		SetWindowLong(p_Handle, GWL_STYLE, p_Style);
		SetWindowLong(p_Handle, GWL_EXSTYLE, p_ExStyle);
	
		AdjustWindow(p_SavedClientLeft, p_SavedClientTop, p_SavedClientWidth, p_SavedClientHeight);
	
		if (!SetWindowPos(p_Handle, HWND_NOTOPMOST, p_Left, p_Top, p_Width, p_Height, SWP_FRAMECHANGED | SWP_SHOWWINDOW)) return false;
	}
	
	return true;
}

Share this post


Link to post
Share on other sites
szecs    2990
So it is just with print screen?
What happens, if you push alt+printscreen?
Does that phenomena always occur, or randomly?
Because I have a similar issue with printscreen: a frame is copied, that is long gone by the time I press printscreen. And I have no freaking idea where does that frame come from. Triple buffering isn't enabled (according to the driver), buffers are always swapped. It's a wonder.

So I can't help, but maybe both of us get the answer for this mystery. (or it's perfectly plausible, that I only misunderstood you, and my problem has nothing to do with yours)

Share this post


Link to post
Share on other sites
Tom KQT    1704
Quote:
Original post by majek
As you can see I'm setting the window position to (0, 0, ScreenWidth, ScreenHeight)

I think you're not as you've used the SWP_NOMOVE flag ;)

Share this post


Link to post
Share on other sites
majek    115
Yeah it sounds like we have the same issue szecs. I tried alt+print screen it's still the same :( I also tried removing SWP_NOMOVE, that seems to have fixed the window being captured in it's old position, but it's still capturing an old frame before fullscreen mode was set. Here's a new image:

[img]http://img.majeks.com/files/2/bigcheese2.jpg[/img]

If it was capturing the current frame it would say "Full Screen: Yes" under Status, and the window/screen size would be the same.

Share this post


Link to post
Share on other sites
majek    115
Before. First I change the resolution, then set the window to fullscreen, then reset the PresentParams and the device.

When the user hits the F key, my Direct3D class calls ToggleFullScreen(), which calls SetFullScreen() in my Window class, which calls ChangeResolution() in my Resolution class. Then I call the ResetDevices() function which resets the D3D device and my ID3DXFont objects.


if (g_Keyboard->IsKeyPressed(KEY_F))
{
if (!g_Direct3D->ToggleFullScreen()) return false;
if (!ResetDevices()) return false;
}

bool ResetDevices(void)
{
if (!g_HUD->BeforeReset()) return false;

if (!g_Direct3D->ResetDevice()) return false;

if (!g_HUD->AfterReset()) return false;

if (!g_Framerate->Reset()) return false;

return true;
}

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by majek
Before. First I change the resolution, then set the window to fullscreen, then reset the PresentParams and the device.
Try calling it after; D3D changes the window style when it toggles between exclusive (fullscreen) mode and back.

Share this post


Link to post
Share on other sites
szecs    2990
But I may misunderstood something.

He toggles, than he pushes printscreen after some time. Am I right? What does function order have to do with the issue? His window is probably redrawn several times until then. Where does that frame come from? What is that some mysterious 3rd buffer?

I have this issue, but double buffering works. But sometimes (at random for me) that mysterious buffer is copied to the clipboard, even if I push printscreen after 10 minutes of run time.

OP: do you have ATI card/driver?

EDIT: An other interesting addition:
If I run Warcraft III or any other games, then 3ds Max (openGL renderer), texture/GUI/whatever parts of the game appear in the viewports while loading. I can see the different cursors (ork hand, whatever). Maybe this has nothing to do with the issue, maybe it's just some non flushed memory.

Anyway, sehr interessant.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by szecs
He toggles, than he pushes printscreen after some time. Am I right? What does function order have to do with the issue? His window is probably redrawn several times until then. Where does that frame come from? What is that some mysterious 3rd buffer?
I understood it as the window frame is only visible in the screenshot, and not on the window. If that's the case, I'd assume that the printscreen code does "weird things" to get the image buffer which shows how the window really is.
If you change window style before Reset()ing the device, then D3D's Reset() call will change the window style again.

Quote:
Original post by szecs
EDIT: An other interesting addition:
If I run Warcraft III or any other games, then 3ds Max (openGL renderer), texture/GUI/whatever parts of the game appear in the viewports while loading. I can see the different cursors (ork hand, whatever). Maybe this has nothing to do with the issue, maybe it's just some non flushed memory.

Anyway, sehr interessant.
Strange, sounds to me like the memory is just out of date as you suggest. If Max used D3D, I'd say to use the debug runtimes and I bet the viewports would be green or magenta, but as far as I know there's no debug runtime alternative for OpenGL.

Share this post


Link to post
Share on other sites
majek    115
Thanks Steve you were right, it was changing the window style when I reset the device. is there anything you dont know? :)

Here is my new dilema... My Direct3D class stores a bool p_FullScreen. When ToggleFullScreen() is called its really just calling SetFullScreen(!p_FullScreen)

bool Direct3D::SetFullScreen(bool fullScreen)
{
if (!p_Created) return false;

p_FullScreen = fullScreen;
if (!p_Window->SetFullScreen(p_FullScreen)) return false;

return true;
}




The BeforeResetDevice() function depends on p_FullScreen to reset the PresentParams, so if I reset the device before toggling fullscreen mode, p_FullScreen will be FALSE, returning the wrong result.

bool Direct3D::BeforeResetDevice(void)
{
if (FAILED(p_Object->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &p_DisplayMode))) return false;

p_PresentParams.AutoDepthStencilFormat = D3DFMT_D16;
p_PresentParams.BackBufferCount = 1;
p_PresentParams.BackBufferFormat = p_DisplayMode.Format;
p_PresentParams.EnableAutoDepthStencil = TRUE;
p_PresentParams.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
p_PresentParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
p_PresentParams.hDeviceWindow = p_Window->GetHandle();
p_PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

if (p_FullScreen)
{
p_PresentParams.BackBufferWidth = p_Resolution->GetWidth();
p_PresentParams.BackBufferHeight = p_Resolution->GetHeight();
p_PresentParams.Windowed = FALSE;
}
else
{
p_PresentParams.BackBufferWidth = 0;
p_PresentParams.BackBufferHeight = 0;
p_PresentParams.Windowed = TRUE;
}

return true;
}




My next question for Steve is... Should I just get rid of the Window::SetFullScreen() function? Since D3D changes the window style for me there's really no point in changing it manually.

@szecs- I have a Geforce GTX 260. I Think there is some mysterious 3rd buffer, but only when D3D is in exclusive mode. The Problem seems to dissapear when I don't use p_PresentParams.Windowed = FALSE.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by majek
Thanks Steve you were right, it was changing the window style when I reset the device. is there anything you dont know? :)

Here is my new dilema... My Direct3D class stores a bool p_FullScreen. When ToggleFullScreen() is called its really just calling SetFullScreen(!p_FullScreen)

The BeforeResetDevice() function depends on p_FullScreen to reset the PresentParams, so if I reset the device before toggling fullscreen mode, p_FullScreen will be FALSE, returning the wrong result.
Why not pass a parameter to BeforeResetDevice() to indicate if it's going into fullscreen mode or not? Then your p_FullScreen variable can mean "Is the app currently in fullscreen mode?", and this'll allow you to use BeforeResetDevice() to reset the device without toggling fullscreen mode (E.g. to change resolution).

Quote:
Original post by majek
My next question for Steve is... Should I just get rid of the Window::SetFullScreen() function? Since D3D changes the window style for me there's really no point in changing it manually.
It's probably a good idea to change it - AFAIK D3D doesn't change the window style back when going windowed -> fullscreen -> windowed, so you end up with a WS_POPUP style window if you don't change the window style. And it doesn't hurt to make your code symmetrical so the window style is set when going to fullscreen mode too.

Share this post


Link to post
Share on other sites
majek    115
Ok, thanks for all the help! All the more reason to keep learning D3D10/11 Lol

I'm actually converting an opengl app to d3d9, I don't know why though :(

Share this post


Link to post
Share on other sites
Tom KQT    1704
Quote:
Original post by Evil SteveIt's probably a good idea to change it - AFAIK D3D doesn't change the window style back when going windowed -> fullscreen -> windowed, so you end up with a WS_POPUP style window if you don't change the window style. And it doesn't hurt to make your code symmetrical so the window style is set when going to fullscreen mode too.


Also, from my experience, there's a problem when going from windowed to fullscreen if you don't set WS_POPUP in Windows XP where windows by default have rounded top corners - everything looks fine in fullscreen and the whole screen is covered, but when you click the top corners (where the rounding would be), you deactivate your window because Windows thinks you clicked outside of it.

Share this post


Link to post
Share on other sites

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