WSG - WGPU Simple Graphics Library
WSG is a Rust library that wraps wgpu to provide a simple, declarative API for 3D graphics. It abstracts away the complexity of managing GPU resources while exposing low-level primitives for advanced users.
NOTE : the development version is currently unstable and the examples described below may not work as expected.
What it does
WSG provides two complementary workflows:
Declarative workflow (recommended)
Register your scene's resources and entities once at startup, then let WSG handle rendering each frame via a GPU-Driven pipeline (Compute Pass → Render Pass):
use wsg_lib::{App, AppHandler};
use wsg_lib::resources::{Mesh, Material, Vertex};
struct MyGame { /* ... */ }
impl AppHandler for MyGame {
fn update(&mut self, _app: &mut App) {
// Modify scene state (transformations, entities) — only place allowed for mutations
}
fn render(&mut self, app: &mut App) {
// WSG automatically runs Compute Pass → Render Pass on the current scene.
// No manual iteration needed — draw_indexed_indirect handles everything.
}
}
#[pollster::main]
async fn main() -> Result<(), wsg_lib::utils::WsgError> {
let mut app = AppBuilder::new().build().await?;
// Declare resources (once, before the render loop)
app.cache.register_shader("basic", "assets/shaders/basic_shader.wgsl")?;
let vertices: [Vertex; 4] = [/* ... */];
let indices: [u16; 6] = [0, 1, 2, 0, 2, 3];
let mesh = Mesh::new(app.context.device(), &vertices, Some(&indices));
let material = Material::new(app.renderer.format(), "basic", &mut app.cache);
app.scene.add_mesh("quad", Arc::new(mesh))?;
app.scene.add_material("mat", Arc::new(material))?;
app.scene.add_entity("my_quad", "quad", "mat")?;
// Run the render loop — WSG handles Compute Pass + Render Pass each frame
app.run(MyGame {})
}
Manual workflow
For fine-grained control, bypass the Scene facade entirely and manipulate Context, Renderer, and PipelineCache directly through their public APIs.
Architecture overview
WSG follows a GPU-Driven two-layer architecture:
- Manager layer (Context) — owns GPU hardware lifecycle (Instance → Surface → Adapter → Device → Queue). Created once at startup.
- Executor layer (Renderer) — orchestrates a two-pass pipeline per frame: Compute Pass (World Matrix calculation + Frustum Culling → Indirect Draw Buffer) then Render Pass (
draw_indexed_indirect). Dynamic, changes each frame.
The high-level App facade ties everything together, automating window lifecycle, event processing, and frame presentation. Users implement the AppHandler trait to inject game logic.
Quick reference
| Concept | Type | Responsibility |
|---|---|---|
| App | Facade | Window lifecycle + event loop + render automation |
| AppHandler | Trait | User-defined update/render callbacks |
| Scene | Struct | Resource depot + entity graph (declarative) |
| Context | Struct | GPU hardware lifecycle (Manager) |
| Renderer | Struct | Two-pass pipeline: Compute + Render |
| Material | Struct | Shader ID → compiled RenderPipeline |
| Mesh | Struct | Persistent GPU geometry container |
| Vertex | Struct | CPU-side vertex attribute tuple |
| PipelineCache | Struct | Shader compilation cache |
| Frame | Struct | Per-frame RAII wrapper for surface texture + view |
Getting started
cargo add wsg-lib # Add the dependency
# Then build your app following the declarative example above
For details on the architecture and internal modules, see ARCHI_APP.