Crate frenderer

source ·
Expand description

A friendly, modular renderer built with WGPU.

Frenderer can be used in three ways (not mutually exclusive):

  1. As a collection of standalone rendering strategies for sprites, textured meshes, and flat-colored meshes.
  2. As a cross-platform wrapper over WGPU initialization and state management, offering a convenient render() function.
  3. As an application framework (with the winit feature) to give reasonable defaults for game simulation and rendering lifecycle.

The entry point for frenderer will depend on how it’s being used; for use case (1), you can initialize a WGPU struct yourself with an adapter, device, and queue, and proceed to use the built-in sprites::SpriteRenderer, meshes::MeshRenderer, meshes::FlatRenderer, or colorgeo::ColorGeo color-geometry postprocessing transform with your own renderpass. In use case (2), you can initialize a Renderer asynchronously with a given size, WGPU instance, and GPU surface, and call Renderer::render to handle all the drawing; or you can let events::Driver manage your application’s event loop and initialize frenderer at the appropriate time (with the winit feature flag). Finally, in use case (3), you’ll use clock::Clock, the extension trait in events::FrendererEvents, and the input::Input struct to simplify your game loop’s lifecycle.

frenderer is highly modular, especially in case (1); in particular, frenderer does not need to take control of the event loop from winit or exclusively own the WGPU instance, device, or adapter. For convenience, users who don’t need this modularity can employ Driver to initialize the window and a renderer. Once you have obtained a frenderer::Renderer, you can call e.g. Renderer::sprite_group_add() to set up a 2D render group and eventually call frenderer::Renderer::sprites_mut() or frenderer::Renderer::sprite_group_resize() to modify the sprite data and frenderer::Renderer::render to draw.

The 3D rendering facilities of frenderer are pretty basic at the moment, with simple perspective cameras and unlit textured or flat-colored meshes. As in the sprite renderer, the overriding performance concern has been to minimize pipeline state changes and draw calls using features like instanced rendering, storage buffers (where available), array textures, and packing multiple meshes into a single buffer.

Frenderer works in retained mode, but the “engine-immediate” example shows how an immediate-mode render API could be built on top of it.

Re-exports§

Modules§

  • Clock provides a convenience for managing a game loop’s fixed-timestep simulation tick rate according to standards set out by Glenn Fiedler and Tyler Glaiel.
  • Color and geometry postprocessing step.
  • Renderer is the main user-facing type of this crate. If you want a renderer as quickly as possible, you can use crate::Driver if you have kept the winit feature flag on. If you don’t need frenderer to initialize wgpu or windowing for you, you can instead use Renderer::with_gpu to construct a renderer with a given instance, adapter, device, and queue (wrapped in a crate::gpu::WGPU struct), dimensions, and surface. Renderer’s built-in rendering scheme uses off-screen rendering at a given resolution, then a color postprocessing step to produce output on the wgpu::Surface.
  • A wrapper for a current and previous input button/mouse state.
  • Similar to sprite groups and individual sprites, in frenderer there are mesh groups and individual meshes. Each individual mesh has some submeshes that are all grouped together (different submeshes can use different materials); meshes can have some number of instances (you set an estimate for the number of instances of each mesh when you’re adding the mesh group; it can grow at runtime but it might be costly so try to minimize the amount of growth), and the setting of instance data and uploading of instance data to the GPU are separated like they are for sprites. The only instance data is a 3D transform (translation, rotation, and a uniform scaling factor (so it fits neatly into 8 floats). Rotations are defined as quaternions.
  • A sprite renderer with multiple layers (“sprite groups”) which can be independently translated; each layer can have several spritesheets and numerous sprites. For efficiency, it’s best to minimize the number of groups.

Structs§

  • Driver takes ownership of winit’s event loop and creates a window and graphics context when possible.
  • A wrapper for a WGPU instance, surface, adapter, device, queue, and surface configuration.

Enums§

Traits§

  • This extension trait is used under the winit feature to simplify event-loop handling.

Functions§

  • If you don’t use Driver, it may still be convenient to call prepare_logging to set up env_logger or console_log appropriately for the platform.
  • If you don’t use Driver, it may still be convenient to call prepare_window to set up a window in a cross-platform way (e.g. on web, it will add the window’s canvas to the HTML document).