bool CanDeviceBeReset(DeviceSettings oldSettings, DeviceSettings newSettings) { if (oldSettings == null || oldSettings.DeviceVersion != newSettings.DeviceVersion) { return(false); } return(Direct3D10.Device != null && oldSettings.Direct3D10.AdapterOrdinal == newSettings.Direct3D10.AdapterOrdinal && oldSettings.Direct3D10.DriverType == newSettings.Direct3D10.DriverType && oldSettings.Direct3D10.CreationFlags == newSettings.Direct3D10.CreationFlags && oldSettings.Direct3D10.SwapChainDescription.SampleDescription.Count == newSettings.Direct3D10.SwapChainDescription.SampleDescription.Count && oldSettings.Direct3D10.SwapChainDescription.SampleDescription.Quality == newSettings.Direct3D10.SwapChainDescription.SampleDescription.Quality); }
/// <summary> /// Changes the device. /// </summary> /// <param name="settings">The settings.</param> /// <param name="minimumSettings">The minimum settings.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="settings"/> is <c>null</c>.</exception> /// <exception cref="NoCompatibleDevicesException">Thrown when the framework cannot find a suitable graphics device.</exception> /// <exception cref="DeviceCreationException">Thrown when device creation fails.</exception> public void ChangeDevice(DeviceSettings settings, DeviceSettings minimumSettings) { if (settings == null) { throw new ArgumentNullException("settings"); } Enumeration10.MinimumSettings = minimumSettings; DeviceSettings validSettings = DeviceSettings.FindValidSettings(settings); SwapChainDescription scd = validSettings.Direct3D10.SwapChainDescription; scd.OutputHandle = game.Window.Handle; validSettings.Direct3D10.SwapChainDescription = scd; CreateDevice(validSettings); }
void Window_UserResized(object sender, EventArgs e) { if (ignoreSizeChanges || !EnsureDevice() || (CurrentSettings.DeviceVersion == DeviceVersion.Direct3D9 && !IsWindowed)) { return; } DeviceSettings newSettings = CurrentSettings.Clone(); bool fullscreen; Output output; Direct3D10.SwapChain.GetFullScreenState(out fullscreen, out output); ResizeDXGIBuffers(0, 0, fullscreen); game.Window.Show(); }
/// <summary> /// Toggles between full screen and windowed mode. /// </summary> /// <exception cref="InvalidOperationException">Thrown when no valid device has been created.</exception> /// <exception cref="NoCompatibleDevicesException">Thrown when the framework cannot find a suitable graphics device.</exception> /// <exception cref="DeviceCreationException">Thrown when device creation fails.</exception> public void ToggleFullScreen() { if (!EnsureDevice()) { throw new InvalidOperationException("No valid device."); } DeviceSettings newSettings = CurrentSettings.Clone(); newSettings.Windowed = !newSettings.Windowed; int width = newSettings.Windowed ? windowedWindowWidth : fullscreenWindowWidth; int height = newSettings.Windowed ? windowedWindowHeight : fullscreenWindowHeight; newSettings.BackBufferWidth = width; newSettings.BackBufferHeight = height; ChangeDevice(newSettings); }
/// <summary> /// Finds valid device settings based upon the desired settings. /// </summary> /// <param name="settings">The desired settings.</param> /// <returns>The best valid device settings matching the input settings.</returns> public static DeviceSettings FindValidSettings(DeviceSettings settings) { // check the desired API version try { GraphicsDeviceManager.EnsureD3D10(); } catch (Exception e) { throw new NoCompatibleDevicesException("Could not initialize Direct3D10.", e); } if (!Enumeration10.HasEnumerated) { Enumeration10.Enumerate(); } DeviceSettings newSettings = settings.Clone(); Direct3D10Settings d3d10 = FindValidD3D10Settings(settings); newSettings.Direct3D10 = d3d10; return(newSettings); }
void CreateDevice(DeviceSettings settings) { DeviceSettings oldSettings = CurrentSettings; CurrentSettings = settings; ignoreSizeChanges = true; bool keepCurrentWindowSize = false; if (settings.BackBufferWidth == 0 && settings.BackBufferHeight == 0) { keepCurrentWindowSize = true; } if (settings.Windowed) { if (oldSettings != null && !oldSettings.Windowed) { fullscreenWindowWidth = oldSettings.BackBufferWidth; fullscreenWindowHeight = oldSettings.BackBufferHeight; } } else { if (oldSettings != null && oldSettings.Windowed) { windowedWindowWidth = oldSettings.BackBufferWidth; windowedWindowHeight = oldSettings.BackBufferHeight; } } // check if the device can be reset, or if we need to completely recreate it Result result = SlimDX.DXGI.ResultCode.Success; bool canReset = CanDeviceBeReset(oldSettings, settings); if (canReset) { result = ResetDevice(); } if (result == SlimDX.Direct3D9.ResultCode.DeviceLost) { deviceLost = true; } else if (!canReset || result.IsFailure) { if (oldSettings != null) { ReleaseDevice(); } InitializeDevice(); } UpdateDeviceInformation(); // check if we need to resize if (settings.Windowed && !keepCurrentWindowSize) { int width; int height; if (NativeMethods.IsIconic(game.Window.Handle)) { WINDOWPLACEMENT placement = new WINDOWPLACEMENT(); placement.length = WINDOWPLACEMENT.Length; NativeMethods.GetWindowPlacement(game.Window.Handle, ref placement); // check if we are being restored if ((placement.flags & WindowConstants.WPF_RESTORETOMAXIMIZED) != 0 && placement.showCmd == WindowConstants.SW_SHOWMINIMIZED) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE); Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle); width = rect.Width; height = rect.Height; NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_MINIMIZE); } else { NativeRectangle frame = new NativeRectangle(); NativeMethods.AdjustWindowRect(ref frame, (uint)windowedStyle, false); int frameWidth = frame.right - frame.left; int frameHeight = frame.bottom - frame.top; width = placement.rcNormalPosition.right - placement.rcNormalPosition.left - frameWidth; height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top - frameHeight; } } else { Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle); width = rect.Width; height = rect.Height; } // check if we have a different desired size if (width != settings.BackBufferWidth || height != settings.BackBufferHeight) { if (NativeMethods.IsIconic(game.Window.Handle)) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE); } if (NativeMethods.IsZoomed(game.Window.Handle)) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE); } NativeRectangle rect = new NativeRectangle(); rect.right = settings.BackBufferWidth; rect.bottom = settings.BackBufferHeight; NativeMethods.AdjustWindowRect(ref rect, NativeMethods.GetWindowLong(game.Window.Handle, WindowConstants.GWL_STYLE), false); NativeMethods.SetWindowPos(game.Window.Handle, IntPtr.Zero, 0, 0, rect.right - rect.left, rect.bottom - rect.top, WindowConstants.SWP_NOZORDER | WindowConstants.SWP_NOMOVE); Rectangle r = NativeMethods.GetClientRectangle(game.Window.Handle); int clientWidth = r.Width; int clientHeight = r.Height; // check if the size was modified by Windows if (clientWidth != settings.BackBufferWidth || clientHeight != settings.BackBufferHeight) { DeviceSettings newSettings = CurrentSettings.Clone(); newSettings.BackBufferWidth = 0; newSettings.BackBufferHeight = 0; if (newSettings.Direct3D10 != null) { SwapChainDescription scd = newSettings.Direct3D10.SwapChainDescription; ModeDescription md = scd.ModeDescription; md.Width = 0; md.Height = 0; scd.ModeDescription = md; newSettings.Direct3D10.SwapChainDescription = scd; } CreateDevice(newSettings); } } } // if the window is still hidden, make sure it is shown if (!game.Window.Visible) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_SHOW); } // set the execution state of the thread if (!IsWindowed) { NativeMethods.SetThreadExecutionState(WindowConstants.ES_DISPLAY_REQUIRED | WindowConstants.ES_CONTINUOUS); } else { NativeMethods.SetThreadExecutionState(WindowConstants.ES_CONTINUOUS); } ignoreSizeChanges = false; }
/// <summary> /// Changes the device. /// </summary> /// <param name="settings">The settings.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="settings"/> is <c>null</c>.</exception> /// <exception cref="NoCompatibleDevicesException">Thrown when the framework cannot find a suitable graphics device.</exception> /// <exception cref="DeviceCreationException">Thrown when device creation fails.</exception> public void ChangeDevice(DeviceSettings settings) { ChangeDevice(settings, null); }
public static Direct3D10Settings BuildOptimalSettings(DeviceSettings settings) { ModeDescription desktopMode = GetAdapterDisplayMode(0, 0); Direct3D10Settings optimal = new Direct3D10Settings(); SwapChainDescription swapChainDescription = new SwapChainDescription(); ModeDescription mode = new ModeDescription(); SampleDescription sample = new SampleDescription(); optimal.AdapterOrdinal = settings.AdapterOrdinal; optimal.DriverType = settings.DeviceType; optimal.PresentFlags = PresentFlags.None; swapChainDescription.IsWindowed = settings.Windowed; swapChainDescription.BufferCount = settings.BackBufferCount; sample.Count = settings.MultisampleCount; sample.Quality = settings.MultisampleQuality; swapChainDescription.SwapEffect = SwapEffect.Discard; if (settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0) { if (settings.Windowed) { mode.Width = 640; mode.Height = 480; } else { mode.Width = desktopMode.Width; mode.Height = desktopMode.Height; } } else { mode.Width = settings.BackBufferWidth; mode.Height = settings.BackBufferHeight; } if (settings.BackBufferFormat == Format.Unknown) { mode.Format = desktopMode.Format; } else { mode.Format = settings.BackBufferFormat; } swapChainDescription.Usage = Usage.RenderTargetOutput; optimal.DepthStencilFormat = settings.DepthStencilFormat; if (settings.RefreshRate == 0) { mode.RefreshRate = new Rational(0, 0); } else { mode.RefreshRate = new Rational(settings.RefreshRate, 1); } if (settings.EnableVSync) { optimal.SyncInterval = 1; } else { optimal.SyncInterval = 0; } swapChainDescription.SampleDescription = sample; swapChainDescription.ModeDescription = mode; optimal.SwapChainDescription = swapChainDescription; return(optimal); }