From 4aae0290ea94a4be6e2b417b8c9d59910a12edba Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 31 Dec 2015 21:16:43 -0400 Subject: [PATCH] Updated some header comments and iOS documentation to better clarify high-dpi / retina support and screen-coordinate sizes versus pixel sizes. --- WhatsNew.txt | 6 ++--- docs/README-ios.md | 42 +++++++++++++++++++++++++------ include/SDL_render.h | 2 +- include/SDL_video.h | 59 ++++++++++++++++++++++++++++++-------------- 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/WhatsNew.txt b/WhatsNew.txt index b37591d826059..698ebf7dfa383 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -71,13 +71,13 @@ Linux: iOS: * Added support for iOS 8 +* The SDL_WINDOW_ALLOW_HIGHDPI window flag now enables high-dpi support, and SDL_GL_GetDrawableSize() or SDL_GetRendererOutputSize() gets the window resolution in pixels +* SDL_GetWindowSize() and display mode sizes are in the "DPI-independent points" / "screen coordinates" coordinate space rather than pixels (matches OS X behavior) +* Added native resolution support for the iPhone 6 Plus * Added support for MFi game controllers * Added support for the hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK * Added sRGB OpenGL ES context support on iOS 7+ -* Added native resolution support for the iPhone 6 Plus * Added support for SDL_DisableScreenSaver(), SDL_EnableScreenSaver() and the hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER -* The SDL_WINDOW_ALLOW_HIGHDPI window flag now enables high-dpi support, and SDL_GL_GetDrawableSize() or SDL_GetRendererOutputSize() gets the window resolution in pixels -* SDL_GetWindowSize() and display mode sizes are in the "DPI-independent points" coordinate space rather than pixels (matches OS X behavior) * SDL_SysWMinfo now contains the OpenGL ES framebuffer and color renderbuffer objects used by the window's active GLES view * Fixed various rotation and orientation issues * Fixed memory leaks diff --git a/docs/README-ios.md b/docs/README-ios.md index 69c35d6f7c11f..d2c6877ec4e13 100644 --- a/docs/README-ios.md +++ b/docs/README-ios.md @@ -47,17 +47,45 @@ Using the Simple DirectMedia Layer for iOS FIXME: This needs to be updated for the latest methods Here is the easiest method: -1. Build the SDL libraries (libSDL.a and libSDLSimulator.a) and the iPhone SDL Application template. -2. Install the iPhone SDL Application template by copying it to one of XCode's template directories. I recommend creating a directory called "SDL" in "/Developer/Platforms/iOS.platform/Developer/Library/XCode/Project Templates/" and placing it there. +1. Build the SDL library (libSDL2.a) and the iPhone SDL Application template. +2. Install the iPhone SDL Application template by copying it to one of Xcode's template directories. I recommend creating a directory called "SDL" in "/Developer/Platforms/iOS.platform/Developer/Library/Xcode/Project Templates/" and placing it there. 3. Start a new project using the template. The project should be immediately ready for use with SDL. Here is a more manual method: -1. Create a new iPhone view based application. -2. Build the SDL static libraries (libSDL.a and libSDLSimulator.a) for iPhone and include them in your project. XCode will ignore the library that is not currently of the correct architecture, hence your app will work both on iPhone and in the iPhone Simulator. +1. Create a new iOS view based application. +2. Build the SDL static library (libSDL2.a) for iOS and include them in your project. Xcode will ignore the library that is not currently of the correct architecture, hence your app will work both on iOS and in the iOS Simulator. 3. Include the SDL header files in your project. -4. Remove the ApplicationDelegate.h and ApplicationDelegate.m files -- SDL for iPhone provides its own UIApplicationDelegate. Remove MainWindow.xib -- SDL for iPhone produces its user interface programmatically. -5. Delete the contents of main.m and program your app as a regular SDL program instead. You may replace main.m with your own main.c, but you must tell XCode not to use the project prefix file, as it includes Objective-C code. +4. Remove the ApplicationDelegate.h and ApplicationDelegate.m files -- SDL for iOS provides its own UIApplicationDelegate. Remove MainWindow.xib -- SDL for iOS produces its user interface programmatically. +5. Delete the contents of main.m and program your app as a regular SDL program instead. You may replace main.m with your own main.c, but you must tell Xcode not to use the project prefix file, as it includes Objective-C code. +============================================================================== +Notes -- Retina / High-DPI and window sizes +============================================================================== + +Window and display mode sizes in SDL are in "screen coordinates" (or "points", +in Apple's terminology) rather than in pixels. On iOS this means that a window +created on an iPhone 6 will have a size in screen cooordinates of 375 x 667, +rather than a size in pixels of 750 x 1334. All iOS apps are expected to +size their content based on screen coordinates / points rather than pixels, +as this allows different iOS devices to have different pixel densities +(Retina versus non-Retina screens, etc.) without apps caring too much. + +By default SDL will not use the full pixel density of the screen on +Retina/high-dpi capable devices. Use the SDL_WINDOW_ALLOW_HIGHDPI flag when +creating your window to enable high-dpi support. + +When high-dpi support is enabled, SDL_GetWindowSize and display mode sizes +will still be in "screen coordinates" rather than pixels, but the window will +have a much greater pixel density when the device supports it, and the +SDL_GL_GetDrawableSize or SDL_GetRendererOutputSize functions (depending on +whether raw OpenGL or the SDL_Render API is used) can be queried to determine +the size in pixels of the drawable screen framebuffer. + +Some OpenGL ES functions such as glViewport expect sizes in pixels rather than +sizes in screen coordinates. When doing 2D rendering with OpenGL ES, an +orthographic projection matrix using the size in screen coordinates +(SDL_GetWindowSize) can be used in order to display content at the same scale +no matter whether a Retina device is used or not. ============================================================================== Notes -- Application events @@ -203,7 +231,7 @@ Loading Shared Objects: Game Center ============================================================================== -Game Center integration requires that you break up your main loop in order to yield control back to the system. In other words, instead of running an endless main loop, you run each frame in a callback function, using: +Game Center integration might require that you break up your main loop in order to yield control back to the system. In other words, instead of running an endless main loop, you run each frame in a callback function, using: int SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); diff --git a/include/SDL_render.h b/include/SDL_render.h index de2749cce5193..9a033a38857b1 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -215,7 +215,7 @@ extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info); /** - * \brief Get the output size of a rendering context. + * \brief Get the output size in pixels of a rendering context. */ extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, int *w, int *h); diff --git a/include/SDL_video.h b/include/SDL_video.h index f466165b40253..e650fe9741b58 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -53,8 +53,8 @@ extern "C" { typedef struct { Uint32 format; /**< pixel format */ - int w; /**< width */ - int h; /**< height */ + int w; /**< width, in screen coordinates */ + int h; /**< height, in screen coordinates */ int refresh_rate; /**< refresh rate (or zero for unspecified) */ void *driverdata; /**< driver-specific data, initialize to 0 */ } SDL_DisplayMode; @@ -143,7 +143,9 @@ typedef enum SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1, data2 */ SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ - SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as a result of an API call or through the system or user changing the window size. */ + SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as + a result of an API call or through the + system or user changing the window size. */ SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ SDL_WINDOWEVENT_MAXIMIZED, /**< Window has been maximized */ SDL_WINDOWEVENT_RESTORED, /**< Window has been restored to normal size @@ -412,8 +414,8 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); * ::SDL_WINDOWPOS_UNDEFINED. * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or * ::SDL_WINDOWPOS_UNDEFINED. - * \param w The width of the window. - * \param h The height of the window. + * \param w The width of the window, in screen coordinates. + * \param h The height of the window, in screen coordinates. * \param flags The flags for the window, a mask of any of the following: * ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL, * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_BORDERLESS, @@ -423,6 +425,12 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); * * \return The id of the window created, or zero if window creation failed. * + * If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size + * in pixels may differ from its size in screen coordinates on platforms with + * high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize to query the + * size of the client area in screen coordinates, and SDL_GL_GetDrawableSize or + * SDL_GetRendererOutputSize to query the drawable size in pixels. + * * \sa SDL_DestroyWindow() */ extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, @@ -513,10 +521,10 @@ extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, * \brief Set the position of a window. * * \param window The window to reposition. - * \param x The x coordinate of the window, ::SDL_WINDOWPOS_CENTERED, or - ::SDL_WINDOWPOS_UNDEFINED. - * \param y The y coordinate of the window, ::SDL_WINDOWPOS_CENTERED, or - ::SDL_WINDOWPOS_UNDEFINED. + * \param x The x coordinate of the window in screen coordinates, or + * ::SDL_WINDOWPOS_CENTERED or ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y coordinate of the window in screen coordinates, or + * ::SDL_WINDOWPOS_CENTERED or ::SDL_WINDOWPOS_UNDEFINED. * * \note The window coordinate origin is the upper left of the display. * @@ -529,8 +537,10 @@ extern DECLSPEC void SDLCALL SDL_SetWindowPosition(SDL_Window * window, * \brief Get the position of a window. * * \param window The window to query. - * \param x Pointer to variable for storing the x position, may be NULL - * \param y Pointer to variable for storing the y position, may be NULL + * \param x Pointer to variable for storing the x position, in screen + * coordinates. May be NULL. + * \param y Pointer to variable for storing the y position, in screen + * coordinates. May be NULL. * * \sa SDL_SetWindowPosition() */ @@ -541,12 +551,17 @@ extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window, * \brief Set the size of a window's client area. * * \param window The window to resize. - * \param w The width of the window, must be >0 - * \param h The height of the window, must be >0 + * \param w The width of the window, in screen coordinates. Must be >0. + * \param h The height of the window, in screen coordinates. Must be >0. * * \note You can't change the size of a fullscreen window, it automatically * matches the size of the display mode. * + * The window size in screen coordinates may differ from the size in pixels, if + * the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a platform with + * high-dpi support (e.g. iOS or OS X). Use SDL_GL_GetDrawableSize or + * SDL_GetRendererOutputSize to get the real client area size in pixels. + * * \sa SDL_GetWindowSize() */ extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, @@ -556,8 +571,15 @@ extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, * \brief Get the size of a window's client area. * * \param window The window to query. - * \param w Pointer to variable for storing the width, may be NULL - * \param h Pointer to variable for storing the height, may be NULL + * \param w Pointer to variable for storing the width, in screen + * coordinates. May be NULL. + * \param h Pointer to variable for storing the height, in screen + * coordinates. May be NULL. + * + * The window size in screen coordinates may differ from the size in pixels, if + * the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a platform with + * high-dpi support (e.g. iOS or OS X). Use SDL_GL_GetDrawableSize or + * SDL_GetRendererOutputSize to get the real client area size in pixels. * * \sa SDL_SetWindowSize() */ @@ -1009,11 +1031,12 @@ extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); /** - * \brief Get the size of a window's underlying drawable (for use with glViewport). + * \brief Get the size of a window's underlying drawable in pixels (for use + * with glViewport). * * \param window Window from which the drawable size should be queried - * \param w Pointer to variable for storing the width, may be NULL - * \param h Pointer to variable for storing the height, may be NULL + * \param w Pointer to variable for storing the width in pixels, may be NULL + * \param h Pointer to variable for storing the height in pixels, may be NULL * * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a