suppression contradictions
This commit is contained in:
@@ -11,7 +11,7 @@ WSG provides two complementary workflows:
|
||||
|
||||
### Declarative workflow (recommended)
|
||||
|
||||
Register your scene's resources and entities before the render loop starts, then iterate them each frame:
|
||||
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):
|
||||
|
||||
```rust
|
||||
use wsg_lib::{App, AppHandler};
|
||||
@@ -20,11 +20,13 @@ 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) {
|
||||
// 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);
|
||||
}
|
||||
// WSG automatically runs Compute Pass → Render Pass on the current scene.
|
||||
// No manual iteration needed — draw_indexed_indirect handles everything.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +34,7 @@ impl AppHandler for MyGame {
|
||||
async fn main() -> Result<(), wsg_lib::utils::WsgError> {
|
||||
let mut app = AppBuilder::new().build().await?;
|
||||
|
||||
// Declare resources
|
||||
// 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];
|
||||
@@ -43,7 +45,7 @@ async fn main() -> Result<(), wsg_lib::utils::WsgError> {
|
||||
app.scene.add_material("mat", Arc::new(material))?;
|
||||
app.scene.add_entity("my_quad", "quad", "mat")?;
|
||||
|
||||
// Run the render loop
|
||||
// Run the render loop — WSG handles Compute Pass + Render Pass each frame
|
||||
app.run(MyGame {})
|
||||
}
|
||||
```
|
||||
@@ -54,10 +56,10 @@ For fine-grained control, bypass the Scene facade entirely and manipulate Contex
|
||||
|
||||
## Architecture overview
|
||||
|
||||
WSG follows a two-layer architecture:
|
||||
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 draw calls per frame by binding Materials + Meshes into RenderPasses. Dynamic, changes each frame.
|
||||
- **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.
|
||||
|
||||
@@ -69,7 +71,7 @@ The high-level `App` facade ties everything together, automating window lifecycl
|
||||
| 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) |
|
||||
| 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 |
|
||||
|
||||
@@ -210,7 +210,9 @@ impl ResourceManager {
|
||||
4. Accès pendant la mise à jour : Pendant la phase de mise à jour (update()), vous pouvez utiliser get_mut() si des modifications sont nécessaires. Soyez vigilant à la gestion des lifetimes et de la mutabilité.
|
||||
5. Validation : Avant d'utiliser un Handle potentiellement ancien ou incertain, vérifiez sa validité avec contains_* si l'opération n'est pas critique, ou laissez get() renvoyer None si le Handle est invalide.
|
||||
6. Suppression Dynamique : Bien que possible, la suppression de ressources pendant la boucle de rendu doit être faite avec prudence. Assurez-vous que les entités ou objets qui référençaient cette ressource soient informés ou nettoyés pour éviter d'utiliser des Handles invalides. La suppression est souvent mieux gérée en fin de frame ou via un système de "marquage pour suppression" suivi d'un nettoyage différé.
|
||||
7. Futur : SecondaryMaps : slotmap permet d'utiliser des SecondaryMap pour associer dynamiquement des données à des ressources existantes sans modifier leur structure principale. Par exemple, SecondaryMap<MeshId, Transform> pourrait stocker les transformations actuelles de chaque maillage. Cela peut être utile pour le rendu ou pour des systèmes de physique/transformation indépendants.
|
||||
7. Futur : SecondaryMaps : slotmap permet d'utiliser des SecondaryMap pour associer dynamiquement des données à des ressources existantes sans modifier leur structure principale. Par exemple, `SecondaryMap<MeshId, Transform>` pourrait stocker les transformations actuelles de chaque maillage. Cela peut être utile pour le rendu ou pour des systèmes de physique/transformation indépendants.
|
||||
|
||||
> **Note sur les Transforms côté GPU** : `SecondaryMap<MeshId, Transform>` est une suggestion d'approche générale. Si le modèle le plus performant pour votre cas d'usage est plutôt un vecteur/plat de Transforms (`Vec<Transform>`) alimentant un Storage Buffer CPU → GPU (comme décrit dans [ARCHI_CPU_GPU](ARCHI_CPU_GPU)), alors c'est cette approche qu'il faut adopter. Comme toutes les ressources sont créées avant le début de la boucle de rendu, vous pouvez décider à ce moment-là du meilleur modèle de stockage — en fonction du volume de meshes et de la fréquence de mise à jour des transforms.
|
||||
|
||||
# Avantages de cette Approche
|
||||
|
||||
|
||||
Reference in New Issue
Block a user