frenderer/lib.rs
1//! A friendly, modular renderer built with WGPU.
2//!
3//! Frenderer can be used in three ways (not mutually exclusive):
4//! 1. As a collection of standalone rendering strategies for sprites, textured meshes, and flat-colored meshes.
5//! 2. As a cross-platform wrapper over WGPU initialization and state management, offering a convenient `render()` function.
6//! 3. As an application framework (with the `winit` feature) to give reasonable defaults for game simulation and rendering lifecycle.
7//!
8//! The entry point for frenderer will depend on how it's being used;
9//! for use case (1), you can initialize a [`WGPU`] struct yourself
10//! with an adapter, device, and queue, and proceed to use the
11//! built-in [`sprites::SpriteRenderer`], [`meshes::MeshRenderer`],
12//! [`meshes::FlatRenderer`], or [`colorgeo::ColorGeo`] color-geometry
13//! postprocessing transform with your own renderpass. In use case
14//! (2), you can initialize a [`Renderer`] asynchronously with a given
15//! size, WGPU instance, and GPU surface, and call
16//! [`Renderer::render`] to handle all the drawing; or you can let
17//! [`events::Driver`] manage your application's event loop and
18//! initialize frenderer at the appropriate time (with the `winit`
19//! feature flag). Finally, in use case (3), you'll use
20//! [`clock::Clock`], the extension trait in
21//! [`events::FrendererEvents`], and the [`input::Input`] struct to
22//! simplify your game loop's lifecycle.
23//!
24//! frenderer is highly modular, especially in case (1); in
25//! particular, frenderer does not need to take control of the event
26//! loop from winit or exclusively own the WGPU instance, device, or
27//! adapter. For convenience, users who don't need this modularity
28//! can employ [`Driver`] to initialize the window and a
29//! renderer. Once you have obtained a [`frenderer::Renderer`], you
30//! can call e.g. [`Renderer::sprite_group_add()`] to set up a 2D
31//! render group and eventually call
32//! [`frenderer::Renderer::sprites_mut()`] or
33//! [`frenderer::Renderer::sprite_group_resize()`] to modify the
34//! sprite data and [`frenderer::Renderer::render`] to draw.
35//!
36//! The 3D rendering facilities of frenderer are pretty basic at the
37//! moment, with simple perspective cameras and unlit textured or
38//! flat-colored meshes. As in the sprite renderer, the overriding
39//! performance concern has been to minimize pipeline state changes
40//! and draw calls using features like instanced rendering, storage
41//! buffers (where available), array textures, and packing multiple
42//! meshes into a single buffer.
43//!
44//! Frenderer works in retained mode, but the "engine-immediate"
45//! example shows how an immediate-mode render API could be built on
46//! top of it.
47
48mod gpu;
49pub use gpu::WGPU;
50pub use wgpu;
51
52pub mod colorgeo;
53pub mod frenderer;
54pub mod meshes;
55pub mod sprites;
56pub use frenderer::*;
57
58fn range<R: std::ops::RangeBounds<usize>>(r: R, hi: usize) -> std::ops::Range<usize> {
59 let low = match r.start_bound() {
60 std::ops::Bound::Included(&x) => x,
61 std::ops::Bound::Excluded(&x) => x + 1,
62 std::ops::Bound::Unbounded => 0,
63 };
64 let high = match r.end_bound() {
65 std::ops::Bound::Included(&x) => x + 1,
66 std::ops::Bound::Excluded(&x) => x,
67 std::ops::Bound::Unbounded => hi,
68 };
69 low..high
70}
71
72#[cfg(feature = "winit")]
73mod events;
74#[cfg(feature = "winit")]
75pub mod input;
76#[cfg(feature = "winit")]
77pub use events::*;
78
79pub mod bitfont;
80pub mod nineslice;
81
82pub mod clock;