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
/// <summary>
/// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure that contains the external bounds of this window, in screen coordinates.
/// External bounds include the title bar, borders and drawing area of the window.
/// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure
/// 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>
public Rectangle Bounds
{
@ -214,8 +216,9 @@ namespace OpenTK
#region ClientRectangle
/// <summary>
/// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure that contains the internal bounds of this window, in client coordinates.
/// The internal bounds include the drawing area of the window, but exclude the titlebar and window borders.
/// Gets or sets a <see cref="System.Drawing.Rectangle"/> structure
/// that defines the bounds of the OpenGL surface, in window coordinates.
/// The coordinates are specified in device-dependent pixels.
/// </summary>
public Rectangle ClientRectangle
{
@ -236,7 +239,9 @@ namespace OpenTK
#region ClientSize
/// <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>
public Size ClientSize
{
@ -288,7 +293,8 @@ namespace OpenTK
#region Height
/// <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>
public int Height
{
@ -431,7 +437,8 @@ namespace OpenTK
#region Width
/// <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>
public int Width
{
@ -506,7 +513,8 @@ namespace OpenTK
#region X
/// <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>
public int X
{
@ -527,7 +535,8 @@ namespace OpenTK
#region Y
/// <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>
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_RESIZABLE;
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 ||
(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)
{
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)
@ -779,11 +782,11 @@ namespace OpenTK.Platform.SDL2
{
get
{
return Size.Width;
return ClientSize.Width;
}
set
{
Size = new Size(value, Height);
ClientSize = new Size(value, Height);
}
}
@ -791,11 +794,11 @@ namespace OpenTK.Platform.SDL2
{
get
{
return Size.Height;
return ClientSize.Height;
}
set
{
Size = new Size(Width, value);
ClientSize = new Size(Width, value);
}
}
@ -803,15 +806,11 @@ namespace OpenTK.Platform.SDL2
{
get
{
// Todo: SDL2 does not have any APIs to get
// the border size or the bounds of the window
// (everything is defined in terms of the client
// area)
return Bounds;
return new Rectangle(new Point(), ClientSize);
}
set
{
Bounds = value;
ClientSize = value.Size;
}
}
@ -819,11 +818,14 @@ namespace OpenTK.Platform.SDL2
{
get
{
return Size;
int w, h;
SDL.SDL_GL_GetDrawableSize(window.Handle, out w, out h);
return new Size(w, h);
}
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 | 0x00001000),
SDL_WINDOW_FOREIGN = 0x00000800,
SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,
}
public const int SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000;
@ -1342,6 +1343,9 @@ namespace OpenTK.Platform.SDL2
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
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 */
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr SDL_GL_GetProcAddress(