feat(core): Étape 11 — resize (surface + depth, Phase 4.4)
This commit is contained in:
@@ -135,6 +135,29 @@ impl App {
|
||||
let aspect = size.width as f32 / size.height.max(1) as f32;
|
||||
self.renderer().render_scene(view, &self.scene, aspect);
|
||||
}
|
||||
|
||||
/// Resizes the surface and depth texture to a new window size (ROADMAP Phase 4.4).
|
||||
/// Reconfigures the surface via `Context::configure` (which returns the chosen format) and
|
||||
/// recreates the depth texture via `Renderer::resize_depth` so the color and depth attachments
|
||||
/// stay the same size. If the surface format changes (rare, deterministic per window), the
|
||||
/// Scene's GPU context is re-initialized to the new format; otherwise the swap alone suffices.
|
||||
/// Inputs: width/height — the new surface dimensions in pixels.
|
||||
/// Returns Ok(()) on success or a `WsgError` if the surface cannot be reconfigured.
|
||||
pub fn resize(&mut self, width: u32, height: u32) -> Result<(), WsgError> {
|
||||
let context = self.context.as_ref().ok_or(WsgError::SurfaceIncompatible)?;
|
||||
let old_format = self.renderer().format();
|
||||
let new_format = context.configure(&context.adapter, width, height)?;
|
||||
self.renderer_mut().resize_depth(width, height);
|
||||
self.renderer_mut().set_format(new_format);
|
||||
if new_format != old_format {
|
||||
// Surface format changed: re-wire the Scene's GPU context (device + queue + format)
|
||||
// so its PipelineCache/pipelines match the new surface format.
|
||||
let device = std::sync::Arc::new(self.renderer_mut().device().clone());
|
||||
self.scene
|
||||
.init_gpu(device, self.context().queue.clone(), new_format);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder for constructing a configured `App` instance with custom title and dimensions.
|
||||
@@ -277,7 +300,25 @@ impl<H: AppHandler> ApplicationHandler for AppRunner<H> {
|
||||
return;
|
||||
};
|
||||
match event {
|
||||
WindowEvent::Resized(size) => {
|
||||
// Garde (D3) : minimiser la fenêtre envoie Resized(0x0) ; ne jamais reconfigurer à 0.
|
||||
let w = size.width as u32;
|
||||
let h = size.height as u32;
|
||||
if w == 0 || h == 0 {
|
||||
return;
|
||||
}
|
||||
// Étape 11 : reconfigurer surface + depth à la nouvelle taille, puis re-rendre.
|
||||
if let Err(e) = app.resize(w, h) {
|
||||
eprintln!("WSG : erreur de resize ({e:?})");
|
||||
}
|
||||
app.window().request_redraw();
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
// Garde (D6) : ne pas rendre sur une surface de taille nulle (fenêtre minimisée).
|
||||
let size = app.window().inner_size();
|
||||
if size.width == 0 || size.height == 0 {
|
||||
return;
|
||||
}
|
||||
// Rendering logic
|
||||
let frame = app.context().get_next_frame();
|
||||
|
||||
|
||||
@@ -167,6 +167,23 @@ impl Renderer {
|
||||
self.write_default_frame_uniforms();
|
||||
}
|
||||
|
||||
/// Recreates the depth texture at a new size, used on window resize (ROADMAP Phase 4.4).
|
||||
/// The previous depth texture is dropped when its field is replaced — no leak, no double
|
||||
/// allocation. The helper `create_depth_texture` (Étape 9, D3) is reused so the recreate stays
|
||||
/// trivial. Inputs: width/height — the new surface dimensions in pixels.
|
||||
pub fn resize_depth(&mut self, width: u32, height: u32) {
|
||||
let (depth_texture, depth_view) = create_depth_texture(&self.device, width, height);
|
||||
self._depth_texture = depth_texture;
|
||||
self.depth_view = depth_view;
|
||||
}
|
||||
|
||||
/// Updates the stored surface texture format after a surface reconfigure (ROADMAP Phase 4.4).
|
||||
/// Used when `Context::configure` returns a different format so the Renderer stays in sync
|
||||
/// with the surface. Inputs: format — the new surface texture format.
|
||||
pub fn set_format(&mut self, format: wgpu::TextureFormat) {
|
||||
self.format = format;
|
||||
}
|
||||
|
||||
/// Rewrites the shared per-frame uniform buffer from the scene's active camera and the current
|
||||
/// viewport aspect, then returns the frame bind group wired to that buffer. Called at the start of
|
||||
/// every `render_scene` so the GPU sees the latest camera matrices and camera position (Étape 4.3).
|
||||
|
||||
Reference in New Issue
Block a user