#![warn(missing_docs)]
use core::fmt;
use core::time::Duration;
pub use glam as math;
#[cfg(feature = "ui")]
pub use egui;
pub use animation::{AnimationStates, Animator, Motion, Progress, Transition};
pub use assets::{Assets, ReliefData, ShadingData, TextureData};
pub use camera::{Camera, Lens, Projection, View};
pub use catalog::Catalog;
pub use color::Color;
pub use context::{FrameContext, InitContext, Startup, TickContext};
pub use holds::Holds;
pub use input::{
Axis2Binding, AxisBinding, ButtonAxis, ButtonAxis2, ButtonBinding, Cursor, InputAction,
InputActions, InputAxis2Action, InputAxisAction, InputButtonAction, JoystickControl, Key,
MouseButton, NoInputActions, NoInputAxes, NoInputAxes2, NoInputButtons, Pad, PadAxis,
PointerDelta, Stick, WheelDelta,
};
pub use light::{Light, MAX_LIGHTS, MAX_SHADOWS, Spot};
pub use material::Material;
pub use mesh::{Clip, Mesh, Meshes, NoClips, NoParts, Part, Slot};
pub use mirage_engine_derive::{
Catalog, Clip, InputAxis2Action, InputAxisAction, InputButtonAction, Part, Saves, ShaderValues,
};
pub use platform::Instant;
pub use post_effect::{EffectStage, PostEffect, PostEffects};
pub use ray::Ray;
pub use save::{SaveKey, SaveValue, Saves};
pub use skybox::{NoSkyboxes, SkyboxData, Skyboxes};
pub use sound::{MAX_VOICES, NoSounds, SoundCue, SoundData, Sounds};
pub use surface_style::{DrawPass, SurfaceStyle, SurfaceStyles};
pub use tonemap::Tonemap;
pub use transform::Transform;
pub use shader_values::ShaderValues;
#[doc(hidden)]
pub use post_effect::Declarations as PostEffectDeclarations;
#[doc(hidden)]
pub use shader_values::Sealed;
#[doc(hidden)]
pub use surface_style::Declarations as SurfaceStyleDeclarations;
use math::UVec2;
use renderer::{mesh_cache, shadows};
extern crate self as mirage_engine;
pub trait Game: Sized + 'static {
type Meshes: Meshes + 'static;
type Sounds: Sounds + 'static;
type InputActions: InputActions + 'static;
type SurfaceStyles: SurfaceStyles + 'static;
type Skyboxes: Skyboxes + 'static;
type PostEffects: PostEffects + 'static;
fn tick(&mut self, ctx: &mut TickContext<'_, Self>);
fn frame(&mut self, ctx: &mut FrameContext<'_, Self>);
}
pub fn run<G: Game>(
config: Config,
init: impl FnOnce(&mut InitContext<'_, G>) -> Result<G, Error> + 'static,
) {
platform::run::<G>(config, init);
}
#[derive(Clone, Debug)]
pub struct Config {
title: String,
size: UVec2,
tick_interval: Duration,
canvas_id: Option<String>,
asset_sources: Vec<String>,
antialiasing: bool,
tonemap: Tonemap,
shadow_resolution: u32,
mesh_memory: usize,
double_click_interval: Option<Duration>,
}
impl Config {
pub const DEFAULT_SIZE: UVec2 = UVec2::new(1280, 720);
pub const DEFAULT_TICK_INTERVAL: Duration = Duration::from_nanos(16_666_667);
pub fn new(title: impl Into<String>) -> Self {
Self {
title: title.into(),
size: Self::DEFAULT_SIZE,
tick_interval: Self::DEFAULT_TICK_INTERVAL,
double_click_interval: None,
canvas_id: None,
asset_sources: Vec::new(),
antialiasing: true,
tonemap: Tonemap::default(),
shadow_resolution: shadows::DEFAULT_RESOLUTION,
mesh_memory: mesh_cache::DEFAULT_MEMORY,
}
}
#[must_use]
pub fn with_assets(mut self, sources: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.asset_sources = sources.into_iter().map(Into::into).collect();
self
}
#[must_use]
pub fn with_size(mut self, width: u32, height: u32) -> Self {
self.size = UVec2::new(width, height);
self
}
#[must_use]
pub fn with_antialiasing(mut self, antialiasing: bool) -> Self {
self.antialiasing = antialiasing;
self
}
#[must_use]
pub fn with_tonemap(mut self, tonemap: Tonemap) -> Self {
self.tonemap = tonemap;
self
}
#[must_use]
pub fn with_shadow_resolution(mut self, texels: u32) -> Self {
self.shadow_resolution =
texels.clamp(shadows::SMALLEST_RESOLUTION, shadows::LARGEST_RESOLUTION);
self
}
#[must_use]
pub fn with_mesh_memory(mut self, bytes: usize) -> Self {
self.mesh_memory = bytes;
self
}
#[must_use]
pub fn with_tick_interval(mut self, interval: Duration) -> Self {
self.tick_interval = interval.max(time::MIN_TICK_INTERVAL);
self
}
#[must_use]
pub fn with_double_click_interval(mut self, interval: Duration) -> Self {
self.double_click_interval = Some(interval);
self
}
#[must_use]
pub fn with_canvas_id(mut self, id: impl Into<String>) -> Self {
self.canvas_id = Some(id.into());
self
}
pub fn title(&self) -> &str {
&self.title
}
pub fn size(&self) -> UVec2 {
self.size
}
pub fn tick_interval(&self) -> Duration {
self.tick_interval
}
pub(crate) fn double_click_interval(&self) -> Option<Duration> {
self.double_click_interval
}
pub fn canvas_id(&self) -> Option<&str> {
self.canvas_id.as_deref()
}
pub fn asset_sources(&self) -> &[String] {
&self.asset_sources
}
pub fn antialiasing(&self) -> bool {
self.antialiasing
}
pub fn tonemap(&self) -> Tonemap {
self.tonemap
}
pub fn shadow_resolution(&self) -> u32 {
self.shadow_resolution
}
pub fn mesh_memory(&self) -> usize {
self.mesh_memory
}
}
#[derive(Clone, Debug)]
pub struct Error {
msg: String,
}
impl Error {
pub fn msg(msg: impl Into<String>) -> Self {
Self { msg: msg.into() }
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.msg)
}
}
impl std::error::Error for Error {}
mod assets;
mod camera;
mod catalog;
mod color;
mod context;
mod gpu;
mod holds;
mod light;
mod material;
mod overrun;
mod platform;
mod renderer;
mod skybox;
mod time;
mod tonemap;
mod transform;
mod ui;
pub mod animation;
pub mod input;
pub mod mesh;
pub mod post_effect;
pub mod ray;
pub mod save;
pub mod shader_values;
pub mod sound;
pub mod surface_style;
#[cfg(all(feature = "offscreen", not(target_arch = "wasm32")))]
pub mod headless;
#[doc(hidden)]
pub mod doctests {
#[doc = include_str!("../README.md")]
pub mod readme {}
}
pub mod prelude {
#[cfg(feature = "ui")]
pub use crate::egui;
pub use crate::math::*;
pub use crate::mesh::{
Cube, Frame, Instance, Mesh, MeshData, Meshes, NoClips, NoParts, Plane, Quad, Sheet, Slot,
Sphere, Vertex,
};
pub use crate::{
AnimationStates, Animator, Assets, Axis2Binding, AxisBinding, ButtonAxis, ButtonAxis2,
ButtonBinding, Camera, Catalog, Clip, Color, Config, Cursor, DrawPass, EffectStage, Error,
FrameContext, Game, Holds, InitContext, InputAction, InputActions, InputAxis2Action,
InputAxisAction, InputButtonAction, Instant, JoystickControl, Key, Light, Material, Motion,
MouseButton, NoInputActions, NoInputAxes, NoInputAxes2, NoInputButtons, NoSkyboxes,
NoSounds, Pad, PadAxis, Part, PointerDelta, PostEffect, PostEffects, Progress, Projection,
Ray, ReliefData, SaveKey, SaveValue, Saves, ShaderValues, ShadingData, SkyboxData,
Skyboxes, SoundCue, SoundData, Sounds, Spot, Startup, Stick, SurfaceStyle, SurfaceStyles,
TextureData, TickContext, Tonemap, Transform, Transition, View, WheelDelta, run,
};
pub use crate::{meshes, post_effects, surface_styles};
}