From e03efa28032a11111ab15b526ba23d1363d54e85 Mon Sep 17 00:00:00 2001 From: Janis Date: Sun, 19 Jan 2025 18:48:54 +0100 Subject: [PATCH] game: store window surface in game crate, store egui here tmprly --- crates/game/Cargo.toml | 2 + crates/game/src/main.rs | 147 +++++++++++++++++++++------------------- 2 files changed, 79 insertions(+), 70 deletions(-) diff --git a/crates/game/Cargo.toml b/crates/game/Cargo.toml index bce3ae4..ba2adad 100644 --- a/crates/game/Cargo.toml +++ b/crates/game/Cargo.toml @@ -9,6 +9,8 @@ tracing = { workspace = true } smol = { workspace = true } glam = { workspace = true } tracing-subscriber = { workspace = true } +rand = { workspace = true } + renderer = { path = "../renderer" } egui = { workspace = true } diff --git a/crates/game/src/main.rs b/crates/game/src/main.rs index 0ba54e3..fb360ce 100644 --- a/crates/game/src/main.rs +++ b/crates/game/src/main.rs @@ -1,6 +1,8 @@ +#![feature(result_flattening)] use std::collections::BTreeMap; -use renderer::Renderer; +use rand::{Rng, SeedableRng}; +use renderer::{render_graph, rendering::Font, swapchain::WindowSurface, Renderer2}; use tracing::info; use tracing_subscriber::EnvFilter; use winit::{ @@ -17,29 +19,34 @@ struct WindowState { egui_platform: egui_winit_platform::Platform, demo_app: egui_demo_lib::DemoWindows, scale_factor: f64, + surface: WindowSurface, } struct WinitState { last_resize_events: BTreeMap>, window_attrs: WindowAttributes, - windows2: BTreeMap, - renderer: Renderer, + windows: BTreeMap, + renderer: Renderer2, last_redraw: std::time::Instant, + egui_state: renderer::EguiState, } impl WinitState { const BASE_WIDTH: u32 = 800; const BASE_HEIGHT: u32 = 600; fn new(window_title: String, display: DisplayHandle) -> WinitState { + let renderer = Renderer2::new(display.as_raw()).expect("renderer"); + Self { - windows2: BTreeMap::new(), + windows: BTreeMap::new(), last_resize_events: BTreeMap::new(), window_attrs: WindowAttributes::default() .with_title(window_title) .with_resizable(true) .with_inner_size(LogicalSize::new(Self::BASE_WIDTH, Self::BASE_HEIGHT)), // TODO: pass down this error and add some kind of error handling UI or dump - renderer: Renderer::new(display.as_raw()).expect("renderer"), + egui_state: renderer::EguiState::new(renderer.device().clone()).unwrap(), + renderer, last_redraw: std::time::Instant::now(), } } @@ -47,12 +54,14 @@ impl WinitState { fn handle_final_resize(&mut self, window_id: WindowId, new_size: PhysicalSize) { _ = (window_id, new_size); info!("TODO: implement resize events"); - if let Some(ctx) = self.renderer.window_contexts.get_mut(&window_id) { - ctx.recreate_with(Some(renderer::Extent2D { - width: new_size.width, - height: new_size.height, - })) - .expect("swapchain recreation"); + if let Some(window) = self.windows.get(&window_id) { + window + .surface + .recreate_with(Some(renderer::Extent2D { + width: new_size.width, + height: new_size.height, + })) + .expect("swapchain recreation"); } } @@ -64,67 +73,63 @@ impl WinitState { self.last_redraw.elapsed().as_millis() ); self.last_redraw = std::time::Instant::now(); - if let Some(window) = self.windows2.get_mut(&window_id) { + if let Some(window) = self.windows.get_mut(&window_id) { // egui - window.egui_platform.begin_pass(); window.demo_app.ui(&window.egui_platform.context()); let output = window.egui_platform.end_pass(Some(&window.window)); - // self.renderer - // .draw_egui(&window.egui_platform.context(), output) - // .unwrap(); - + let textures_to_remove = output + .textures_delta + .free + .iter() + .filter_map(|id| self.egui_state.lookup_texture(*id)) + .collect::>(); // rendering + let render = self.renderer.draw_graph(&window.surface, |renderer, rg| { + use renderer::rendering::{egui_pass, egui_pre_pass}; + let framebuffer = rg.get_framebuffer().unwrap(); + let dev = renderer.device().clone(); - let textures_to_remove = smol::block_on(self.renderer.draw_with_graph( - &window_id, - || window.window.pre_present_notify(), - |renderer, rg| { - use renderer::rendering::{egui_pass, egui_pre_pass}; - let framebuffer = rg.get_framebuffer().unwrap(); - let dev = renderer.vulkan.device.clone(); + use renderer::ash::vk::Handle; + use renderer::device::DeviceOwned; + let [r, g, b]: [f32; 3] = + rand::prelude::StdRng::seed_from_u64(window.surface.surface.handle().as_raw()) + .gen(); + render_graph::clear_pass(rg, renderer::util::Rgba([r, g, b, 1.0]), framebuffer); + egui_pre_pass( + &dev, + rg, + &mut renderer.texture_manager, + &mut self.egui_state, + &output, + )?; - if let Some(font) = self.font.as_ref() { - font.pass(rg, framebuffer)?; - } + let _ = egui_pass( + &dev, + rg, + &mut renderer.texture_manager, + &mut renderer.samplers, + &mut self.egui_state, + &window.egui_platform.context(), + output, + framebuffer, + )?; - egui_pre_pass( - &dev, - rg, - &mut renderer.texture_handler, - &mut renderer.egui_state, - &output, - )?; + renderer::Result::Ok(()) + }); - let textures_to_remove = egui_pass( - &dev, - rg, - &mut renderer.texture_handler, - renderer.vulkan.samplers_mut(), - &mut renderer.egui_state, - &window.egui_platform.context(), - output, - framebuffer, - )?; - - renderer::Result::Ok(textures_to_remove) - }, - )) - .unwrap() - .unwrap(); + match smol::block_on(render).flatten() { + Ok(_) => {} + Err(e) => { + tracing::error!("encountered error while rendering: {e}"); + } + } for tid in textures_to_remove { - self.renderer.texture_handler.remove_texture(tid); + self.renderer.texture_manager_mut().remove_texture(tid); } - // self.renderer - // .debug_draw_egui(&window_id, &window.egui_platform.context(), output, || { - // window.window.pre_present_notify(); - // }) - // .inspect_err(|err| { - // tracing::error!("error encountered while drawing: {err}"); - // }) - // .expect("drawing"); + window.window.request_redraw(); } } @@ -132,8 +137,7 @@ impl WinitState { fn remove_window(&mut self, window_id: WindowId) { tracing::info!(window = u64::from(window_id), "window close requested"); - self.windows2.remove(&window_id); - self.renderer.window_contexts.remove(&window_id); + self.windows.remove(&window_id); } fn create_window(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { @@ -157,14 +161,16 @@ impl WinitState { height: size.height, }; - let _ = self.renderer.new_window_context( - extent, - window_id, - window.window_handle().expect("window handle"), - ); + let surface = self + .renderer + .create_surface( + window.window_handle().expect("window handle").as_raw(), + extent, + ) + .expect("surface"); let scale_factor = window.scale_factor(); - self.windows2.insert( + self.windows.insert( window_id, WindowState { window, @@ -178,6 +184,7 @@ impl WinitState { ..Default::default() }, ), + surface, }, ); } @@ -198,7 +205,7 @@ impl ApplicationHandler for WinitState { self.last_resize_events.clear(); - if self.windows2.is_empty() { + if self.windows.is_empty() { event_loop.exit(); } } @@ -215,7 +222,7 @@ impl ApplicationHandler for WinitState { // } // } - if let Some(window) = self.windows2.get_mut(&window_id) { + if let Some(window) = self.windows.get_mut(&window_id) { window.egui_platform.handle_event(&event); } @@ -274,7 +281,7 @@ impl ApplicationHandler for WinitState { self.handle_draw_request(window_id); } winit::event::WindowEvent::ScaleFactorChanged { scale_factor, .. } => { - if let Some(window) = self.windows2.get_mut(&window_id) { + if let Some(window) = self.windows.get_mut(&window_id) { window.scale_factor = scale_factor; } }