Jump to content
  • Advertisement
Sign in to follow this  
Nypyren

Managed DirectX - Changing Resolution

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

Semi-n00b question here: I'd like to change the fullscreen resolution in my game. What's the minimum required procedure for this? A complete device shutdown/recreate? Calling Device.Reset with new PresentParameters doesn't work. Also, I've got Textures, Meshes, Effects, VertexBuffers and IndexBuffers that were created using the current Device. If I have to recreate a Device to switch resolution, do I have to recreate *all* of these? If I have to recreate everything, is there a common pattern used to keep track of what is currently loaded, or do you just make a wrapper class for each Texture, Mesh, Effect, etc, with a Recreate function or something? Also, does anyone know of a non-book Managed DirectX How-To/FAQ/Bible that would answer other questions similar to this? The book I have is actually out of date on a lot of things as of the August SDK. Weird, but true. [Edit] The book I have is the "Managed DirectX Kick Start" one that's pretty much the best I've seen so far. [Edited by - Nypyren on August 23, 2005 11:11:57 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Nypyren
I'd like to change the fullscreen resolution in my game. What's the minimum required procedure for this? A complete device shutdown/recreate? Calling Device.Reset with new PresentParameters doesn't work.

Changing the presentation params will effectively change both the resolution and the windowed state. Check the caps viewer for the resolutions, backbuffer formats, and refresh rates that your card supports.

Quote:
Also, I've got Textures, Meshes, Effects, VertexBuffers and IndexBuffers that were created using the current Device. If I have to recreate a Device to switch resolution, do I have to recreate *all* of these?

If you completely destroy a device, all resources are invalid as well. However, if you reset a device, only the default pool resources have to be released.

Quote:
If I have to recreate everything, is there a common pattern used to keep track of what is currently loaded, or do you just make a wrapper class for each Texture, Mesh, Effect, etc, with a Recreate function or something?

Yea, that is a common solution. To reset, there are generally two required functions:

OnDeviceLoss() to release the resource before the device reset
OnDeviceReset() to recreate the resource after the device reset

Share this post


Link to post
Share on other sites
Hiya Nypyren,
How are you doing?

The Problem
Switching resolutions in your game. i.e. from 800x600 to 1024x768

The Solution
When switching resolutions you need to tell direct3d that you are switching the resolutions.

This is normally accomplished by restating in the presentation parameters that your back buffer's (color buffer's) width and height is changing. So the general pattern is followed.

1) Set the Back Buffer's width and height
2) Reset the device and give it the newly generated presentation parameters.

When doing graphics programming I try and think about it logically...
Your device needs to know that you want to change the resolution, in this case you need to reset the device and provide it the presentation parameters.

With regards to the recreation of your objects, What I normally do is have a manager recreating those resources. So the manager will call a reset method on my objects that will recreate them. "Not the best practise though"


I hope this helps buddy :)
Take care.

Share this post


Link to post
Share on other sites

public void ChangePresentation(int adapter, Size resolution, Format backformat, DepthFormat depthformat, bool windowed)
{
pparams.AutoDepthStencilFormat = depthformat;
pparams.BackBufferCount = 0;
pparams.BackBufferFormat = backformat;
pparams.BackBufferWidth = resolution.Width;
pparams.BackBufferHeight = resolution.Height;
pparams.DeviceWindow = control;
pparams.DeviceWindowHandle = control.Handle;
pparams.EnableAutoDepthStencil = true;
pparams.ForceNoMultiThreadedFlag = false;
pparams.FullScreenRefreshRateInHz = 60;
pparams.MultiSample = MultiSampleType.None;
pparams.MultiSampleQuality = 0;
pparams.PresentationInterval = PresentInterval.Immediate;
pparams.PresentFlag = PresentFlag.None;
pparams.SwapEffect = SwapEffect.Discard;
pparams.Windowed = windowed;

device.Reset(pparams);
}








The line with Reset throws the amazingly unhelpful InvalidCallException with the message "Error in application" (apparently it's the same as D3DERR_INVALIDCALL). I'm attempting a simple 1024x768 @ X8R8G8B8 -> 800x600 @ X8R8G8B8 fullscreen switch.

Device.Reset documentation:

"A call to Device.Reset fails if made on a different thread than the one used to create the device being reset."

I perform the call on the same thread as I initially created the device.

"Exceptions: InvalidCallException: The method call is invalid. For example, a method's parameter might contain an invalid value."

I've manually set every single parameter to what I presume are proper values.

The system is not rendering anything (i.e. in a BeginScene/EndScene block or doing any other DirectX calls on other threads). There is only one thread active.

[Edit]

I guess the function throws an exception, but it actually works. If I just eat the exception and let my BeginRender function deal with it like a task-swap-in (which does all of the CheckCooperativeLevel and Reset mumbo jumbo) then it works. Except the HLSL Effects still don't function after a reset. WEAK.

Docs: "Pixel shaders and vertex shaders survive Device.Reset calls for DirectX 9.0. They do not need to be re-created explicitly by the application."

I do get both the Effect.Lost and Effect.Reset events when I reset the device.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nypyren
The line with Reset throws the amazingly unhelpful InvalidCallException with the message "Error in application" (apparently it's the same as D3DERR_INVALIDCALL).

D3D APIs generally do not return detailed error codes, otherwise we would have thousands of HRESULTs and exception types. It is left up to you to fire up the debugger and check out the debug output. This will tell you exactly why the function failed.

Quote:

I guess the function throws an exception, but it actually works. If I just eat the exception and let my BeginRender function deal with it like a task-swap-in (which does all of the CheckCooperativeLevel and Reset mumbo jumbo) then it works. Except the HLSL Effects still don't function after a reset. WEAK.

Of course it doesn't work - the point of the exception was to tell you that the function call failed. You shouldn't continue like it was successful. I'm surprised it works at all after that point.

Share this post


Link to post
Share on other sites
Might have been helpful if VS2005's debugging window actually displayed the same info that DebugView picks up.

"Direct3D9: (ERROR) :All user created stateblocks must be freed before Reset can succeed. Reset Fails."

Jackpot. So I tell my EffectManager to call Effect.OnLostDevice on all effects before I call Device.Reset, then I call Effect.OnResetDevice on all effects afterward. Had to do this in my BeginRender/EndRender stuff as well.

The weird part is that when I called Device.Reset without explicitly calling Effect.OnLostDevice and Effect.OnResetDevice, I got the Effect.Lost and Effect.Reset event handlers firing.


I have to make sure that the device isn't already lost when I try to reset it (I had a frame-counter switching the resolution for testing purposes), but other than that I can switch resolutions now.


Thanks, everyone. I was wondering how to get the debugging messages - good thing I checked your FAQ link.

[Edited by - Nypyren on August 24, 2005 9:35:29 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!