Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update conf module to derive more traits and improve docs #523

Merged
merged 1 commit into from
Feb 6, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 105 additions & 86 deletions src/conf.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
//! Context creation configuration
//!
//! A [`Conf`](struct.Conf.html) struct is used to describe a hardware and platform specific setup,
//! A [`Conf`] 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
//! You can set the [`Conf::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).
//! [`miniquad::start`][super::start], but the framebuffer sizes returned by
//! [`screen_size`] will be scaled up according to the DPI scaling ratio.
//! You can also get a DPI scaling factor with the function [`dpi_scale`].
//!
//! Here's an example on a Mac with Retina display:
//! ```ignore
//! Conf {
Expand All @@ -25,115 +25,135 @@
//! };
//! ```
//!
//! 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:
//! The functions [`screen_size`] and [`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,
//! 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
//! ```
//!
//! [`dpi_scale`]: super::window::dpi_scale
//! [`screen_size`]: super::window::screen_size

#[derive(Debug)]
/// Specifies how to load an OpenGL context on X11 in Linux.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
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
/// Use `libGLX.so` (or `libGLX.so.0`) exclusively. Panics if unavailable.
GLXOnly,
/// Use libEGL.so/libEGL.so.0 and its funciton for creating OpenGL context
/// If there is no libEGL - just panic right away
/// Use `libEGL.so` (or `libEGL.so.0`) exclusively. Panics if unavailable.
EGLOnly,
/// Use libGLX and if there is not libGLX - try libEGL.
/// The default option.
/// Prefer `libGLX`; fall back to `libEGL` if `libGLX` is unavailable.
/// This is the default choice.
#[default]
GLXWithEGLFallback,
/// Use libEGL and if there is not libEGL - try libGLX.
/// Prefer `libEGL`; fall back to `libGLX` if `libEGL` is unavailable.
EGLWithGLXFallback,
}

#[derive(Debug)]
/// On Linux, the backend used for windowing and event handling.
///
/// Defaults to `X11Only`. The Wayland implementation is currently unstable
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum LinuxBackend {
/// Use only the X11 backend. Panics if unavailable. This is the default choice.
#[default]
X11Only,
/// Use only the Wayland backend. Panics if unavailable.
WaylandOnly,
/// Prefer X11, fall back to Wayland if X11 is unavailable.
X11WithWaylandFallback,
/// Prefer Wayland, fall back to X11 if Wayland is unavailable.
WaylandWithX11Fallback,
}

#[derive(Debug, PartialEq, Clone, Copy)]
/// On Apple platforms, choose the rendering API for creating contexts.
///
/// Miniquad always links to Metal.framework (assuming it's present),
/// and links to OpenGL dynamically only if required.
///
/// Defaults to AppleGfxApi::GL for legacy reasons.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum AppleGfxApi {
/// Use OpenGL for Apple platforms. This is the default choice.
#[default]
OpenGl,
/// Use Metal for Apple platforms.
Metal,
}

#[derive(Debug, PartialEq, Clone, Copy)]
/// On the Web, specify which WebGL version to use.
///
/// While miniquad itself only uses WebGL 1 features, a WebGL 2 context allows to:
/// - Use GLES3 shaders.
/// - Do raw WebGL2 OpenGL calls.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum WebGLVersion {
/// Use WebGL 1.0. This is the default choice.
#[default]
WebGL1,
/// Use WebGL 2.0.
WebGL2,
}

/// Platform specific settings.
#[derive(Debug)]
/// Platform-specific settings.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
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.
/// Determines how to load an OpenGL context on X11 (via GLX or EGL).
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.
/// Specifies which Linux window system (X11 or Wayland) is preferred or used.
pub linux_backend: LinuxBackend,

/// While miniquad itself only use webgl1 features, webgl2 context allows to:
/// - use gles3 shaders
/// - do raw webgl2 opengl calls
/// Specifies which WebGL version to use on the Web (1.0. or 2.0).
pub webgl_version: WebGLVersion,

/// 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.
/// Defines which rendering API to use on Apple platforms (Metal or OpenGL).
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!
/// Optional swap interval (vertical sync).
///
/// Note that this is highly platform- and driver-dependent.
/// There is no guarantee the FPS will match the specified `swap_interval`.
/// In other words, `swap_interval` is only a hint to the GPU driver and
/// not a reliable way to limit the game's FPS.
pub swap_interval: Option<i32>,

/// A way to reduce CPU usage to zero when waiting for an incoming event.
/// update()/draw() will only be called after `window::request_update()`.
/// It is recommended to put `request_update` at the end of `resize_event` and
/// relevant mouse/keyboard input.
/// `request_update` may be used from other threads to "wake up" the window.
/// If `true`, the event loop will block until [`schedule_update`] is called.
///
/// This can reduce CPU usage to nearly zero while waiting for events.
///
/// It is recommended to call `schedule_update` at the end of `resize_event`
/// or any relevant mouse/keyboard input.
///
/// `schedule_update` may be used from other threads to "wake up" the window.
///
/// [`schedule_update`]: super::window::schedule_update
pub blocking_event_loop: bool,

/// 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?
/// If `true`, the framebuffer includes 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,

/// Whether to draw the default window decorations on Wayland.
/// Only works when using the Wayland backend.
/// When using Wayland, this controls whether to draw the default window decorations.
pub wayland_use_fallback_decorations: bool,
}

impl Default for Platform {
fn default() -> Platform {
Platform {
linux_x11_gl: LinuxX11Gl::GLXWithEGLFallback,
linux_backend: LinuxBackend::X11Only,
apple_gfx_api: AppleGfxApi::OpenGl,
webgl_version: WebGLVersion::WebGL1,
linux_x11_gl: LinuxX11Gl::default(),
linux_backend: LinuxBackend::default(),
apple_gfx_api: AppleGfxApi::default(),
webgl_version: WebGLVersion::default(),
blocking_event_loop: false,
swap_interval: None,
framebuffer_alpha: false,
Expand All @@ -142,44 +162,43 @@ impl Default for Platform {
}
}

/// Describes a hardware and platform-specific setup.
#[derive(Debug)]
pub struct Conf {
/// Title of the window, defaults to an empty string.
/// Window title. Defaults to an empty string.
pub window_title: String,
/// The preferred width of the window, ignored on wasm/android.
///
/// Default: 800

/// Preferred window width (ignored on WASM/Android).
/// Defaults to `800`.
pub window_width: i32,
/// The preferred height of the window, ignored on wasm/android.
///
/// Default: 600

/// Preferred window height (ignored on WASM/Android).
/// Defaults to `600`.
pub window_height: i32,
/// Whether the rendering canvas is full-resolution on HighDPI displays.
///
/// Default: false

/// If `true`, the rendering canvas is scaled for HighDPI displays.
/// Defaults to `false`.
pub high_dpi: bool,
/// Whether the window should be created in fullscreen mode, ignored on wasm/android.
///
/// Default: false

/// If `true`, create the window in fullscreen mode (ignored on WASM/Android).
/// Defaults to `false`.
pub fullscreen: bool,
/// MSAA sample count
///
/// Default: 1

/// MSAA sample count.
/// Defaults to `1`.
pub sample_count: i32,

/// Determines if the application user can resize the window
/// If `true`, the 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.
/// - dock and titlebar icon on MacOs.
/// - TODO: favicon on HTML5
/// - TODO: taskbar and titlebar(highly dependent on the WM) icons on Linux
/// Optional icon data used by the OS where applicable:
/// - On Windows, taskbar/title bar icon
/// - On macOS, Dock/title bar icon
/// - TODO: Favicon on HTML5
/// - TODO: Taskbar/title bar icon on Linux (depends on WM)
pub icon: Option<Icon>,

/// Platform specific settings. Hints to OS for context creation, driver-specific
/// settings etc.
/// Platform-specific hints (e.g., context creation, driver settings).
pub platform: Platform,
}

Expand Down Expand Up @@ -237,9 +256,9 @@ impl Default for Conf {
window_width: 800,
window_height: 600,
high_dpi: true,
fullscreen: true,
fullscreen: true, //
sample_count: 1,
window_resizable: false,
window_resizable: false, //
icon: Some(Icon::miniquad_logo()),
platform: Default::default(),
}
Expand Down
Loading