Jump to content
  • Advertisement
Sign in to follow this  
ChristianPena

[MDX] C# - Change resolution at runtime

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

Hi, I created a Renderer class to wrap around the D3D Device class. I have pasted below two of the methods in that class, Initialize and UpdateDevice. Initialize checks that the adapter supports the modes that are necessary. It then calls UpdateDevice which creates the actual device. UpdateDevice will be called whenever settings are updated, such as the current resolution. I have some basic input handling which changes the resolution in the current PresentParameters and then calls UpdateDevice(). When I attempt to call UpdateDevice() after updating the resolution, the line where I create the Device throws an exception: D3DERR_DEVICELOST. I've done some reading on it and understand what the error means, but I do not understand why it is happening. I only get the error in Fullscreen mode. In windowed mode, the change of resolution is successful and the device is recreated. I am hoping that someone can spot what it is that I am doing wrong here. Any other comments on the code are welcome as well. Thanks in advance.
public bool Initialize()
{
	foreach (AdapterInformation ai in Manager.Adapters)
	{
		foreach (DisplayMode mode in ai.SupportedDisplayModes)
		{
			Debug.WriteLine(mode.Format.ToString() + " " +
				mode.Height.ToString() + " " + mode.Width.ToString());
		}
	}

	// Get the supported format: 16 or 32 bits
	Format fmt;
	if (!Manager.CheckDeviceType(Manager.Adapters.Default.Adapter, 
		DeviceType.Hardware, Format.X8R8G8B8, Format.X8R8G8B8, true))
	{
		if (!Manager.CheckDeviceType(Manager.Adapters.Default.Adapter, 
			DeviceType.Hardware, Format.X4R4G4B4, Format.X4R4G4B4, false))
		{
			// Cannot support 16 or 32 bit so quit
			return false;
		}
		else
		{
			fmt = Format.X4R4G4B4;
		}
	}
	else
	{
		fmt = Format.X8R8G8B8;
	}

	// Check that the 16 bit stencil buffer is there
	if (!Manager.CheckDeviceFormat(Manager.Adapters.Default.Adapter, 
		DeviceType.Hardware, fmt, Usage.DepthStencil, ResourceType.Surface, Format.D16))
	{
		return false;
	}

	// Get the device capabilities
	Caps caps = Manager.GetDeviceCaps(Manager.Adapters.Default.Adapter, 
		DeviceType.Hardware);

	// Check whther we have hardware and software processing
	if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
	{
		mCreateFlags = CreateFlags.HardwareVertexProcessing;
	}
	else
	{
		mCreateFlags = CreateFlags.SoftwareVertexProcessing;
	}

	// Create the present parameters
	mPresentParams.EnableAutoDepthStencil = true;
	mPresentParams.AutoDepthStencilFormat = DepthFormat.D16;
	mPresentParams.SwapEffect = SwapEffect.Discard;
	mPresentParams.BackBufferFormat = fmt;
	mPresentParams.PresentationInterval = PresentInterval.Default;

	// Create the device
	return UpdateDevice();
}

public bool UpdateDevice()
{
	// Initialized?
	if (mPresentParams == null || mForm == null)
	{
		return false;
	}

	// See if there were previous parameters. Need these if current
	// parameters fail
	PresentParameters prev = null;
	if (mDevice != null)
	{
		prev = mDevice.PresentationParameters;
		mDevice.DeviceLost -= new EventHandler(mDevice_DeviceLost);
		mDevice.DeviceReset -= new EventHandler(mDevice_DeviceReset);
		mDevice = null;
	}

	// Go through the display modes and find the matching one
	DisplayModeCollection modes = Manager.Adapters.Default.SupportedDisplayModes[mPresentParams.BackBufferFormat];

	bool modeFound = false;
	DisplayMode lastMode = new DisplayMode();
	foreach (DisplayMode mode in modes)
	{
		// Remember the last mode found
		lastMode = mode;
		if (mode.Width == mPresentParams.BackBufferWidth
			&& mode.Height == mPresentParams.BackBufferHeight)
		{
			modeFound = true;
		}
	}

	if (!modeFound)
	{
		if (prev != null)
		{
			// If no match found then go with the previous parameters
			mPresentParams = prev;
		}
		else
		{
			if (lastMode.Height != 0)
			{
				// If there is no match and no previous parameters then 
				// go with the last mode found if there was one...
				mPresentParams.BackBufferWidth = lastMode.Width;
				mPresentParams.BackBufferHeight = lastMode.Height;
			}
			else
			{
				// No dice...
				return false;
			}
		}
	}

	// Create the device
	mDevice = new Device(Manager.Adapters.Default.Adapter, DeviceType.Hardware, 
		mForm, mCreateFlags, mPresentParams);

	if (mDevice != null)
	{
		// If the device creation was successful then assign event handlers
		mDevice.DeviceLost += new EventHandler(mDevice_DeviceLost);
        mDevice.DeviceReset += new EventHandler(mDevice_DeviceReset);				

		return true;
	}
	else
	{
		return false;
	}
}

[Edited by - Muhammad Haggag on November 30, 2005 4:30:49 AM]

Share this post


Link to post
Share on other sites
Advertisement
When you create the device, you specify the backbuffer width and height and then create the device. When you want to reset the device using new present parameters you will get a device lost as the device really is lost and you will need to handle it appropriately. You can look at my article here or at the MSDN documentation here.
The basic pattern will be to recreate your present parameters and reset the device using the new present parameters.

I hope this helps.
Take care.

PS: please use the source tags described in the "Read this first before posting sticky" as you might get into trouble for not doing so.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!