diff --git a/Source/Examples/Tests/TestResolutionChanges.cs b/Source/Examples/Tests/TestResolutionChanges.cs
index b353b66f..426d32ca 100644
--- a/Source/Examples/Tests/TestResolutionChanges.cs
+++ b/Source/Examples/Tests/TestResolutionChanges.cs
@@ -24,9 +24,11 @@ namespace Examples.Tests
foreach (DisplayDevice dev in DisplayDevice.AvailableDisplays)
{
Trace.WriteLine(dev.ToString());
- //MessageBox.Show(dev.ToString());
- //dev.ChangeResolution(640, 480, 32, 60.0f);
- //dev.RestoreResolution();
+ MessageBox.Show(dev.ToString());
+ // Switch to the first available resolution that has the same bpp as the current one (usually 640x480@60Hz)
+ dev.ChangeResolution(dev.SelectResolution(0, 0, dev.BitsPerPixel, 0));
+ MessageBox.Show(dev.ToString());
+ dev.RestoreResolution();
}
}
}
diff --git a/Source/OpenTK/Graphics/DisplayDevice.cs b/Source/OpenTK/Graphics/DisplayDevice.cs
index 330a154b..96d50455 100644
--- a/Source/OpenTK/Graphics/DisplayDevice.cs
+++ b/Source/OpenTK/Graphics/DisplayDevice.cs
@@ -67,7 +67,6 @@ namespace OpenTK.Graphics
#region --- Public Methods ---
-
#region public int Width
/// Gets a System.Int32 that contains the width of this display in pixels.
@@ -108,7 +107,54 @@ namespace OpenTK.Graphics
#endregion
- #region public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ #region public DisplayResolution[] AvailableResolutions
+
+ ///
+ /// Gets an array of OpenTK.DisplayResolution objects, which describe all available resolutions
+ /// for this device.
+ ///
+ public DisplayResolution[] AvailableResolutions
+ {
+ get
+ {
+ lock (display_lock)
+ {
+ return available_resolutions.ToArray();
+ }
+ }
+ }
+
+ #endregion
+
+ #region public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
+
+ ///
+ /// Selects an available resolution that matches the specified parameters.
+ ///
+ /// The width of the requested resolution in pixels.
+ /// The height of the requested resolution in pixels.
+ /// The bits per pixel of the requested resolution.
+ /// The refresh rate of the requested resolution in Herz.
+ /// The requested DisplayResolution or null if the parameters cannot be met.
+ ///
+ /// A parameter set to 0 will not be used in the search (e.g. if refreshRate is 0, any refresh rate will be considered valid).
+ /// This function generates garbage.
+ ///
+ public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ {
+ return available_resolutions.Find(delegate(DisplayResolution test)
+ {
+ return
+ ((width > 0 && width == test.Width) || width == 0) &&
+ ((height > 0 && height == test.Height) || height == 0) &&
+ ((bitsPerPixel > 0 && bitsPerPixel == test.BitsPerPixel) || bitsPerPixel == 0) &&
+ ((refreshRate > 0 && (int)refreshRate == (int)test.RefreshRate) || refreshRate == 0);
+ });
+ }
+
+ #endregion
+
+ #region public void ChangeResolution(DisplayResolution resolution)
/// Changes the resolution of the DisplayDevice.
/// The new width of the DisplayDevice.
@@ -116,20 +162,18 @@ namespace OpenTK.Graphics
/// The new bits per pixel of the DisplayDevice.
/// The new refresh rate of the DisplayDevice.
/// Thrown if the requested resolution change failed.
- public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ public void ChangeResolution(DisplayResolution resolution)
{
- if (width <= 0) throw new ArgumentOutOfRangeException("width", "Must be greater than zero.");
- if (height <= 0) throw new ArgumentOutOfRangeException("height", "Must be greater than zero.");
- if (bitsPerPixel <= 0) throw new ArgumentOutOfRangeException("bitsPerPixel", "Must be greater than zero.");
- if (refreshRate <= 0) throw new ArgumentOutOfRangeException("refreshRate", "Must be greater than zero.");
+ if (resolution == null)
+ throw new ArgumentNullException("resulotion", "Must be a valid resolution.");
- if (implementation.TryChangeResolution(width, height, bitsPerPixel, refreshRate))
+ if (implementation.TryChangeResolution(this, resolution))
{
- current_resolution = new DisplayResolution(width, height, bitsPerPixel, refreshRate);
+ current_resolution = resolution;
}
else
- throw new GraphicsModeException(String.Format("Device {0}: Failed to change resolution to {1}x{2}x{3]@{4]Hz",
- ToString(), width, height, bitsPerPixel, refreshRate));
+ throw new GraphicsModeException(String.Format("Device {0}: Failed to change resolution to {1}.",
+ this, resolution));
}
#endregion
@@ -138,7 +182,7 @@ namespace OpenTK.Graphics
public void RestoreResolution()
{
- implementation.RestoreResolution();
+ implementation.RestoreResolution(this);
}
#endregion
@@ -146,7 +190,7 @@ namespace OpenTK.Graphics
#region public static DisplayDevice[] AvailableDisplays
///
- /// Gets an array of OpenTK.Display objects, which describe all available display devices.
+ /// Gets an array of OpenTK.DisplayDevice objects, which describe all available display devices.
///
public static DisplayDevice[] AvailableDisplays
{
@@ -191,19 +235,19 @@ namespace OpenTK.Graphics
/// Determines whether the specified DisplayDevices are equal.
/// The System.Object to check against.
/// True if the System.Object is an equal DisplayDevice; false otherwise.
- public override bool Equals(object obj)
- {
- if (obj is DisplayDevice)
- {
- DisplayDevice dev = (DisplayDevice)obj;
- return
- IsPrimary == dev.IsPrimary &&
- current_resolution == dev.current_resolution &&
- available_resolutions.Count == dev.available_resolutions.Count;
- }
+ //public override bool Equals(object obj)
+ //{
+ // if (obj is DisplayDevice)
+ // {
+ // DisplayDevice dev = (DisplayDevice)obj;
+ // return
+ // IsPrimary == dev.IsPrimary &&
+ // current_resolution == dev.current_resolution &&
+ // available_resolutions.Count == dev.available_resolutions.Count;
+ // }
- return false;
- }
+ // return false;
+ //}
#endregion
@@ -211,10 +255,10 @@ namespace OpenTK.Graphics
/// Returns a unique hash representing this DisplayDevice.
/// A System.Int32 that may serve as a hash code for this DisplayDevice.
- public override int GetHashCode()
- {
- return current_resolution.GetHashCode() ^ IsPrimary.GetHashCode() ^ available_resolutions.Count;
- }
+ //public override int GetHashCode()
+ //{
+ // return current_resolution.GetHashCode() ^ IsPrimary.GetHashCode() ^ available_resolutions.Count;
+ //}
#endregion
diff --git a/Source/OpenTK/Graphics/DisplayResolution.cs b/Source/OpenTK/Graphics/DisplayResolution.cs
index 46457bff..1cf62357 100644
--- a/Source/OpenTK/Graphics/DisplayResolution.cs
+++ b/Source/OpenTK/Graphics/DisplayResolution.cs
@@ -24,6 +24,11 @@ namespace OpenTK.Graphics
internal DisplayResolution(int width, int height, int bitsPerPixel, float refreshRate)
{
+ if (width <= 0) throw new ArgumentOutOfRangeException("width", "Must be greater than zero.");
+ if (height <= 0) throw new ArgumentOutOfRangeException("height", "Must be greater than zero.");
+ if (bitsPerPixel <= 0) throw new ArgumentOutOfRangeException("bitsPerPixel", "Must be greater than zero.");
+ if (refreshRate <= 0) throw new ArgumentOutOfRangeException("refreshRate", "Must be greater than zero.");
+
this.width = width;
this.height = height;
this.bits_per_pixel = bitsPerPixel;
diff --git a/Source/OpenTK/Graphics/IDisplayDeviceDriver.cs b/Source/OpenTK/Graphics/IDisplayDeviceDriver.cs
index 6845def2..6b4eac1c 100644
--- a/Source/OpenTK/Graphics/IDisplayDeviceDriver.cs
+++ b/Source/OpenTK/Graphics/IDisplayDeviceDriver.cs
@@ -14,8 +14,8 @@ namespace OpenTK.Graphics
{
internal interface IDisplayDeviceDriver
{
- bool TryChangeResolution(int width, int height, int bitsPerPixel, float refreshRate);
- void RestoreResolution();
+ bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution);
+ void RestoreResolution(DisplayDevice device);
//DisplayDevice[] AvailableDevices { get; }
//DisplayResolution[]
}
diff --git a/Source/OpenTK/Platform/Windows/WinDisplayDevice.cs b/Source/OpenTK/Platform/Windows/WinDisplayDevice.cs
index 1784b861..8458b96a 100644
--- a/Source/OpenTK/Platform/Windows/WinDisplayDevice.cs
+++ b/Source/OpenTK/Platform/Windows/WinDisplayDevice.cs
@@ -18,8 +18,9 @@ namespace OpenTK.Platform.Windows
{
internal class WinDisplayDeviceDriver : IDisplayDeviceDriver
{
- // In OpenTK nomenclature, a DisplayDevice is a screen, not a video card!
static object display_lock = new object();
+ static Dictionary available_device_names =
+ new Dictionary(); // Needed for ChangeDisplaySettingsEx
#region --- Constructors ---
@@ -71,6 +72,8 @@ namespace OpenTK.Platform.Windows
// Construct the OpenTK DisplayDevice through the accumulated parameters.
opentk_dev = new OpenTK.Graphics.DisplayDevice(opentk_dev_current_res, opentk_dev_primary,
opentk_dev_available_res);
+
+ available_device_names.Add(opentk_dev, dev1.DeviceName);
}
}
}
@@ -83,31 +86,34 @@ namespace OpenTK.Platform.Windows
#region --- IDisplayDeviceDriver Members ---
- #region public bool TryChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ #region public bool TryChangeResolution(OpenTK.Graphics.DisplayDevice device, DisplayResolution resolution)
- public bool TryChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ public bool TryChangeResolution(OpenTK.Graphics.DisplayDevice device, DisplayResolution resolution)
{
- DeviceMode settings = new DeviceMode();
- settings.PelsWidth = width;
- settings.PelsHeight = height;
- settings.BitsPerPel = bitsPerPixel;
- settings.DisplayFrequency = (int)refreshRate;
- settings.Fields = Constants.DM_BITSPERPEL
+ DeviceMode mode = new DeviceMode();
+ mode.PelsWidth = resolution.Width;
+ mode.PelsHeight = resolution.Height;
+ mode.BitsPerPel = resolution.BitsPerPixel;
+ mode.DisplayFrequency = (int)resolution.RefreshRate;
+ mode.Fields = Constants.DM_BITSPERPEL
| Constants.DM_PELSWIDTH
- | Constants.DM_PELSHEIGHT;
+ | Constants.DM_PELSHEIGHT
+ | Constants.DM_DISPLAYFREQUENCY;
- return Functions.ChangeDisplaySettings(settings, ChangeDisplaySettingsEnum.Fullscreen) ==
+ //return Functions.ChangeDisplaySettings(settings, ChangeDisplaySettingsEnum.Fullscreen) ==
+ // Constants.DISP_CHANGE_SUCCESSFUL;
+ return Functions.ChangeDisplaySettingsEx(available_device_names[device], mode, IntPtr.Zero, 0, IntPtr.Zero) ==
Constants.DISP_CHANGE_SUCCESSFUL;
}
#endregion
- #region public void RestoreResolution()
+ #region public void RestoreResolution(OpenTK.Graphics.DisplayDevice device)
- public void RestoreResolution()
+ public void RestoreResolution(OpenTK.Graphics.DisplayDevice device)
{
- Functions.ChangeDisplaySettings(null, (ChangeDisplaySettingsEnum)0);
- //Functions.ChangeDisplaySettings(
+ //Functions.ChangeDisplaySettings(null, (ChangeDisplaySettingsEnum)0);
+ Functions.ChangeDisplaySettingsEx(available_device_names[device], null, IntPtr.Zero, 0, IntPtr.Zero);
}
#endregion