1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
//! Context creation configuration
//!
//! A [`Conf`](struct.Conf.html) struct is used to describe a hardware and platform specific setup,
//! mostly video display settings.
//!
//! ## High DPI rendering
//!
//! You can set the [`Conf::high_dpi`](struct.Conf.html#structfield.high_dpi) flag during initialization to request
//! a full-resolution framebuffer on HighDPI displays. The default behaviour
//! is `high_dpi = false`, this means that the application will
//! render to a lower-resolution framebuffer on HighDPI displays and the
//! rendered content will be upscaled by the window system composer.
//! In a HighDPI scenario, you still request the same window size during
//! [`miniquad::start`](../fn.start.html), but the framebuffer sizes returned by [`Context::screen_size`](../graphics/struct.Context.html#method.screen_size)
//! will be scaled up according to the DPI scaling ratio.
//! You can also get a DPI scaling factor with the function
//! [`Context::dpi_scale`](../graphics/struct.Context.html#method.dpi_scale).
//! Here's an example on a Mac with Retina display:
//! ```ignore
//! Conf {
//! width = 640,
//! height = 480,
//! high_dpi = true,
//! .. Default::default()
//! };
//! ```
//!
//! The functions [`screen_size`](../graphics/struct.Context.html#method.screen_size) and [`dpi_scale`](../graphics/struct.Context.html#method.dpi_scale) will
//! return the following values:
//! ```bash
//! screen_size -> (1280, 960)
//! dpi_scale -> 2.0
//! ```
//!
//! If the high_dpi flag is false, or you're not running on a Retina display,
//! the values would be:
//! ```bash
//! screen_size -> (640, 480)
//! dpi_scale -> 1.0
//! ```
#[derive(Debug)]
pub enum LinuxX11Gl {
/// Use libGLX.so/libGLX.so.0 and its funciton for creating OpenGL context
/// If there is no libGLX - just panic right away
GLXOnly,
/// Use libEGL.so/libEGL.so.0 and its funciton for creating OpenGL context
/// If there is no libEGL - just panic right away
EGLOnly,
/// Use libGLX and if there is not libGLX - try libEGL.
/// The default option.
GLXWithEGLFallback,
/// Use libEGL and if there is not libEGL - try libGLX.
EGLWithGLXFallback,
}
#[derive(Debug)]
pub enum LinuxBackend {
X11Only,
WaylandOnly,
X11WithWaylandFallback,
WaylandWithX11Fallback,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum AppleGfxApi {
OpenGl,
Metal,
}
/// Platform specific settings.
#[derive(Debug)]
pub struct Platform {
/// On X11 there are two ways to get OpenGl context: libglx.so and libegl.so
/// Default is GLXWithEGLFallback - will try to create glx context and if fails -
/// try EGL. If EGL also fails - panic.
pub linux_x11_gl: LinuxX11Gl,
/// Wayland or X11. Defaults to X11WithWaylandFallback - miniquad will try
/// to load "libX11.so", but if there is no - will try to initialize
/// through wayland natively. If both fails (no graphics server at
/// all, like KMS) - will panic.
///
/// Defaults to X11Only. Wayland implementation is way too unstable right now.
pub linux_backend: LinuxBackend,
/// Which rendering context to create, Metal or OpenGL.
/// Miniquad always links with Metal.framework (assuming it is always present)
/// but it links with OpenGL dynamically and only if required.
///
/// Defaults to AppleGfxApi::GL for legacy reasons.
pub apple_gfx_api: AppleGfxApi,
/// On some platform it is possible to ask the OS for a specific swap interval.
/// Note that this is highly platform and implementation dependent,
/// there is no guarantee that FPS will be equal to swap_interval.
/// In other words - "swap_interval" is a hint for a GPU driver, this is not
/// the way to limit FPS in the game!
pub swap_interval: Option<i32>,
/// Whether the framebuffer should have an alpha channel.
/// Currently supported only on Android
/// TODO: Make it works on web, on web it should make a transparent HTML5 canvas
/// TODO: Document(and check) what does it actually mean on android. Transparent window?
pub framebuffer_alpha: bool,
}
impl Default for Platform {
fn default() -> Platform {
Platform {
linux_x11_gl: LinuxX11Gl::GLXWithEGLFallback,
swap_interval: None,
linux_backend: LinuxBackend::X11Only,
apple_gfx_api: AppleGfxApi::OpenGl,
framebuffer_alpha: false,
}
}
}
#[derive(Debug)]
pub struct Conf {
/// Title of the window, defaults to an empty string.
pub window_title: String,
/// The preferred width of the window, ignored on wasm/android.
///
/// Default: 800
pub window_width: i32,
/// The preferred height of the window, ignored on wasm/android.
///
/// Default: 600
pub window_height: i32,
/// Whether the rendering canvas is full-resolution on HighDPI displays.
///
/// Default: false
pub high_dpi: bool,
/// Whether the window should be created in fullscreen mode, ignored on wasm/android.
///
/// Default: false
pub fullscreen: bool,
/// MSAA sample count
///
/// Default: 1
pub sample_count: i32,
/// Determines if the application user can resize the window
pub window_resizable: bool,
/// Miniquad allows to change the window icon programmatically.
/// The icon will be used as
/// - taskbar and titlebar icons on Windows.
/// - TODO: favicon on HTML5
/// - TODO: taskbar and titlebar(highly dependent on the WM) icons on Linux
/// - TODO: dock and titlebar icon on MacOs
pub icon: Option<Icon>,
/// Platform specific settings. Hints to OS for context creation, driver-specific
/// settings etc.
pub platform: Platform,
}
/// Icon image in three levels of detail.
#[derive(Clone)]
pub struct Icon {
/// 16 * 16 image of RGBA pixels (each 4 * u8) in row-major order.
pub small: [u8; 16 * 16 * 4],
/// 32 x 32 image of RGBA pixels (each 4 * u8) in row-major order.
pub medium: [u8; 32 * 32 * 4],
/// 64 x 64 image of RGBA pixels (each 4 * u8) in row-major order.
pub big: [u8; 64 * 64 * 4],
}
impl Icon {
pub fn miniquad_logo() -> Icon {
Icon {
small: crate::default_icon::SMALL,
medium: crate::default_icon::MEDIUM,
big: crate::default_icon::BIG,
}
}
}
// Printing 64x64 array with a default formatter is not meaningfull,
// so debug will skip the data fields of an Icon
impl std::fmt::Debug for Icon {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Icon").finish()
}
}
// reasonable defaults for PC and mobiles are slightly different
#[cfg(not(target_os = "android"))]
impl Default for Conf {
fn default() -> Conf {
Conf {
window_title: "".to_owned(),
window_width: 800,
window_height: 600,
high_dpi: false,
fullscreen: false,
sample_count: 1,
window_resizable: true,
icon: Some(Icon::miniquad_logo()),
platform: Default::default(),
}
}
}
#[cfg(target_os = "android")]
impl Default for Conf {
fn default() -> Conf {
Conf {
window_title: "".to_owned(),
window_width: 800,
window_height: 600,
high_dpi: true,
fullscreen: true,
sample_count: 1,
window_resizable: false,
icon: Some(Icon::miniquad_logo()),
platform: Default::default(),
}
}
}