Add support for HiDPI modes

When HiDPI is enabled, the size of the OpenGL surface (specified in
pixels) may no longer correspond to the size of the window (specified
in points). Width, Height, ClientSize and ClientRectangle return the
size of the OpenGL surface in device-dependent pixel coordinates
(origin: top-left pixel of the surface). Bounds and Size return the
size of the window in device-independent point coordinates (origin:
desktop).
This commit is contained in:
Stefanos A 2013-10-04 01:38:19 +02:00
parent 913c4f16e6
commit b4c29d802b
3 changed files with 38 additions and 23 deletions

View file

@ -192,8 +192,10 @@ namespace OpenTK
#region Bounds #region Bounds
/// <summary> /// <summary>
/// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure that contains the external bounds of this window, in screen coordinates. /// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure
/// External bounds include the title bar, borders and drawing area of the window. /// that specifies the external bounds of this window, in screen coordinates.
/// The coordinates are specified in device-independent points and
/// include the title bar, borders and drawing area of the window.
/// </summary> /// </summary>
public Rectangle Bounds public Rectangle Bounds
{ {
@ -214,8 +216,9 @@ namespace OpenTK
#region ClientRectangle #region ClientRectangle
/// <summary> /// <summary>
/// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure that contains the internal bounds of this window, in client coordinates. /// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure
/// The internal bounds include the drawing area of the window, but exclude the titlebar and window borders. /// that defines the bounds of the OpenGL surface, in window coordinates.
/// The coordinates are specified in device-dependent pixels.
/// </summary> /// </summary>
public Rectangle ClientRectangle public Rectangle ClientRectangle
{ {
@ -236,7 +239,9 @@ namespace OpenTK
#region ClientSize #region ClientSize
/// <summary> /// <summary>
/// Gets or sets a <see cref="System.Drawing.Size"/> structure that contains the internal size this window. /// Gets or sets a <see cref="System.Drawing.Size"/> structure
/// that defines the size of the OpenGL surface in window coordinates.
/// The coordinates are specified in device-dependent pixels.
/// </summary> /// </summary>
public Size ClientSize public Size ClientSize
{ {
@ -288,7 +293,8 @@ namespace OpenTK
#region Height #region Height
/// <summary> /// <summary>
/// Gets or sets the external height of this window. /// Gets or sets the height of the OpenGL surface in window coordinates.
/// The coordinates are specified in device-dependent pixels.
/// </summary> /// </summary>
public int Height public int Height
{ {
@ -431,7 +437,8 @@ namespace OpenTK
#region Width #region Width
/// <summary> /// <summary>
/// Gets or sets the external width of this window. /// Gets or sets the height of the OpenGL surface in window coordinates.
/// The coordinates are specified in device-dependent pixels.
/// </summary> /// </summary>
public int Width public int Width
{ {
@ -506,7 +513,8 @@ namespace OpenTK
#region X #region X
/// <summary> /// <summary>
/// Gets or sets the horizontal location of this window on the desktop. /// Gets or sets the horizontal location of this window in screen coordinates.
/// The coordinates are specified in device-independent points.
/// </summary> /// </summary>
public int X public int X
{ {
@ -527,7 +535,8 @@ namespace OpenTK
#region Y #region Y
/// <summary> /// <summary>
/// Gets or sets the vertical location of this window on the desktop. /// Gets or sets the vertical location of this window in screen coordinates.
/// The coordinates are specified in device-independent points.
/// </summary> /// </summary>
public int Y public int Y
{ {

View file

@ -75,6 +75,7 @@ namespace OpenTK.Platform.SDL2
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL; flags |= SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL;
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE; flags |= SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN; flags |= SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN;
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI;
if ((flags & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP) != 0 || if ((flags & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP) != 0 ||
(flags & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN) != 0) (flags & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN) != 0)
@ -249,7 +250,9 @@ namespace OpenTK.Platform.SDL2
static void ProcessMotionEvent(Sdl2NativeWindow window, SDL.SDL_Event ev) static void ProcessMotionEvent(Sdl2NativeWindow window, SDL.SDL_Event ev)
{ {
window.mouse.Position = new Point(ev.motion.x, ev.motion.y); float scale = window.ClientSize.Width / (float)window.Size.Width;
window.mouse.Position = new Point(
(int)(ev.motion.x * scale), (int)(ev.motion.y * scale));
} }
static void ProcessWheelEvent(Sdl2NativeWindow window, SDL.SDL_Event ev) static void ProcessWheelEvent(Sdl2NativeWindow window, SDL.SDL_Event ev)
@ -779,11 +782,11 @@ namespace OpenTK.Platform.SDL2
{ {
get get
{ {
return Size.Width; return ClientSize.Width;
} }
set set
{ {
Size = new Size(value, Height); ClientSize = new Size(value, Height);
} }
} }
@ -791,11 +794,11 @@ namespace OpenTK.Platform.SDL2
{ {
get get
{ {
return Size.Height; return ClientSize.Height;
} }
set set
{ {
Size = new Size(Width, value); ClientSize = new Size(Width, value);
} }
} }
@ -803,15 +806,11 @@ namespace OpenTK.Platform.SDL2
{ {
get get
{ {
// Todo: SDL2 does not have any APIs to get return new Rectangle(new Point(), ClientSize);
// the border size or the bounds of the window
// (everything is defined in terms of the client
// area)
return Bounds;
} }
set set
{ {
Bounds = value; ClientSize = value.Size;
} }
} }
@ -819,11 +818,14 @@ namespace OpenTK.Platform.SDL2
{ {
get get
{ {
return Size; int w, h;
SDL.SDL_GL_GetDrawableSize(window.Handle, out w, out h);
return new Size(w, h);
} }
set set
{ {
Size = value; float scale = Size.Width / (float)ClientSize.Width;
Size = new Size((int)(value.Width * scale), (int)(value.Height * scale));
} }
} }

View file

@ -960,6 +960,7 @@ namespace OpenTK.Platform.SDL2
SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN_DESKTOP =
(SDL_WINDOW_FULLSCREEN | 0x00001000), (SDL_WINDOW_FULLSCREEN | 0x00001000),
SDL_WINDOW_FOREIGN = 0x00000800, SDL_WINDOW_FOREIGN = 0x00000800,
SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,
} }
public const int SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000; public const int SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000;
@ -1341,7 +1342,10 @@ namespace OpenTK.Platform.SDL2
/* context refers to an SDL_GLContext */ /* context refers to an SDL_GLContext */
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
public static extern void SDL_GL_DeleteContext(IntPtr context); public static extern void SDL_GL_DeleteContext(IntPtr context);
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
public static extern void SDL_GL_GetDrawableSize(IntPtr window, out int w, out int h);
/* IntPtr refers to a function pointer */ /* IntPtr refers to a function pointer */
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr SDL_GL_GetProcAddress( public static extern IntPtr SDL_GL_GetProcAddress(