game: store window surface in game crate, store egui here tmprly

This commit is contained in:
Janis 2025-01-19 18:48:54 +01:00
parent 40885eb9ce
commit e03efa2803
2 changed files with 79 additions and 70 deletions

View file

@ -9,6 +9,8 @@ tracing = { workspace = true }
smol = { workspace = true } smol = { workspace = true }
glam = { workspace = true } glam = { workspace = true }
tracing-subscriber = { workspace = true } tracing-subscriber = { workspace = true }
rand = { workspace = true }
renderer = { path = "../renderer" } renderer = { path = "../renderer" }
egui = { workspace = true } egui = { workspace = true }

View file

@ -1,6 +1,8 @@
#![feature(result_flattening)]
use std::collections::BTreeMap; 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::info;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use winit::{ use winit::{
@ -17,29 +19,34 @@ struct WindowState {
egui_platform: egui_winit_platform::Platform, egui_platform: egui_winit_platform::Platform,
demo_app: egui_demo_lib::DemoWindows, demo_app: egui_demo_lib::DemoWindows,
scale_factor: f64, scale_factor: f64,
surface: WindowSurface,
} }
struct WinitState { struct WinitState {
last_resize_events: BTreeMap<WindowId, PhysicalSize<u32>>, last_resize_events: BTreeMap<WindowId, PhysicalSize<u32>>,
window_attrs: WindowAttributes, window_attrs: WindowAttributes,
windows2: BTreeMap<WindowId, WindowState>, windows: BTreeMap<WindowId, WindowState>,
renderer: Renderer<WindowId>, renderer: Renderer2,
last_redraw: std::time::Instant, last_redraw: std::time::Instant,
egui_state: renderer::EguiState,
} }
impl WinitState { impl WinitState {
const BASE_WIDTH: u32 = 800; const BASE_WIDTH: u32 = 800;
const BASE_HEIGHT: u32 = 600; const BASE_HEIGHT: u32 = 600;
fn new(window_title: String, display: DisplayHandle) -> WinitState { fn new(window_title: String, display: DisplayHandle) -> WinitState {
let renderer = Renderer2::new(display.as_raw()).expect("renderer");
Self { Self {
windows2: BTreeMap::new(), windows: BTreeMap::new(),
last_resize_events: BTreeMap::new(), last_resize_events: BTreeMap::new(),
window_attrs: WindowAttributes::default() window_attrs: WindowAttributes::default()
.with_title(window_title) .with_title(window_title)
.with_resizable(true) .with_resizable(true)
.with_inner_size(LogicalSize::new(Self::BASE_WIDTH, Self::BASE_HEIGHT)), .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 // 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(), last_redraw: std::time::Instant::now(),
} }
} }
@ -47,12 +54,14 @@ impl WinitState {
fn handle_final_resize(&mut self, window_id: WindowId, new_size: PhysicalSize<u32>) { fn handle_final_resize(&mut self, window_id: WindowId, new_size: PhysicalSize<u32>) {
_ = (window_id, new_size); _ = (window_id, new_size);
info!("TODO: implement resize events"); info!("TODO: implement resize events");
if let Some(ctx) = self.renderer.window_contexts.get_mut(&window_id) { if let Some(window) = self.windows.get(&window_id) {
ctx.recreate_with(Some(renderer::Extent2D { window
width: new_size.width, .surface
height: new_size.height, .recreate_with(Some(renderer::Extent2D {
})) width: new_size.width,
.expect("swapchain recreation"); height: new_size.height,
}))
.expect("swapchain recreation");
} }
} }
@ -64,67 +73,63 @@ impl WinitState {
self.last_redraw.elapsed().as_millis() self.last_redraw.elapsed().as_millis()
); );
self.last_redraw = std::time::Instant::now(); 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 // egui
window.egui_platform.begin_pass(); window.egui_platform.begin_pass();
window.demo_app.ui(&window.egui_platform.context()); window.demo_app.ui(&window.egui_platform.context());
let output = window.egui_platform.end_pass(Some(&window.window)); let output = window.egui_platform.end_pass(Some(&window.window));
// self.renderer let textures_to_remove = output
// .draw_egui(&window.egui_platform.context(), output) .textures_delta
// .unwrap(); .free
.iter()
.filter_map(|id| self.egui_state.lookup_texture(*id))
.collect::<Vec<_>>();
// rendering // 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( use renderer::ash::vk::Handle;
&window_id, use renderer::device::DeviceOwned;
|| window.window.pre_present_notify(), let [r, g, b]: [f32; 3] =
|renderer, rg| { rand::prelude::StdRng::seed_from_u64(window.surface.surface.handle().as_raw())
use renderer::rendering::{egui_pass, egui_pre_pass}; .gen();
let framebuffer = rg.get_framebuffer().unwrap(); render_graph::clear_pass(rg, renderer::util::Rgba([r, g, b, 1.0]), framebuffer);
let dev = renderer.vulkan.device.clone(); egui_pre_pass(
&dev,
rg,
&mut renderer.texture_manager,
&mut self.egui_state,
&output,
)?;
if let Some(font) = self.font.as_ref() { let _ = egui_pass(
font.pass(rg, framebuffer)?; &dev,
} rg,
&mut renderer.texture_manager,
&mut renderer.samplers,
&mut self.egui_state,
&window.egui_platform.context(),
output,
framebuffer,
)?;
egui_pre_pass( renderer::Result::Ok(())
&dev, });
rg,
&mut renderer.texture_handler,
&mut renderer.egui_state,
&output,
)?;
let textures_to_remove = egui_pass( match smol::block_on(render).flatten() {
&dev, Ok(_) => {}
rg, Err(e) => {
&mut renderer.texture_handler, tracing::error!("encountered error while rendering: {e}");
renderer.vulkan.samplers_mut(), }
&mut renderer.egui_state, }
&window.egui_platform.context(),
output,
framebuffer,
)?;
renderer::Result::Ok(textures_to_remove)
},
))
.unwrap()
.unwrap();
for tid in textures_to_remove { 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(); window.window.request_redraw();
} }
} }
@ -132,8 +137,7 @@ impl WinitState {
fn remove_window(&mut self, window_id: WindowId) { fn remove_window(&mut self, window_id: WindowId) {
tracing::info!(window = u64::from(window_id), "window close requested"); tracing::info!(window = u64::from(window_id), "window close requested");
self.windows2.remove(&window_id); self.windows.remove(&window_id);
self.renderer.window_contexts.remove(&window_id);
} }
fn create_window(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { fn create_window(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
@ -157,14 +161,16 @@ impl WinitState {
height: size.height, height: size.height,
}; };
let _ = self.renderer.new_window_context( let surface = self
extent, .renderer
window_id, .create_surface(
window.window_handle().expect("window handle"), window.window_handle().expect("window handle").as_raw(),
); extent,
)
.expect("surface");
let scale_factor = window.scale_factor(); let scale_factor = window.scale_factor();
self.windows2.insert( self.windows.insert(
window_id, window_id,
WindowState { WindowState {
window, window,
@ -178,6 +184,7 @@ impl WinitState {
..Default::default() ..Default::default()
}, },
), ),
surface,
}, },
); );
} }
@ -198,7 +205,7 @@ impl ApplicationHandler for WinitState {
self.last_resize_events.clear(); self.last_resize_events.clear();
if self.windows2.is_empty() { if self.windows.is_empty() {
event_loop.exit(); 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); window.egui_platform.handle_event(&event);
} }
@ -274,7 +281,7 @@ impl ApplicationHandler for WinitState {
self.handle_draw_request(window_id); self.handle_draw_request(window_id);
} }
winit::event::WindowEvent::ScaleFactorChanged { scale_factor, .. } => { 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; window.scale_factor = scale_factor;
} }
} }