multi-window

This commit is contained in:
Janis 2024-12-15 02:49:44 +01:00
parent ee995bbd01
commit 99c86c0c85
4 changed files with 68 additions and 17 deletions

View file

@ -19,6 +19,7 @@ vk-mem = "0.4.0"
vk-sync = "0.1.6" vk-sync = "0.1.6"
winit = "0.30.5" winit = "0.30.5"
tinyvec = "1.8" tinyvec = "1.8"
rand = "0.8.5"
futures = "0.3" futures = "0.3"
smol = "2.0" smol = "2.0"

View file

@ -5,6 +5,7 @@ use tracing::info;
use winit::{ use winit::{
application::ApplicationHandler, application::ApplicationHandler,
dpi::{LogicalSize, PhysicalSize}, dpi::{LogicalSize, PhysicalSize},
event::ElementState,
event_loop::EventLoop, event_loop::EventLoop,
raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle}, raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle},
window::{Window, WindowAttributes, WindowId}, window::{Window, WindowAttributes, WindowId},
@ -14,6 +15,7 @@ struct WindowState {
last_resize_events: BTreeMap<WindowId, PhysicalSize<u32>>, last_resize_events: BTreeMap<WindowId, PhysicalSize<u32>>,
window_attrs: WindowAttributes, window_attrs: WindowAttributes,
window: Option<Window>, window: Option<Window>,
windows: BTreeMap<WindowId, Window>,
renderer: Renderer, renderer: Renderer,
} }
@ -21,6 +23,7 @@ impl WindowState {
fn new(window_title: String, display: DisplayHandle) -> WindowState { fn new(window_title: String, display: DisplayHandle) -> WindowState {
Self { Self {
window: None, window: None,
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)
@ -49,17 +52,25 @@ impl WindowState {
fn handle_draw_request(&mut self, window_id: WindowId) { fn handle_draw_request(&mut self, window_id: WindowId) {
_ = window_id; _ = window_id;
info!("TODO: implement draw request"); info!(
window_id = u64::from(window_id),
"TODO: implement draw request"
);
self.renderer.debug_draw().expect("drawing"); self.renderer.debug_draw().expect("drawing");
} }
}
impl ApplicationHandler for WindowState { fn create_window(
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { &mut self,
tracing::debug!("winit::resumed"); event_loop: &winit::event_loop::ActiveEventLoop,
self.window = ) {
Some(event_loop.create_window(self.window_attrs.clone()).unwrap()); let window = event_loop
let window_id = self.window.as_ref().unwrap().id(); .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"); tracing::info!(window = u64::from(window_id), "created new window");
let size = self let size = self
@ -75,12 +86,18 @@ impl ApplicationHandler for WindowState {
let _ = self.renderer.new_window_context( let _ = self.renderer.new_window_context(
extent, extent,
window_id, window_id,
self.window window.window_handle().expect("window handle"),
.as_ref()
.unwrap()
.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( fn about_to_wait(
@ -113,7 +130,28 @@ impl ApplicationHandler for WindowState {
window = u64::from(window_id), window = u64::from(window_id),
"window close requested" "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 { winit::event::WindowEvent::KeyboardInput {
device_id, device_id,
@ -137,7 +175,7 @@ impl ApplicationHandler for WindowState {
} }
winit::event::WindowEvent::RedrawRequested => { winit::event::WindowEvent::RedrawRequested => {
self.handle_draw_request(window_id); 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(); window.request_redraw();
} }
} }

View file

@ -5,6 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
tinyvec = {workspace = true} tinyvec = {workspace = true}
rand = {workspace = true}
dyn-clone = "1" dyn-clone = "1"
anyhow = "1.0.89" anyhow = "1.0.89"
ash = "0.38.0" ash = "0.38.0"

View file

@ -8,9 +8,15 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use ash::{khr, vk, Entry}; use ash::{
khr,
vk::{self, Handle},
Entry,
};
use dyn_clone::DynClone; use dyn_clone::DynClone;
use rand::{Rng, SeedableRng};
use tinyvec::{array_vec, ArrayVec}; use tinyvec::{array_vec, ArrayVec};
use tracing::info;
use winit::raw_window_handle::DisplayHandle; use winit::raw_window_handle::DisplayHandle;
mod commands; mod commands;
@ -526,6 +532,7 @@ struct Swapchain {
impl Drop for Swapchain { impl Drop for Swapchain {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
info!("dropping swapchain {:?}", self.swapchain);
for view in &self.image_views { for view in &self.image_views {
self.device.device.destroy_image_view(*view, None); self.device.device.destroy_image_view(*view, None);
} }
@ -1571,8 +1578,12 @@ impl Renderer {
// let view = image.view(&dev, vk::ImageAspectFlags::COLOR)?; // 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 { let clear_values = vk::ClearColorValue {
float32: [0.275, 0.769, 0.941, 1.0], float32: [r, g, b, 1.0],
}; };
unsafe { unsafe {