docs: erase DRAFT scratchpad content for next step
This commit is contained in:
-147
@@ -5,150 +5,3 @@
|
||||
> le code + README.md ; les autres docs `docs/*` restent stables.
|
||||
|
||||
---
|
||||
|
||||
# Étape : Rendu automatique de la scène + vue de frame exposée
|
||||
|
||||
## 1. Contexte (état réel au 2026-09-16)
|
||||
|
||||
- `App::run()` : acquiert `Frame` via `context.get_next_frame()`, appelle `handler.render(&mut self)`,
|
||||
puis `renderer.present(frame)`.
|
||||
- ⚠️ `handler.render()` ne reçoit **pas** la frame : le callback ne peut rien dessiner. C'est précisément
|
||||
le point bloquant signalé par `docs/PLAN.md` (§ Phase 2 intégra Scene, check-list) et `docs/ROADMAP.md`
|
||||
(point de départ : « render() ne peut pas encore dessiner — vue de frame non exposée »).
|
||||
- `Renderer::render(view, mesh, material)` existe et fonctionne (usage bas-niveau dans `manual.rs`) :
|
||||
il ouvre 1 encoder + 1 render pass par objet, dessine, soumet.
|
||||
- `Scene` a déjà : `add_mesh`, `add_material`, `add_entity`, `iter_entities() -> (label, mesh, mat)`,
|
||||
`get_mesh`, `get_material`, `remove_entity`.
|
||||
- `Material` porte déjà sa `Arc<RenderPipeline>` (compilée via `PipelineCache`). La scène stocke des
|
||||
`Arc<Material>`. Donc pour dessiner une scène, le code n'a **pas** besoin de consulter le cache :
|
||||
chaque matériau détient sa pipeline. Le « lien PipelineCache → Scene » du PLAN est donc **conceptuel**,
|
||||
pas indispensable côté rendu pour cette étape.
|
||||
|
||||
## 2. Objectif
|
||||
|
||||
1. Que `AppHandler::render()` reçoive la vue/frame courante.
|
||||
2. Que la scène se rende automatiquement (`app.render(scene)`), sans que `simple.rs` touche à wgpu.
|
||||
3. Que `simple.rs` affiche le quad (4 sommets, 6 indices, matériau `basic`), en gardant ~15 lignes.
|
||||
|
||||
## 3. Plan d'implémentation (détail, dans l'ordre)
|
||||
|
||||
### Étape 3.1 — Exposer la vue de frame au callback
|
||||
|
||||
**Fichier** : `lib/src/handler.rs` (+ `app.rs`).
|
||||
|
||||
Changer la signature :
|
||||
```rust
|
||||
fn render(&mut self, app: &mut App, frame: &Frame);
|
||||
```
|
||||
- `Frame` est un type de bibliothèque (`core::Frame`) qui expose `frame.view()` → `&wgpu::TextureView`.
|
||||
C'est plus riche et plus stable que de passer le `TextureView` brut : on garde une API bibliothèque.
|
||||
- Adapter `handler.rs` docs (consignes `docs/DOCUMENTATION.md` : backticks, description ≤3 lignes,
|
||||
ce que/qui/quand).
|
||||
|
||||
**Fichier** : `lib/src/app.rs`, dans `App::run`, branche `RedrawRequested` :
|
||||
```rust
|
||||
let frame = self.context.get_next_frame();
|
||||
handler.render(&mut self, &frame); // frame est owned (valeur locale) → pas de conflit de borrow avec &mut self
|
||||
self.renderer.present(frame);
|
||||
```
|
||||
> Point d'attention borrow : `frame` est une valeur *owned* détachée de `self.context` une fois acquise,
|
||||
> on peut donc la passer par référence en même temps que `&mut self` sans erreur du borrow checker.
|
||||
|
||||
### Étape 3.2 — Méthode de rendu de scène groupé
|
||||
|
||||
**Fichier** : `lib/src/core/renderer.rs`.
|
||||
|
||||
Le `Renderer::render(view, mesh, material)` actuel ouvre un encoder+pass **par objet** (N submits par frame
|
||||
si appelé en boucle). Pour rendre une scène entière proprement, ajouter un rendu **batch** :
|
||||
|
||||
```rust
|
||||
pub fn render_scene(&self, view: &wgpu::TextureView, scene: &Scene) {
|
||||
let mut encoder = self.device.create_command_encoder(...);
|
||||
{
|
||||
let mut pass = encoder.begin_render_pass(/* color attachment: view */);
|
||||
for (_label, mesh, material) in scene.iter_entities() {
|
||||
pass.set_pipeline(&material.pipeline);
|
||||
pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
||||
if let Some(ib) = &mesh.index_buffer {
|
||||
pass.set_index_buffer(ib.slice(..), wgpu::IndexFormat::Uint16);
|
||||
pass.draw_indexed(0..mesh.num_indices, 0, 0..1);
|
||||
} else {
|
||||
pass.draw(0..mesh.num_vertices, 0..1);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.queue.submit(once(encoder.finish()));
|
||||
}
|
||||
```
|
||||
- **Batching** : un seul pass pour toutes les entités (aligné sur le principe « batching par matériau »
|
||||
évoqué dans renderer.rs / README Phase 4.3). On évite N submits/encoder alloués à la volée.
|
||||
- Conserver `render(view, mesh, material)` (API bas-niveau utilisée par `manual.rs`). Le battle placer du code commun (layout pass / draw d'un mesh) dans un petit helper privé pour éviter la duplication.
|
||||
- Import `crate::scene::Scene`.
|
||||
- Documenter selon `docs/DOCUMENTATION.md`.
|
||||
|
||||
### Étape 3.3 — Automatisation côté App
|
||||
|
||||
**Fichier** : `lib/src/app.rs`.
|
||||
|
||||
Ajouter sur `App` :
|
||||
```rust
|
||||
pub fn render_scene(&self, view: &wgpu::TextureView) {
|
||||
self.renderer.render_scene(view, &self.scene);
|
||||
}
|
||||
```
|
||||
Le rendu automatique est branché par **défaut** dans le trait (**Option A, décidée**) :
|
||||
```rust
|
||||
fn render(&mut self, app: &mut App, frame: &Frame) {
|
||||
app.render_scene(frame.view());
|
||||
}
|
||||
```
|
||||
→ `simple.rs` **n'implémente même pas `render`** : la scène se rend toute seule, exactement l'esprit
|
||||
« scene auto-render ». L'utilisateur avancé peut surcharger `render` pour contrôler le dessin.
|
||||
|
||||
### Étape 3.4 — Remplir `simple.rs`
|
||||
|
||||
**Fichier** : `lib/examples/simple.rs`.
|
||||
|
||||
- Créer le quad (mêmes 4 sommets + 6 indices que dans `manual.rs`, mais sans toucher à wgpu : tout se fait
|
||||
via `Scene` + `AppBuilder`).
|
||||
- Enregistrer le shader : `app.cache.register_shader("basic", utils::BASIC_SHADER_PATH)`
|
||||
(le shader_id `"basic"` fonctionne déjà en fallback sur `BASIC_SHADER`, cf. `pipeline_cache.rs`).
|
||||
- Créer le matériau avec `Material::new(app.renderer.format(), "basic", &mut app.cache)`.
|
||||
- Créer le mesh avec `Mesh::new(app.renderer.device(), &vertices, Some(&indices))`.
|
||||
- Enregistrer dans `app.scene` : `add_mesh`, `add_material`, `add_entity`.
|
||||
- Tout ce remplissage se fait dans `AppHandler::update()` (ou dans `run()` avant `app.run(...)` — à voir
|
||||
selon où `app` est constructible ; le plus simple : dans `update(&mut self, app)` une fois).
|
||||
|
||||
> ⚠️ Les vertex passent par `Mesh::new(device, ...)` qui exige `wgpu::Device`. **Décision prise** : pour
|
||||
> l'étape 1, utiliser `app.renderer.device()`/`app.renderer.format()` (accès bibliothèque — l'utilisateur
|
||||
> n'importe pas wgpu). Un helper haut niveau `Scene::add_quad_entity` pourra être ajouté plus tard.
|
||||
|
||||
### Étape 3.5 — Validation
|
||||
|
||||
```bash
|
||||
cargo check --workspace
|
||||
cargo doc -p wsg-lib --no-deps # exigence : "generated 0 warnings"
|
||||
cargo run -p wsg-lib --example simple # le quad doit s'afficher
|
||||
cargo run -p wsg-lib --example manual # le workflow manuel doit rester fonctionnel
|
||||
cargo fmt --all
|
||||
```
|
||||
- Vérifier docs (`docs/DOCUMENTATION.md`) : zéro warning, backticks, chaque item public documenté.
|
||||
- Committer proprement (conventional commits, ex. `feat(app): expose frame view and auto-render scene`).
|
||||
|
||||
## 4. Décisions (actées)
|
||||
|
||||
| Sujet | Décision |
|
||||
|-------|----------|
|
||||
| Signature de `render` | Ajouter `&Frame` en paramètre (Option A : default → auto-render) |
|
||||
| Où dessiner la scène | `Renderer::render_scene(view, &Scene)` en **batch** (1 pass unique) |
|
||||
| PipelineCache dans Scene | **Non bougé pour cette étape** : les `Material` portent déjà leur pipeline ; le lien conceptuel cache↔scene est reporté |
|
||||
| wgpu dans `simple.rs` | Via `app.renderer.device()`/`format()` : l'utilisateur n'importe pas wgpu |
|
||||
| Helper quad haut niveau | Reporté (éventuel `Scene::add_quad_entity`) |
|
||||
|
||||
## 5. Notes ouvertes / idées
|
||||
|
||||
- Le "label" d'entité n'est pour l'instant pas utilisé au rendu (juste itéré). OK pour le MVP.
|
||||
- `num_indices == 0` dans le cas non indexé : bien gérer le branchement indexé/non indexé (copié depuis
|
||||
`Renderer::render` actuel).
|
||||
- Après cette étape, l'ajout de lumières/textures/caméras = simple ajout de données à la Scene
|
||||
(voir `docs/ROADMAP.md` Phases 2-4 et `docs/PLAN.md` Phase 4).
|
||||
|
||||
Reference in New Issue
Block a user