# WSG — WGPU Simple Graphics Library **WSG** (WGPU Simple Graphics) est une bibliothèque Rust qui wrap [wgpu](https://github.com/gfx-rs/wgpu) et [winit](https://crates.io/crates/winit) pour dessiner en 3D **sans toucher wgpu directement**. ## Ce que vous obtenez - **Une fenêtre 3D en ~30 lignes** — pas de wgpu, pas de winit dans votre code - **Éclairage Phong** (directional, point, spot) + **ombres portées** (shadow mapping) - **HDR + Tone Mapping** (ACES Filmic / Reinhard) — opt-in, zéro coût si désactivé - **Pipeline GPU-driven** — world matrices + frustum culling sur le GPU, indirect draws - **LOD** (Level of Detail) — dégradation automatique de la géométrie selon la distance - **Primitives procédurales** — cube, sphère, cylindre, cône, tore, plan - **Import de fichiers** — parser OBJ intégré (glTF en cours) - **Caméra orbitale** + input unifié (clavier/souris) - **LOD, culling, HDR, ombres** : tout est **opt-in** — ce que vous n'activez pas ne coûte rien ## Forces | Force | Détail | |-------|--------| | **Zéro wgpu dans votre code** | L'API déclarative (`AppBuilder` + `AppHandler`) encapsule tout | | **Opt-in = zéro coût** | Un effet non activé n'alloue rien, n'exécute rien | | **Features Cargo** | Ne compilez que les primitives/import dont vous avez besoin | | **Un seul shader** | Le `standard` shader (Phong) couvre 90 % des cas ; mode unlit pour la 2D | | **GPU-driven** | Le CPU envoie des transforms, le GPU fait le reste (matrices, culling, draws) | ## Quickstart ```rust use wsg_lib::prelude::*; use wsg_lib::app::AppBuilder; use wsg_lib::utils::WsgError; struct MaScene; impl AppHandler for MaScene { fn setup(&mut self, app: &mut wsg_lib::App) { app.scene .register_shader("standard", wsg_lib::utils::STANDARD_SHADER_PATH) .unwrap(); app.scene .create_material("mat", "standard", None) .unwrap(); // Un cube lit par Phong, posé au-dessus d'un plan app.scene .create_mesh("cube", cube(1.0), Some("mat")) .unwrap(); app.scene .add_entity("my_cube", "cube") .unwrap(); app.scene .create_mesh("ground", plane(10.0, 10.0, 1, 1), Some("mat")) .unwrap(); app.scene .add_entity("floor", "ground") .unwrap(); } } fn main() -> Result<(), WsgError> { let mut app = AppBuilder::new() .title("Ma scène WSG") .with_hdr(ToneMapper::Aces) // optionnel : HDR + tone mapping .build()?; app.run(MaScene); Ok(()) } ``` ```toml [dependencies] wsg-lib = { path = "../lib" } pollster = { version = "1", features = ["macro"] } ``` ```sh cargo run --example demo # le showcase complet (6 primitives, 3 lumières, ombres, HDR) ``` ## Fonctionnalités | Catégorie | Ce qui est disponible | |-----------|----------------------| | **Géométrie** | 6 primitives procédurales + import OBJ + `Geometry` custom | | **Rendu** | Phong (lit), unlit (2D flat), HDR + tone mapping (ACES/Reinhard) | | **Lumières** | Directional, point, spot (8 max) + ambient | | **Ombres** | Shadow mapping (directional/spot), slope-scaled bias, PCF | | **LOD** | Décimation quadric auto, hystérésis, 1 buffer multi-niveaux | | **GPU-driven** | Compute pass (matrices + culling) → indirect draws | | **Caméra** | Orbitale (drag/zoom/reset) + presets (front/side/top) | | **Input** | Clavier (pressed/held/released), souris (delta, scroll, boutons) | | **Textures** | RGBA8 (de bytes, de fichier, placeholder blanc) | ## Documentation | Où | Quoi | |----|------| | [docs/user/](docs/user/README.md) | **Guide utilisateur** (EN) — comment utiliser l'API, pas à pas | | [docs/tech/](docs/tech/ARCHI_APP.md) | **Architecture interne** (FR) — décisions, specs, cibles | | [docs/ROADMAP.md](docs/ROADMAP.md) | Feuille de route (phases 1-5 ✅, phase 6 en cours) | | [docs/PLAN.md](docs/PLAN.md) | Livre de recette (historique des étapes) | | `cargo doc -p wsg-lib --no-deps` | **Référence API** (rustdoc, 100 % couvert) | ## Exemples | Exemple | Ce qu'il montre | |---------|----------------| | `demo` | Le showcase : 6 primitives, 3 lumières, ombres, HDR, LOD, caméra orbitale | | `cube` | MVP 3D : un cube lit par Phong, texture checkerboard | | `simple` | Minimal : un quad coloré en mode unlit (2D) | | `shadow_test` | Ombres portées isolées | | `spot_test` | Spotlight isolé | | `import` | Import de fichier OBJ (feature `import-obj`) | | `manual` | Workflow low-level (Context/Renderer/PipelineCache, sans App) | ## Features Cargo ```toml # Default : toutes les primitives wsg-lib = { path = "../lib" } # Minimal : juste le cube wsg-lib = { path = "../lib", default-features = false, features = ["prim-cube"] } # Avec import OBJ wsg-lib = { path = "../lib", features = ["import-obj"] } ``` | Feature | Active | |---------|--------| | `prim-cube`, `prim-plane`, `prim-sphere`, `prim-cylinder`, `prim-cone`, `prim-torus` | Primitives | | `all-prims` (default) | Les 6 primitives | | `import-obj` | Parser Wavefront OBJ | | `import-gltf` | glTF (stub) | ## Build ```sh cargo build --workspace # tout cargo test --workspace # 116 tests cargo check --all-targets # vérification rapide cargo run -p wsg-lib --example demo # lancer le showcase ``` ## Projet - **Langage** : Rust 2024 - **Dépendances** : wgpu 30, winit 0.30, glam (math) - **Pas publié sur crates.io** (dépendance par path) - **Status** : MVP complet (phases 1-5 ✅), post-MVP en cours (phase 6) --- *Documentation détaillée (architecture, status, API reference, workflow manuel) : [README_DETAILS.md](README_DETAILS.md)*