Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualDbowler92

Posted 09 September 2012 - 05:27 AM


Hi I'll try to answer your question


I have read that I need to change the D3DPRESENT PARAMS and call Reset() via the Direct3D Device object... But this blew up my game and im not sure why.


That's true you have to call Reset(), but you have to keep some things in mind. Take a look at my enableFullScreen() function:
[source lang="cpp"]void D3DApp::enableFullScreenMode(){// Are we already in fullscreen mode?if( !md3dPP.Windowed ) return;int width = GetSystemMetrics(SM_CXSCREEN);int height = GetSystemMetrics(SM_CYSCREEN);md3dPP.BackBufferFormat = D3DFMT_X8R8G8B8;md3dPP.BackBufferWidth = width;md3dPP.BackBufferHeight = height;md3dPP.Windowed = false;// Reset the device with the changes.onLostDevice();HR(gd3dDevice->Reset(&md3dPP));onResetDevice();}[/source]
md3dPP is a D3DPRESENT_PARAMETERS (like the one you use to create the device).
Notice that before calling device->Reset() I call a method named onLostDevice() and after calling device->Reset() I call onResetDevice().
What onLostDevice() does is to prepare all your game assets (textures, meshes, etc) for a device resetting, for instance, any D3DAsset has to placed in what is called a memory pool, let's say you create a texture and you specify you're going to use de D3DPOOL_DEFAULT, in that case, objects placed in that pool need to be destroyed before calling device->Reset() and reinitialized after that. Some other objects like dynamic renderTargets need to be destroyed too. I suppose that's why you're game is crashing when you call Reset(), because you're not taking this into account. (In the previous example you can place your texture in the D3DPOOL_MANAGED so that you don't have to destroy the texture)

How do you guys handle rendering? For example, say my window is of size 1024 by 768. Lets say I render my Texture (with the transformation matrix) at point 1024, 768 (centred) - This obviously renders right at the bottom right of the screen... but lets say the user changes the resolution settings to 1920 by 1080. That image is no longer rendered at the bottom right of the screen


That's true, for 2D objects you have to take into account the window size when you're rendering them, so if you were drawing your texture like this:
texture->Draw(0,0,1024,768)
Now you have to draw like this:
texture->Draw(0,0,1920,1080)

(The same goes with other 2D objects like plain Text)

For 3D objects you don't have to worry, the only thing you have to know is that when you change to a higher resolution you're going to see more things of your scene, i.e, your field of view is going to change to a bigger one (usually you specify a vertical field of view, so It's the horizontal field of view that changes).


Hi,

Many thanks for the detailed response Posted Image

As you guessed, I had failed to release my game assets and that was causing the crash. I have, however, updraded my Texture2D and Surface2D classes so that they are all created in the MANAGED pool.

That has stopped the crashing - which is good, but right now when I press Alt+Tab, I end up with a white box that represents my drawing area. :/

[source lang="cpp"]void ChangeScreenMode(HWND window){ OutputDebugStringW(L"ChangeScreenmode\n"); if (isInWindowedMode) { OutputDebugStringW(L"To FS\n"); //Change to FS spriteHandler->OnLostDevice(); d3dpp.Windowed = FALSE; HRESULT hResult = d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_POPUPWINDOW); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = false; spriteHandler->OnResetDevice(); } else { OutputDebugStringW(L"To Windowed\n"); //Change to Windowed spriteHandler->OnLostDevice(); d3dpp.Windowed = TRUE; d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, SCREENW, SCREENH, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = true; spriteHandler->OnResetDevice(); }}[/source]

This is the current function...

First things first - It should be noted that this function is ugly... ive yet to clear it up. Persoanlly, I prefer things to work before I make them look good/optimized. Second, the SetWindowsLong & Pos functions... I copied and pasted from google and as a result, far from finished.

Any idea why my beutiful black Direct3D window is replaced by an ugly white box??


Turns out that I had lost the back buffer Posted Image

So the solution is like this - Again, not a clean bit of code

[source lang="cpp"]void ChangeScreenMode(HWND window){ OutputDebugStringW(L"ChangeScreenmode\n"); backbuffer->Release(); if (isInWindowedMode) { OutputDebugStringW(L"To FS\n"); //Change to FS spriteHandler->OnLostDevice(); d3dpp.Windowed = FALSE; HRESULT hResult = d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, SCREENW, SCREENH, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = false; spriteHandler->OnResetDevice(); } else { OutputDebugStringW(L"To Windowed\n"); //Change to Windowed spriteHandler->OnLostDevice(); d3dpp.Windowed = TRUE; d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, SCREENW, SCREENH, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = true; spriteHandler->OnResetDevice(); } d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); completedTransition = true;}[/source]

One last question regarding full screen mode...

My Textures and such render perfectly happily in Windowed mode - yet in full screen mode, they dont render at all... :S Any ideas?? (The same applies even if I start the game in full screen mode and then Alt+Enter to windowed mode where the textures appear again)

#1Dbowler92

Posted 09 September 2012 - 05:15 AM


Hi I'll try to answer your question


I have read that I need to change the D3DPRESENT PARAMS and call Reset() via the Direct3D Device object... But this blew up my game and im not sure why.


That's true you have to call Reset(), but you have to keep some things in mind. Take a look at my enableFullScreen() function:
[source lang="cpp"]void D3DApp::enableFullScreenMode(){// Are we already in fullscreen mode?if( !md3dPP.Windowed ) return;int width = GetSystemMetrics(SM_CXSCREEN);int height = GetSystemMetrics(SM_CYSCREEN);md3dPP.BackBufferFormat = D3DFMT_X8R8G8B8;md3dPP.BackBufferWidth = width;md3dPP.BackBufferHeight = height;md3dPP.Windowed = false;// Reset the device with the changes.onLostDevice();HR(gd3dDevice->Reset(&md3dPP));onResetDevice();}[/source]
md3dPP is a D3DPRESENT_PARAMETERS (like the one you use to create the device).
Notice that before calling device->Reset() I call a method named onLostDevice() and after calling device->Reset() I call onResetDevice().
What onLostDevice() does is to prepare all your game assets (textures, meshes, etc) for a device resetting, for instance, any D3DAsset has to placed in what is called a memory pool, let's say you create a texture and you specify you're going to use de D3DPOOL_DEFAULT, in that case, objects placed in that pool need to be destroyed before calling device->Reset() and reinitialized after that. Some other objects like dynamic renderTargets need to be destroyed too. I suppose that's why you're game is crashing when you call Reset(), because you're not taking this into account. (In the previous example you can place your texture in the D3DPOOL_MANAGED so that you don't have to destroy the texture)

How do you guys handle rendering? For example, say my window is of size 1024 by 768. Lets say I render my Texture (with the transformation matrix) at point 1024, 768 (centred) - This obviously renders right at the bottom right of the screen... but lets say the user changes the resolution settings to 1920 by 1080. That image is no longer rendered at the bottom right of the screen


That's true, for 2D objects you have to take into account the window size when you're rendering them, so if you were drawing your texture like this:
texture->Draw(0,0,1024,768)
Now you have to draw like this:
texture->Draw(0,0,1920,1080)

(The same goes with other 2D objects like plain Text)

For 3D objects you don't have to worry, the only thing you have to know is that when you change to a higher resolution you're going to see more things of your scene, i.e, your field of view is going to change to a bigger one (usually you specify a vertical field of view, so It's the horizontal field of view that changes).


Hi,

Many thanks for the detailed response Posted Image

As you guessed, I had failed to release my game assets and that was causing the crash. I have, however, updraded my Texture2D and Surface2D classes so that they are all created in the MANAGED pool.

That has stopped the crashing - which is good, but right now when I press Alt+Tab, I end up with a white box that represents my drawing area. :/

[source lang="cpp"]void ChangeScreenMode(HWND window){ OutputDebugStringW(L"ChangeScreenmode\n"); if (isInWindowedMode) { OutputDebugStringW(L"To FS\n"); //Change to FS spriteHandler->OnLostDevice(); d3dpp.Windowed = FALSE; HRESULT hResult = d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_POPUPWINDOW); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = false; spriteHandler->OnResetDevice(); } else { OutputDebugStringW(L"To Windowed\n"); //Change to Windowed spriteHandler->OnLostDevice(); d3dpp.Windowed = TRUE; d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, SCREENW, SCREENH, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = true; spriteHandler->OnResetDevice(); }}[/source]

This is the current function...

First things first - It should be noted that this function is ugly... ive yet to clear it up. Persoanlly, I prefer things to work before I make them look good/optimized. Second, the SetWindowsLong & Pos functions... I copied and pasted from google and as a result, far from finished.

Any idea why my beutiful black Direct3D window is replaced by an ugly white box??


Turns out that I had lost the back buffer :)

So the solution is like this - Again, not a clean bit of code

[source lang="cpp"]void ChangeScreenMode(HWND window){ OutputDebugStringW(L"ChangeScreenmode\n"); backbuffer->Release(); if (isInWindowedMode) { OutputDebugStringW(L"To FS\n"); //Change to FS spriteHandler->OnLostDevice(); d3dpp.Windowed = FALSE; HRESULT hResult = d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, SCREENW, SCREENH, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = false; spriteHandler->OnResetDevice(); } else { OutputDebugStringW(L"To Windowed\n"); //Change to Windowed spriteHandler->OnLostDevice(); d3dpp.Windowed = TRUE; d3ddev->Reset(&d3dpp); SetWindowLong(d3dpp.hDeviceWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW); SetWindowPos(d3dpp.hDeviceWindow, HWND_TOP, 0, 0, SCREENW, SCREENH, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); isInWindowedMode = true; spriteHandler->OnResetDevice(); } d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); completedTransition = true;}[/source]

One last question regarding full screen mode...

My Textures and such render perfectly happily in Windowed mode - yet in full screen mode, they dont render at all... :S Any ideas??

PARTNERS