public void RefreshDisplayDevices() { this.displayDevices.Clear(); foreach(DeviceType devType in Enum.GetValues(typeof(DeviceType))) { DisplayDevice displayDevice = new DisplayDevice(this, devType); // add the display device if we have any valid device modes if (displayDevice.DeviceModes.Count >= 0) this.displayDevices.Add(displayDevice); } }
private readonly ArrayList vertexProcessingTypes = new ArrayList(); // List of VertexProcessingTypes #endregion Fields #region Constructors public DisplayDeviceMode(DisplayDevice displayDevice, Format adapterFormat, Format backBufferFormat, Boolean isWindowed) { this.displayDevice = displayDevice; this.adapterFormat = adapterFormat; this.backBufferFormat = backBufferFormat; this.isWindowed = isWindowed; this.RefreshDepthStencilFormats(); this.RefreshMultiSampleTypes(); this.RefreshDepthStencilMultiSampleConflicts(); this.RefreshVertexProcessingTypes(); this.RefreshPresentIntervals(); }
public Boolean FindBestFullScreenMode(Boolean requiresHardware, Boolean requiresReference) { // For fullscreen, default to first HAL DeviceCombo that supports the current desktop // display mode, or any display mode if HAL is not compatible with the desktop mode, or // non-HAL if no HAL is available DisplayMode adapterDesktopDisplayMode = new DisplayMode(); DisplayMode bestAdapterDesktopDisplayMode = new DisplayMode(); DisplayMode bestDisplayMode = new DisplayMode(); bestAdapterDesktopDisplayMode.Width = 0; bestAdapterDesktopDisplayMode.Height = 0; bestAdapterDesktopDisplayMode.Format = 0; bestAdapterDesktopDisplayMode.RefreshRate = 0; DisplayAdapter bestAdapter = null; DisplayDevice bestDevice = null; DisplayDeviceMode bestDeviceMode = null; foreach (DisplayAdapter displayAdapter in hardwareInfo.DisplayAdapters) { adapterDesktopDisplayMode = Manager.Adapters[displayAdapter.Ordinal].CurrentDisplayMode; foreach (DisplayDevice displayDevice in displayAdapter.DisplayDevices) { if (requiresHardware && displayDevice.DeviceType != DeviceType.Hardware) { continue; } if (requiresReference && displayDevice.DeviceType != DeviceType.Reference) { continue; } foreach (DisplayDeviceMode deviceMode in displayDevice.DeviceModes) { bool adapterMatchesBackBuffer = (deviceMode.BackBufferFormat == deviceMode.AdapterFormat); bool adapterMatchesDesktop = (deviceMode.AdapterFormat == adapterDesktopDisplayMode.Format); if (deviceMode.IsWindowed) { continue; } // If we haven't found a compatible set yet, or if this set // is better (because it's a HAL, and/or because formats match better), // save it if (bestDeviceMode == null || bestDeviceMode.DeviceType != DeviceType.Hardware && displayDevice.DeviceType == DeviceType.Hardware || bestDeviceMode.DeviceType == DeviceType.Hardware && bestDeviceMode.AdapterFormat != adapterDesktopDisplayMode.Format && adapterMatchesDesktop || bestDeviceMode.DeviceType == DeviceType.Hardware && adapterMatchesDesktop && adapterMatchesBackBuffer) { bestAdapterDesktopDisplayMode = adapterDesktopDisplayMode; bestAdapter = displayAdapter; bestDevice = displayDevice; bestDeviceMode = deviceMode; if (displayDevice.DeviceType == DeviceType.Hardware && adapterMatchesDesktop && adapterMatchesBackBuffer) { // This fullscreen device combo looks great -- take it goto EndFullScreenDeviceComboSearch; } // Otherwise keep looking for a better fullscreen device combo } } } } EndFullScreenDeviceComboSearch: if (bestDeviceMode == null) { return(false); } // Need to find a display mode on the best adapter that uses pBestDeviceCombo->AdapterFormat // and is as close to bestAdapterDesktopDisplayMode's res as possible bestDisplayMode.Width = 0; bestDisplayMode.Height = 0; bestDisplayMode.Format = 0; bestDisplayMode.RefreshRate = 0; foreach (DisplayMode displayMode in bestAdapter.DisplayModes) { if (displayMode.Format != bestDeviceMode.AdapterFormat) { continue; } if (displayMode.Width == bestAdapterDesktopDisplayMode.Width && displayMode.Height == bestAdapterDesktopDisplayMode.Height && displayMode.RefreshRate == bestAdapterDesktopDisplayMode.RefreshRate) { // found a perfect match, so stop bestDisplayMode = displayMode; break; } else if (displayMode.Width == bestAdapterDesktopDisplayMode.Width && displayMode.Height == bestAdapterDesktopDisplayMode.Height && displayMode.RefreshRate > bestDisplayMode.RefreshRate) { // refresh rate doesn't match, but width/height match, so keep this // and keep looking bestDisplayMode = displayMode; } else if (bestDisplayMode.Width == bestAdapterDesktopDisplayMode.Width) { // width matches, so keep this and keep looking bestDisplayMode = displayMode; } else if (bestDisplayMode.Width == 0) { // we don't have anything better yet, so keep this and keep looking bestDisplayMode = displayMode; } } graphicsSettings.FullScreenDisplayAdapter = bestAdapter; graphicsSettings.FullScreenDisplayDevice = bestDevice; graphicsSettings.FullScreenDeviceMode = bestDeviceMode; graphicsSettings.IsWindowed = false; graphicsSettings.FullScreenDisplayMode = bestDisplayMode; //if (hardwareInfo.AppUsesDepthBuffer) graphicsSettings.FullScreenDepthStencilBufferFormat = (DepthFormat)bestDeviceMode.DepthStencilFormats[0]; graphicsSettings.FullScreenMultiSampleType = (MultiSampleType)bestDeviceMode.MultiSampleTypes[0]; graphicsSettings.FullScreenMultiSampleQuality = 0; graphicsSettings.FullScreenVertexProcessingType = (VertexProcessingType)bestDeviceMode.VertexProcessingTypes[0]; graphicsSettings.FullScreenPresentInterval = (PresentInterval)bestDeviceMode.PresentIntervals[0]; return(true); }
/// <summary> /// Sets up GraphicsSettings with best available windowed mode, subject to /// the doesRequireHardware and doesRequireReference constraints. /// </summary> /// <param name="requiresHardware">Does the device require hardware support.</param> /// <param name="requiresReference">Does the device require the ref device.</param> /// <returns>true if a mode is found, false otherwise.</returns> public Boolean FindBestWindowedMode(Boolean requiresHardware, Boolean requiresReference) { // Get display mode of primary adapter (which is assumed to be where the window // will appear) DisplayMode primaryDesktopDisplayMode = Manager.Adapters[0].CurrentDisplayMode; DisplayAdapter bestAdapter = null; DisplayDevice bestDevice = null; DisplayDeviceMode bestDeviceMode = null; foreach (DisplayAdapter displayAdapter in this.hardwareInfo.DisplayAdapters) { foreach (DisplayDevice displayDevice in displayAdapter.DisplayDevices) { if (requiresHardware && displayDevice.DeviceType != DeviceType.Hardware) { continue; } if (requiresReference && displayDevice.DeviceType != DeviceType.Reference) { continue; } foreach (DisplayDeviceMode deviceMode in displayDevice.DeviceModes) { bool adapterMatchesBackBuffer = (deviceMode.BackBufferFormat == deviceMode.AdapterFormat); if (!deviceMode.IsWindowed) { continue; } if (deviceMode.AdapterFormat != primaryDesktopDisplayMode.Format) { continue; } // If we haven't found a compatible DeviceCombo yet, or if this set // is better (because it's a HAL, and/or because formats match better), // save it if (bestDeviceMode == null || bestDeviceMode.DeviceType != DeviceType.Hardware && displayDevice.DeviceType == DeviceType.Hardware || deviceMode.DeviceType == DeviceType.Hardware && adapterMatchesBackBuffer) { bestAdapter = displayAdapter; bestDevice = displayDevice; bestDeviceMode = deviceMode; if (displayDevice.DeviceType == DeviceType.Hardware && adapterMatchesBackBuffer) { // This windowed device combo looks great -- take it goto EndWindowedDeviceComboSearch; } // Otherwise keep looking for a better windowed device combo } } } } EndWindowedDeviceComboSearch: if (bestDeviceMode == null) { return(false); } this.graphicsSettings.WindowedDisplayAdapter = bestAdapter; this.graphicsSettings.WindowedDisplayDevice = bestDevice; this.graphicsSettings.WindowedDeviceMode = bestDeviceMode; this.graphicsSettings.IsWindowed = true; this.graphicsSettings.WindowedDisplayMode = primaryDesktopDisplayMode; this.graphicsSettings.WindowedWidth = this.viewport.ClientRectangle.Right - this.viewport.ClientRectangle.Left; this.graphicsSettings.WindowedHeight = this.viewport.ClientRectangle.Bottom - this.viewport.ClientRectangle.Top; // todo: fix depth buffer setting //if (Direct3DEnumerator.AppUsesDepthBuffer) graphicsSettings.WindowedDepthStencilBufferFormat = (DepthFormat)bestDeviceMode.DepthStencilFormats[0]; this.graphicsSettings.WindowedMultiSampleType = (MultiSampleType)bestDeviceMode.MultiSampleTypes[0]; this.graphicsSettings.WindowedMultiSampleQuality = 0; this.graphicsSettings.WindowedVertexProcessingType = (VertexProcessingType)bestDeviceMode.VertexProcessingTypes[0]; this.graphicsSettings.WindowedPresentInterval = (PresentInterval)bestDeviceMode.PresentIntervals[0]; return(true); }
private void Initialize3DEnvironment() { DisplayAdapter adapterInfo = graphicsSettings.DisplayAdapter; DisplayDevice deviceInfo = graphicsSettings.DisplayDevice; isWindowed = graphicsSettings.IsWindowed; // Prepare window for possible windowed/fullscreen change // AdjustWindowForChange(); // Set up the presentation parameters RefreshPresentParameters(); if (deviceInfo.Caps.PrimitiveMiscCaps.IsNullReference) { // Warn user about null ref device that can't render anything throw new ApplicationException("null reference device"); } CreateFlags createFlags = new CreateFlags(); switch (graphicsSettings.VertexProcessingType) { case VertexProcessingType.Software: createFlags = CreateFlags.SoftwareVertexProcessing; break; case VertexProcessingType.Mixed: createFlags = CreateFlags.MixedVertexProcessing; break; case VertexProcessingType.Hardware: createFlags = CreateFlags.HardwareVertexProcessing; break; case VertexProcessingType.PureHardware: createFlags = CreateFlags.HardwareVertexProcessing | CreateFlags.PureDevice; break; default: throw new ApplicationException("Unable to determine vertex processing method."); } // Create the device device = new Device(graphicsSettings.AdapterOrdinal, graphicsSettings.DisplayDevice.DeviceType, this.viewport, createFlags, this.presentParameters); if (device != null) { // Cache our local objects renderStates = device.RenderState; samplerStates = device.SamplerState; textureStates = device.TextureState; // When moving from fullscreen to windowed mode, it is important to // adjust the window size after recreating the device rather than // beforehand to ensure that you get the window size you want. For // example, when switching from 640x480 fullscreen to windowed with // a 1000x600 window on a 1024x768 desktop, it is impossible to set // the window size to 1000x600 until after the display mode has // changed to 1024x768, because windows cannot be larger than the // desktop. if (graphicsSettings.IsWindowed && (this.viewport is System.Windows.Forms.Form)) { // Make sure main window isn't topmost, so error message is visible this.viewport.Location = new System.Drawing.Point(rectWindowBounds.Left, rectWindowBounds.Top); this.viewport.Size = new System.Drawing.Size((rectWindowBounds.Right - rectWindowBounds.Left), (rectWindowBounds.Bottom - rectWindowBounds.Top)); } // Store device Caps graphicsCaps = device.DeviceCaps; behavior = createFlags; // Store render target surface desc Surface BackBuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono); backBufferDesc = BackBuffer.Description; BackBuffer.Dispose(); BackBuffer = null; // Set up the fullscreen cursor if (showFullScreenCursor && !graphicsSettings.IsWindowed) { System.Windows.Forms.Cursor ourCursor = this.viewport.Cursor; device.SetCursor(ourCursor, true); device.ShowCursor(true); } // Confine cursor to fullscreen window if (clipFullScreenCursor) { if (!isWindowed) { System.Drawing.Rectangle rcWindow = this.viewport.ClientRectangle; } } // Setup the event handlers for our device device.DeviceLost += InvalidateDeviceObjects; device.DeviceReset += RestoreDeviceObjects; device.Disposing += DeleteDeviceObjects; device.DeviceResizing += new CancelEventHandler(EnvironmentResized); // Initialize the app's device-dependent objects try { if (InitDeviceObjects != null) { InitDeviceObjects(null, null); } if (RestoreDeviceObjects != null) { RestoreDeviceObjects(null, null); } return; } catch { // Cleanup before we try again if (InvalidateDeviceObjects != null) { InvalidateDeviceObjects(null, null); } if (DeleteDeviceObjects != null) { DeleteDeviceObjects(null, null); } device.Dispose(); device = null; if (this.viewport.Disposing) { return; } } } // HACK: removed fallback to reference rasterizer /* * // If that failed, fall back to the reference rasterizer * if( deviceInfo.DevType == Direct3D.DeviceType.Hardware ) * { * if (FindBestWindowedMode(false, true)) * { * isWindowed = true; * if(viewport is System.Windows.Forms.Form) * { * // Make sure main window isn't topmost, so error message is visible * this.viewport.Location = new System.Drawing.Point(windowBoundsRect.Left, windowBoundsRect.Top); * this.viewport.Size = new System.Drawing.Size(( windowBoundsRect.Right - windowBoundsRect.Left ), ( windowBoundsRect.Bottom - windowBoundsRect.Top)); * //AdjustWindowForChange(); * } * * // Let the user know we are switching from HAL to the reference rasterizer * //DisplayErrorMsg( null, AppMsgType.WarnSwitchToRef); * * Initialize3DEnvironment(); * } * } */ }