Print Screen/Fullscreen question

Started by
12 comments, last by TomKQT 13 years, 11 months ago
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: bigcheese.jpg 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;
}

Advertisement
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)
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 ;)

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:

bigcheese2.jpg

If it was capturing the current frame it would say "Full Screen: Yes" under Status, and the window/screen size would be the same.
Are you calling your SetFullScreen() function after Reset()ing the device?
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;}
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.
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.
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.
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.

This topic is closed to new replies.

Advertisement