diff --git a/Cargo.lock b/Cargo.lock index 18d8023..6c2f356 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1268,6 +1268,7 @@ dependencies = [ "lz4_flex", "ndk 0.8.0", "nohash-hasher", + "pollster", "postcard", "rand", "raw-window-handle", @@ -1843,6 +1844,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + [[package]] name = "postcard" version = "1.0.8" diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 20dd548..057fcc7 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -15,6 +15,7 @@ hui = { version = "0.1.0-alpha.4", git = "https://github.com/griffi-gh/hui", rev hui-winit = { version = "0.1.0-alpha.4", git = "https://github.com/griffi-gh/hui", rev = "dd5af8b9e2" } log = "0.4" wgpu = { version = "0.20", features = ["webgl"] } +pollster = "0.3" winit = { version = "0.30", features = ["android-native-activity"] } raw-window-handle = "0.6" glam = { version = "0.27", features = ["debug-glam-assert", "fast-math"] } @@ -36,6 +37,7 @@ serde_json = { version = "1.0", optional = true } #only used for `generate_visua rand = { version = "0.8", features = ["alloc", "small_rng"]} atomic = "0.6" + [target.'cfg(target_os = "android")'.dependencies] android-activity = "^0.5.2" ndk = "0.8" diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index 1a393cc..1da5fd0 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -1,3 +1,4 @@ +use pollster::FutureExt; use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, AllStoragesView}; use winit::{ event_loop::ActiveEventLoop, @@ -19,18 +20,27 @@ pub struct BackgroundColor(pub Vec3); #[derive(Unique, Clone, Copy)] #[repr(transparent)] +#[deprecated = "use Renderer.size instead"] +#[allow(deprecated)] pub struct WindowSize(pub UVec2); #[derive(Unique)] pub struct Renderer { pub window: Window, + pub instance: wgpu::Instance, + pub surface: wgpu::Surface<'static>, + pub device: wgpu::Device, + pub queue: wgpu::Queue, + pub surface_config: wgpu::SurfaceConfiguration, + pub size: PhysicalSize, + // pub depth_texture: wgpu::Texture, } impl Renderer { pub fn init(event_loop: &ActiveEventLoop, settings: &GameSettings) -> Self { log::info!("initializing display"); - let wb = WindowAttributes::new() + let window_attributes = Window::default_attributes() .with_title("kubi") .with_maximized(true) .with_min_inner_size(PhysicalSize::new(640, 480)) @@ -44,6 +54,7 @@ impl Renderer { let monitor = event_loop.primary_monitor().or_else(|| { event_loop.available_monitors().next() }); + if let Some(monitor) = monitor { log::info!("monitor: {}", monitor.name().unwrap_or_else(|| "generic".into())); match fs_settings.mode { @@ -75,8 +86,58 @@ impl Renderer { None } }); + let window = event_loop.create_window(window_attributes).unwrap(); - Self { window } + let size = window.inner_size(); + + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::all(), + ..Default::default() + }); + + let surface = instance.create_surface(window).unwrap(); + + let adapter = instance.request_adapter( + &wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::HighPerformance, + compatible_surface: Some(&surface), + force_fallback_adapter: false, + }, + ).block_on().unwrap(); + + let (device, queue) = adapter.request_device( + &wgpu::DeviceDescriptor { + label: None, + required_features: wgpu::Features::empty(), + required_limits: wgpu::Limits::downlevel_defaults(), + }, + None, + ).block_on().unwrap(); + + let surface_config = surface.get_default_config(&adapter, size.width, size.height).unwrap(); + surface.configure(&device, &surface_config); + + Self { window, instance, surface, device, queue, surface_config, size } + } + + pub fn resize(&mut self, size: PhysicalSize) { + if size.width == 0 || size.height == 0 { + log::warn!("Ignoring resize event with zero width or height"); + return + } + if self.size == size { + log::warn!("Ignoring resize event with same size"); + return + } + log::debug!("resizing surface to {:?}", size); + self.size = size; + self.surface_config.width = size.width; + self.surface_config.height = size.height; + self.surface.configure(&self.device, &self.surface_config); + } + + pub fn reconfigure(&self) { + self.surface.configure(&self.device, &self.surface_config); } }