This commit is contained in:
Jérôme Bousquié
2026-07-08 15:58:20 +02:00
parent 7b25564483
commit 3414d68819
4 changed files with 148 additions and 35 deletions
+78 -11
View File
@@ -1,16 +1,83 @@
# WSG - WGPU Simple Graphics Library
A simple WGPU wrapper to expose basic objects for drawing and manipulation: Meshes, Vertices, Indexes, UVs
WSG is a Rust library that wraps [wgpu](https://github.com/gfx-rs/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.
| Component | Ownership | Role |
|-----------|-----------|------|
| Instance | wgpu | The entry point. It manages connections with graphics drivers (Vulkan, Metal, DX12). |
| Surface | wgpu | The link between wgpu and your window (winit). This is where rendering is displayed. |
| Adapter | wgpu | Represents your GPU (physical or software). |
| Device | wgpu | The engine's core. It creates buffers, textures, and pipelines. |
| Queue | wgpu | The queue. You send drawing commands for execution. |
| Context | Our Lib | A logical container. wgpu doesn't have a "Context" object; we create it to group these disparate objects and simplify your user API. |
## What it does
Context (Lib) : Initializes the GPU, creates the surface, and holds the Device and Queue. It is static (created once at startup).
WSG provides two complementary workflows:
Renderer (Lib) : Uses the Device to create pipelines, manages your 500,000 vertices, and uses the Queue to send rendering instructions each frame. It is dynamic (it changes depending on what you want to display).
### Declarative workflow (recommended)
Register your scene's resources and entities before the render loop starts, then iterate them each frame:
```rust
use wsg_lib::{App, AppHandler};
use wsg_lib::resources::{Mesh, Material, Vertex};
struct MyGame { /* ... */ }
impl AppHandler for MyGame {
fn render(&mut self, app: &mut App) {
// Draw every entity registered in app.scene
for (_, mesh, material) in app.scene.iter_entities() {
app.renderer.render(app.context.get_next_frame().view(), mesh, material);
}
}
}
#[pollster::main]
async fn main() -> Result<(), wsg_lib::utils::WsgError> {
let mut app = AppBuilder::new().build().await?;
// Declare resources
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
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 two-layer architecture:
- **Manager layer (Context)** — owns GPU hardware lifecycle (Instance → Surface → Adapter → Device → Queue). Created once at startup.
- **Executor layer (Renderer)** — orchestrates draw calls per frame by binding Materials + Meshes into RenderPasses. 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 | Draw call orchestration (Executor) |
| 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
```bash
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](docs/ARCHI_APP.md).