diff --git a/Cargo.toml b/Cargo.toml index 843ad78..783b176 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ vk-mem = "0.4.0" vk-sync = "0.1.6" winit = "0.30.5" tinyvec = "1.8" +rand = "0.8.5" futures = "0.3" smol = "2.0" diff --git a/crates/game/src/main.rs b/crates/game/src/main.rs index 57e0c69..f429344 100644 --- a/crates/game/src/main.rs +++ b/crates/game/src/main.rs @@ -5,6 +5,7 @@ use tracing::info; use winit::{ application::ApplicationHandler, dpi::{LogicalSize, PhysicalSize}, + event::ElementState, event_loop::EventLoop, raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle}, window::{Window, WindowAttributes, WindowId}, @@ -14,6 +15,7 @@ struct WindowState { last_resize_events: BTreeMap>, window_attrs: WindowAttributes, window: Option, + windows: BTreeMap, renderer: Renderer, } @@ -21,6 +23,7 @@ impl WindowState { fn new(window_title: String, display: DisplayHandle) -> WindowState { Self { window: None, + windows: BTreeMap::new(), last_resize_events: BTreeMap::new(), window_attrs: WindowAttributes::default() .with_title(window_title) @@ -49,17 +52,25 @@ impl WindowState { fn handle_draw_request(&mut self, window_id: WindowId) { _ = window_id; - info!("TODO: implement draw request"); + info!( + window_id = u64::from(window_id), + "TODO: implement draw request" + ); self.renderer.debug_draw().expect("drawing"); } -} -impl ApplicationHandler for WindowState { - fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { - tracing::debug!("winit::resumed"); - self.window = - Some(event_loop.create_window(self.window_attrs.clone()).unwrap()); - let window_id = self.window.as_ref().unwrap().id(); + fn create_window( + &mut self, + event_loop: &winit::event_loop::ActiveEventLoop, + ) { + let window = event_loop + .create_window( + self.window_attrs + .clone() + .with_window_level(winit::window::WindowLevel::AlwaysOnTop), + ) + .expect("new window"); + let window_id = window.id(); tracing::info!(window = u64::from(window_id), "created new window"); let size = self @@ -75,12 +86,18 @@ impl ApplicationHandler for WindowState { let _ = self.renderer.new_window_context( extent, window_id, - self.window - .as_ref() - .unwrap() - .window_handle() - .expect("window handle"), + window.window_handle().expect("window handle"), ); + + self.windows.insert(window.id(), window); + } +} + +impl ApplicationHandler for WindowState { + fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + tracing::debug!("winit::resumed"); + + self.create_window(event_loop); } fn about_to_wait( @@ -113,7 +130,28 @@ impl ApplicationHandler for WindowState { window = u64::from(window_id), "window close requested" ); - event_loop.exit(); + + self.windows.remove(&window_id); + self.renderer.window_contexts.remove(&window_id); + + if self.windows.is_empty() { + event_loop.exit(); + } + } + winit::event::WindowEvent::KeyboardInput { + event: + winit::event::KeyEvent { + physical_key: + winit::keyboard::PhysicalKey::Code( + winit::keyboard::KeyCode::Space, + ), + state: ElementState::Pressed, + repeat: false, + .. + }, + .. + } => { + self.create_window(event_loop); } winit::event::WindowEvent::KeyboardInput { device_id, @@ -137,7 +175,7 @@ impl ApplicationHandler for WindowState { } winit::event::WindowEvent::RedrawRequested => { self.handle_draw_request(window_id); - if let Some(window) = self.window.as_ref() { + if let Some(window) = self.windows.get(&window_id) { window.request_redraw(); } } diff --git a/crates/renderer/Cargo.toml b/crates/renderer/Cargo.toml index 62257e3..6db2b27 100644 --- a/crates/renderer/Cargo.toml +++ b/crates/renderer/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] tinyvec = {workspace = true} +rand = {workspace = true} dyn-clone = "1" anyhow = "1.0.89" ash = "0.38.0" diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index d28d335..cbac9af 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -8,9 +8,15 @@ use std::{ sync::{Arc, Mutex}, }; -use ash::{khr, vk, Entry}; +use ash::{ + khr, + vk::{self, Handle}, + Entry, +}; use dyn_clone::DynClone; +use rand::{Rng, SeedableRng}; use tinyvec::{array_vec, ArrayVec}; +use tracing::info; use winit::raw_window_handle::DisplayHandle; mod commands; @@ -526,6 +532,7 @@ struct Swapchain { impl Drop for Swapchain { fn drop(&mut self) { unsafe { + info!("dropping swapchain {:?}", self.swapchain); for view in &self.image_views { self.device.device.destroy_image_view(*view, None); } @@ -1571,8 +1578,12 @@ impl Renderer { // let view = image.view(&dev, vk::ImageAspectFlags::COLOR)?; + let [r, g, b] = rand::prelude::StdRng::seed_from_u64( + ctx.surface.surface.as_raw(), + ) + .gen::<[f32; 3]>(); let clear_values = vk::ClearColorValue { - float32: [0.275, 0.769, 0.941, 1.0], + float32: [r, g, b, 1.0], }; unsafe {