![]() |
CUGL 4.0
Cornell University Game Library
|
#include <CUDisplay.h>
Public Types | |
| enum class | Orientation : unsigned int { UNKNOWN = 0 , LANDSCAPE = 1 , PORTRAIT = 2 , LANDSCAPE_REVERSED = 3 , UPSIDE_DOWN = 4 } |
| typedef std::function< void(Orientation previous, Orientation current)> | Listener |
Static Public Member Functions | |
| static bool | start (std::string title, Rect bounds, Uint32 flags) |
| static void | stop () |
| static Display * | get () |
Static Public Attributes | |
| static Uint32 | INIT_FULLSCREEN |
| static Uint32 | INIT_CENTERED |
| static Uint32 | INIT_RESIZABLE |
| static Uint32 | INIT_HIGH_DPI |
| static Uint32 | INIT_CAMERA |
| static Uint32 | INIT_VSYNC |
| static Uint32 | INIT_MULTISAMPLED |
| static Uint32 | INIT_LARGE_POINTS |
| static Uint32 | INIT_WIDE_LINES |
Protected Member Functions | |
| Display () | |
| bool | init (std::string title, Rect bounds, Uint32 flags) |
| void | dispose () |
| ~Display () | |
Protected Attributes | |
| std::string | _title |
| SDL_Window * | _window |
| SDL_DisplayID | _display |
| GraphicsContext * | _context |
| bool | _fullscreen |
| Rect | _frame |
| Rect | _drawable |
| Rect | _usable |
| float | _scale |
| Mat4 | _transform |
| bool | _notched |
| Listener | _orientationListener |
| Orientation | _initialOrientation |
| Orientation | _configOrientation |
| Orientation | _windowOrientation |
| Orientation | _deviceOrientation |
Static Protected Attributes | |
| static Display * | _thedisplay |
Friends | |
| class | Application |
This class is a singleton representing the native display.
The static methods of this class start() and stop() the SDL video system. Without it, you cannot draw anything. This should be the first and last methods called in any application. The Application class does this for you automatically.
The primary purpose of the display object is to initialize (and dispose) the graphics context. Any start-up features for your graphics system (e.g. OpenGL or Vulkan) should go in this class. They are set via the flags sent to the method start().
The singleton display object also has several methods to get the (current) screen resolution and aspect ratio. The most important of these two is the the aspect ratio. Aspect ratio is one of the most unportable parts of cross-platform development. Everything else can be scaled to the screen, but the aspect ratio is fixed from the very beginning. With that said, applications on desktop platforms may support window resizing.
The singleton display also has information about the display and device orientation for mobile devices. In fact, is is possible to assign a listener to the object to respond to changes in device orientation.
If the device has multiple displays, this singleton will only refer to the main display.
This type represents a listener for an orientation change.
In CUGL, listeners are implemented as a set of callback functions, not as objects. For simplicity, Displays only have a single listener that handles both display and device changes (see getDisplayOrientation() and getDeviceOrientation().) If you wish for more than one listener, then your listener should handle its own dispatch.
Unlike other events, this callback will be invoked at the end of an animation frame, after the screen has been drawn. So it will be processed before any input events waiting for the next frame. If you wish for more than one listener, then your listener should handle its own dispatch.
The function type is equivalent to
std::function<void(Orientation previous, Orientation current)>
| previous | The previous device orientation (before the change) |
| current | The current device orientation (after the change) |
|
strong |
The possible device/display orientations.
We use the same orientations for device and display even though these may not always agree (such as when the user has locked the display)
|
protected |
|
inlineprotected |
Deletes this object, releasing all resources.
This method quits the SDL video system and disposes the graphics context, effectively exitting and shutting down the entire program.
WARNING: This class is a singleton. You should never access this destructor directly. Use the stop() method instead.
| void cugl::Display::clear | ( | Color4f | color | ) |
Clears the screen to the given clear color.
This method should be called before any user drawing happens.
| color | The clear color |
| void cugl::Display::config | ( | ) |
Sets up the initial transform.
This helper is called by init to determine the transform.
|
protected |
Uninitializes this object, releasing all resources.
This method quits the SDL video system and disposes the graphics context, effectively exitting and shutting down the entire program.
WARNING: This class is a singleton. You should never access this method directly. Use the stop() method instead.
|
inlinestatic |
Returns the singleton instance for the display
You must call this static method first to get information about your specific display. This method will return nullptr until start() is called first.
|
inline |
Returns the display configuration orientation.
Typically, this value is the display orientation at startup. The display orientation is the orientation of the coordinate space for drawing on a mobile device. In other words, the origin is at the bottom left of the screen in this device orientation.
In some rare cases this value can change. In particular, it can change on Android devices using large screen behavior in Android 15+. Those devices cannot lock orientation, and autorotation may cause the configuration (and window size!) to change.
The display orientation may or may not agree with the device orientation.
In particular, it will not agree if the display orientation is locked (to say portrait or landscape only). However, this is the orientation that is important for drawing to the screen. To get the device orientation, call getDeviceOrientation().
|
inline |
Returns the current device orientation.
The device orientation is the orientation of a mobile device, as held by the user. It may or may not agree with the display orientation, which is how the screen is drawn. For example, if the screen is locked to landscape orientation, it is still possible for the device to have portrait orientation when it is held on its side.
This method is useful when you want to switch game modes for a different orientation (e.g. Powerpuff Girls Flipped Out).
|
inline |
Returns the current display orientation.
This value is the current display orientation. The display orientation is the orientation of the coordinate space for drawing on a mobile device. In other words, the origin is at the bottom left of the screen in this device orientation.
The display orientation may or may not agree with the device orientation.
In particular, it will not agree if the display orientation is locked (to say portrait or landscape only). However, this is the orientation that is important for drawing to the screen. To get the device orientation, call getDeviceOrientation().
|
inline |
Returns the bounds of the external frame for this display.
If the display is windowed (as opposed to fullscreen), this method will return the bounds of that window on the screen itself. For fullscreen Display objects, this will return the dimensions of the screen.
Note that the units reported by this method are often in points, not pixels. So on Retina display Apple devices, the dimensions of this frame could be half, or even a third, of the getViewBounds.
In addition, this value is reported using the screen coordinate system. In this coordinate system, the origin is often the top-right.
|
inline |
Returns the graphics context for this display.
The graphics context is an opaque type storing the information that is needed for the active graphics API (e.g. OpenGL, Vulkan, or Headless) This is only exposed for internal debugging purposes.
| const std::string cugl::Display::getGraphicsDescription | ( | ) | const |
Returns a description of the graphics API for this display.
For example, if this application is backed by OpenGL, this method returns the OpenGL version. For Vulkan, it returns the Vulkan version. If it is a headless client, it returns "Headless".
|
inline |
Returns the initial display orientation.
This value is the display orientation at startup. The display orientation is the orientation of the coordinate space for drawing on a mobile device. In other words, the origin is at the bottom left of the screen in this device orientation.
The display orientation may or may not agree with the device orientation.
In particular, it will not agree if the display orientation is locked (to say portrait or landscape only). However, this is the orientation that is important for drawing to the screen. To get the device orientation, call getDeviceOrientation().
| Vec2 cugl::Display::getMouseScreenPosition | ( | float | x, |
| float | y | ||
| ) |
Returns the screen position for the given mouse location.
This method transforms (x,y) via getTransform. A screen position is always with respect to an origin in the top-left corner.
| x | The mouse x-coordinate |
| y | The mouse y-coordinate |
| Vec2 cugl::Display::getMouseWindowPosition | ( | float | x, |
| float | y | ||
| ) |
Returns the window position for the given mouse location.
This method transforms (x,y) via getTransform. A window position is always with respect to an origin in the bottom-left corner.
| x | The mouse x-coordinate |
| y | The mouse y-coordinate |
| Orientation cugl::Display::getNaturalOrientation | ( | ) | const |
Returns the natural orientation of this device.
The natural orientation corresponds to the intended orientiation that this mobile device should be held. For devices with home buttons, this home button is always expected at the bottom. For the vast majority of devices, this means the intended orientation is Portrait. However, some Samsung tablets have the home button oriented for Landscape.
This is important because the accelerometer axis is oriented relative to the natural orientation. So a natural landscape device will have a different accelerometer orientation than a portrait device. Unfortunately, this method can have unexpected results on Android 15+ devices with large-screen behavior. If you wish to actually determine if the accelerometer axes are swapped, use hasSwappedAxes
|
inline |
Returns the listener for the display orientation.
This listener handles changes in either the device orientation (see getDeviceOrientation() or the display orientation (see getDeviceOrientation(). Since the device orientation will always change when the display orientation does, this callback can easily safely handle both. The boolean parameter in the callback indicates whether or not a display orientation change has happened as well.
Unlike other events, this listener will be invoked at the end of an animation frame, after the screen has been drawn. So it will be processed before any input events waiting for the next frame.
The display may only have one orientation listener at a time. If there is no listener, this method returns nullptr.
|
inline |
Returns the number of pixels for each point.
A point is a logical screen pixel. If you are using a traditional display, points and pixels are the same. However, on Retina displays and other high dpi monitors, they may be different. In particular, the number of pixels per point is a scaling factor times the point.
This value is defined as the ratio of getViewBounds to getFrameBounds. In practice, you should not need to use this scaling factor for anything other than determining if the high dpi setting is in use.
| float cugl::Display::getRefreshRate | ( | ) | const |
Returns the refresh rate of the display.
If the rate is unspecified, this will return 0.
|
inline |
Returns the usable bounds of this display in pixels.
Usable is a subjective term defined by the operating system. In general, it means the full screen minus any space used by important user interface elements, like a status bar (iPhone), menu bar (macOS), or task bar (Windows), or a notch (modern phones).
The value returned will always be a (potentially unproper) subrectangle of getViewBounds.
|
inline |
Returns the title of this display
On a desktop, this title will be displayed at the top of the window.
| Vec2 cugl::Display::getTouchScreenPosition | ( | float | x, |
| float | y | ||
| ) |
Returns the screen position for the given touch location.
This method converts (x,y) from normalized coordinates to pixel coordinates and then transforms the result via getTransform. A screen position is always with respect to an origin in the top-left corner.
| x | The touch x-coordinate |
| y | The touch y-coordinate |
| Vec2 cugl::Display::getTouchScreenValue | ( | float | x, |
| float | y | ||
| ) |
Returns the normalized window position for the given touch location.
This method keeps (x,y) in normalized coordinate and transforms the result via getTransform. A screen position is always with respect to an origin in the top-left corner.
| x | The touch x-coordinate |
| y | The touch y-coordinate |
| Vec2 cugl::Display::getTouchWindowPosition | ( | float | x, |
| float | y | ||
| ) |
Returns the window position for the given touch location.
This method converts (x,y) from normalized coordinates to pixel coordinates and then transforms the result via getTransform. A window position is always with respect to an origin in the bottom-left corner.
| x | The touch x-coordinate |
| y | The touch y-coordinate |
| Vec2 cugl::Display::getTouchWindowValue | ( | float | x, |
| float | y | ||
| ) |
Returns the normalized window position for the given touch location.
This method keeps (x,y) in normalized coordinate and transforms the result via getTransform. A window position is always with respect to an origin in the bottom-left corner.
| x | The touch x-coordinate |
| y | The touch y-coordinate |
|
inline |
Returns the transform for this display.
Some graphics APIs use an internal coordinate system that is rotated according to the coordinate system that we want. The returned transform should be applied AFTER apply any camera transforms to a scene before executing any drawing commands.
|
inline |
Returns the drawable bounds of this display in pixels.
This method returns the internal pixel bounds of the Display window. The origin of this rectangle will always be at (0,0), indicating the bottom left corner of the window. Note the getPixelDensity is the ratio of this size relative to the size of getFrameBounds.
|
inline |
Returns true if this device has a notch.
Notched devices are edgeless smartphones or tablets that include at dedicated area in the screen for a camera. Examples include the iPhone X.
If a device is notched you should call getSafeBounds() before laying out UI elements. It is acceptable to animate and draw backgrounds behind the notch, but it is not acceptable to place UI elements outside of these bounds.
|
inline |
Returns true if this display has an orientation listener
This listener handles changes in either the device orientation (see getDeviceOrientation() or the display orientation (see getDeviceOrientation(). Since the device orientation will always change when the display orientation does, this callback can easily safely handle both. The boolean parameter in the callback indicates whether or not a display orientation change has happened as well.
Unlike other events, this listener will be invoked at the end of an animation frame, after the screen has been drawn. So it will be processed before any input events waiting for the next frame.
The display may only have one orientation listener at a time.
| bool cugl::Display::hasSwappedAxes | ( | ) | const |
Returns true if the accelerometer axes as swapped.
By default, accelerometer axes assume that the user is holding the device in portrait mode. So the x-axis is the short edge, while the y-axis is the long edge. If this function returns true, these axes are swapped so that the x-axis is the long edge, while the y-axis is the short edge.
| void cugl::Display::hide | ( | ) |
Hides the window for this display (assuming it was visible).
This method does nothing if the window was not visible.
|
protected |
Initializes the display with the current screen information.
This method creates a display with the given title and bounds. As part of this initialization, it will create the graphics context, using the flags provided. The bounds are ignored if the display is fullscreen. In that case, it will use the bounds of the display.
This method gathers the native resolution bounds, pixel density, and orientation using platform-specific tools.
WARNING: This class is a singleton. You should never access this initializer directly. Use the start() method instead.
| title | The window/display title |
| bounds | The window/display bounds |
| flags | The initialization flags |
| bool cugl::Display::isLandscape | ( | ) | const |
Returns true if this display (not device) has a landscape orientation
| bool cugl::Display::isPortrait | ( | ) | const |
Returns true if this display (not device) has a portrait orientation
| void cugl::Display::lock | ( | ) |
Locks the display, preventing any drawing commands.
This method provides some safety with regard to shader usage.
| void cugl::Display::refresh | ( | ) |
Refreshes the display.
This method will swap the framebuffers, drawing the screen. This method should be called after any user drawing happens.
It will also reassess the orientation state and call the listener as necessary
| bool cugl::Display::removeOrientationListener | ( | ) |
Removes the display orientation listener for this display.
This listener handles changes in either the device orientation (see getDeviceOrientation() or the display orientation (see getDeviceOrientation(). Since the device orientation will always change when the display orientation does, this callback can easily safely handle both. The boolean parameter in the callback indicates whether or not a display orientation change has happened as well.
Unlike other events, this listener will be invoked at the end of an animation frame, after the screen has been drawn. So it will be processed before any input events waiting for the next frame.
A display may only have one orientation listener at a time. If this display does not have an orientation listener, this method will fail.
| void cugl::Display::resync | ( | ) |
Resynchronizes this object with the physical display.
This method is called in response to a resizing event for windows that can be resized. This may also adjust the configuration orientation.
| bool cugl::Display::setFrameBounds | ( | const Rect & | bounds | ) |
Resets the the bounds of the external frame of this display.
This method will do nothing if the display is fullscreen. Otherwise, it will attempt to resize the window to the given dimensions. Not that the units used by this method are often in points, not pixels. So on Retina display Apple devices, the dimensions of this frame could be half, or even a third, of the getViewBounds.
In addition, the bounds are specified using the screen coordinate system. In this coordinate system, the origin is often the top-right.
| bounds | The new frame bounds |
|
inline |
Repositions the external frame of this display
This method will do nothing if the display is fullscreen. Otherwise, it will attempt to reposition the window to the given coordinates. Note that the units used by this method are often in points, not pixels. So on Retina display Apple devices, the dimensions of this frame could be half, or even a third, of the getViewBounds. In addition, in the screen coordinate system, the origin is often the top-right.
| origin | The frame origin |
| bool cugl::Display::setFrameOrigin | ( | Uint32 | x, |
| Uint32 | y | ||
| ) |
Repositions the external frame of this display
This method will do nothing if the display is fullscreen. Otherwise, it will attempt to reposition the window to the given coordinates. Note that the units used by this method are often in points, not pixels. So on Retina display Apple devices, the dimensions of this frame could be half, or even a third, of the getViewBounds. In addition, in the screen coordinate system, the origin is often the top-right.
| x | The x-coordinate of the frame |
| y | The x-coordinate of the frame |
|
inline |
Resizes the external frame of this display.
This method will do nothing if the display is fullscreen. Otherwise, it will attempt to resize the window to the given dimensions. Not that the units used by this method are often in points, not pixels. So on Retina display Apple devices, the dimensions of this frame could be half, or even a third, of the getViewBounds.
| size | The new frame size |
| bool cugl::Display::setFrameSize | ( | Uint32 | width, |
| Uint32 | height | ||
| ) |
Resizes the external frame of this display.
This method will do nothing if the display is fullscreen. Otherwise, it will attempt to resize the window to the given dimensions. Not that the units used by this method are often in points, not pixels. So on Retina display Apple devices, the dimensions of this frame could be half, or even a third, of the getViewBounds.
| width | The new frame width |
| height | The new frame height |
|
inline |
Sets the orientation listener for this display.
This listener handles changes in either the device orientation (see getDeviceOrientation() or the display orientation (see getDeviceOrientation(). Since the device orientation will always change when the display orientation does, this callback can easily safely handle both. The boolean parameter in the callback indicates whether or not a display orientation change has happened as well.
A display may only have one orientation listener at a time. If this display already has an orientation listener, this method will replace it for the once specified.
Unlike other events, this listener will be invoked at the end of an animation frame, after the screen has been drawn. So it will be processed before any input events waiting for the next frame.
| listener | The listener to use |
| void cugl::Display::setTitle | ( | const std::string | title | ) |
Sets the title of this display
On a desktop, the title will be displayed at the top of the window.
| title | The title of this display |
| void cugl::Display::show | ( | ) |
Shows the window for this display (assuming it was hidden).
This method does nothing if the window was not hidden.
|
static |
Starts up the SDL display and video system.
This static method needs to be the first line of any application, though it is handled automatically in the Application class.
This method creates the display with the given title and bounds. As part of this initialization, it will create the graphics context, using the flags provided. The bounds are ignored if the display is fullscreen. In that case, it will use the bounds of the display.
Once this method is called, the get() method will no longer return a null value.
| title | The window/display title |
| bounds | The window/display bounds |
| flags | The initialization flags |
| bool cugl::Display::startTextEvents | ( | ) |
Enable text events on the given display.
The method is used by TextInput to activate text input events. On devices without keyboards, calling this method will typically create a virtual keyboard on the display. You can dismiss it by calling stopTextEvents
|
static |
Shuts down the SDL display and video system.
This static method needs to be the last line of any application, though it is handled automatically in the Application class. It will dipose of the display and the graphics context.
Once this method is called, the get() method will return nullptr. More importantly, no SDL function calls will work anymore.
| bool cugl::Display::stopTextEvents | ( | ) |
Disables text events on the given display.
The method is used by TextInput to deactivate text input events. If startTextEvents created a virtual keyboard, this method will dismiss it.
| void cugl::Display::unlock | ( | ) |
Unlocks the display, allowing drawing commands to proceed
This method provides some safety with regard to shader usage.
|
friend |
This is called by the application loop
|
protected |
The value of the configuration orientation
|
protected |
The associated graphics context
|
protected |
The value of the device orientation
|
protected |
The display index (for multiscreen displays)
|
protected |
The drawable bounds in pixels
|
protected |
The bounds for this display with respect to the device
|
protected |
Whether we are using full screen
|
protected |
The value of the initial orientation
|
protected |
Whether this device has a notch in it
|
protected |
A listener for the orientation
|
protected |
The pixel density of the device
This value is the ratio of the display size to the drawable size.
|
staticprotected |
The display singleton
|
protected |
The title (Window name) of the display
|
protected |
A pre-transform to fix orientation issues on Android
|
protected |
The safe area bounds in pixels
The safe area consist of the drawing area minus regions that should not be drawn over, like notches, menu bars, and home regions.
|
protected |
The SDL window, which provides the OpenGL drawing context
|
protected |
The value of the display orientation
|
static |
Whether this display should support the camera (EXPERIMENTAL)
|
static |
Whether this display should be centered (on windowed screens)
|
static |
Whether this display should use the fullscreen
|
static |
Whether this display should support a High DPI screen
|
static |
Whether to support points larger than one pixel (Vulkan only)
|
static |
Whether this display should be multisampled
|
static |
Whether this display resizable (incompatible with full screen)
|
static |
Whether this display should have VSync enabled
|
static |
Whether to support points lines wider than one pixel (Vulkan only)