From d39a7d62e7bdc63b2055ad93bf511cdd1e40e69d Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sun, 19 Jan 2025 11:28:12 +0100 Subject: a --- client/Cargo.toml | 3 +- client/src/main.rs | 1 + client/src/renderer.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ client/src/window.rs | 24 +++++++++++----- 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 client/src/renderer.rs (limited to 'client') diff --git a/client/Cargo.toml b/client/Cargo.toml index 471a905..8101167 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -10,7 +10,8 @@ anyhow = "1.0.95" arrayvec = "0.5.2" warn = ">=0.1.1,<0.3.0" xdg = "2.5.2" - +wgpu = "23.0.1" +pollster = "0.4.0" winit = "0.30.8" twgame = { path = "../../twgame/twgame" } diff --git a/client/src/main.rs b/client/src/main.rs index ab05178..8373db9 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -4,6 +4,7 @@ use window::WindowState; use winit::event_loop::EventLoop; pub mod client; +pub mod renderer; pub mod window; fn main() -> Result<()> { diff --git a/client/src/renderer.rs b/client/src/renderer.rs new file mode 100644 index 0000000..c8f7f0b --- /dev/null +++ b/client/src/renderer.rs @@ -0,0 +1,76 @@ +use std::sync::Arc; + +use anyhow::{Result, anyhow}; +use pollster::FutureExt; +use twgpu::{ + Camera, GpuCamera, + map::{GpuMapData, GpuMapStatic}, + shared::Rng, + sprites::{ParticleData, SpriteTextures, SpritesData, SpritesStatic}, + textures::Samplers, +}; +use wgpu::{ + Backends, DeviceDescriptor, Features, Instance, InstanceDescriptor, Limits, MemoryHints, + PowerPreference, RequestAdapterOptions, TextureFormat, +}; +use winit::window::Window; + +pub struct Renderer<'a> { + window: &'a Window, +} + +impl<'a> Renderer<'a> { + pub fn new(window: &'a Window) -> Result { + let texture_format = TextureFormat::Bgra8UnormSrgb; + + let instance = Instance::new(InstanceDescriptor { + backends: Backends::all(), + ..Default::default() + }); + + let surface = instance.create_surface(window)?; + + let adapter = instance + .request_adapter(&RequestAdapterOptions { + power_preference: PowerPreference::HighPerformance, + compatible_surface: Some(&surface), + force_fallback_adapter: false, + }) + .block_on() + .ok_or(anyhow!("no adapter found"))?; + + eprintln!("Adapter {:#?}", adapter.limits()); + let (device, queue) = adapter + .request_device( + &DeviceDescriptor { + label: None, + required_features: Features::default(), + required_limits: Limits::default(), + memory_hints: MemoryHints::Performance, + }, + None, + ) + .block_on()?; + + let samplers = Arc::new(Samplers::new(&device)); + let mut camera = Camera::new(1.); + let gpu_camera = Arc::new(GpuCamera::upload(&camera, &device)); + + let map_static = GpuMapStatic::new(texture_format, &device); + let map_data = GpuMapData::upload(&twmap, &device, &queue); + let map_render = + map_static.prepare_render(&twmap, &map_data, &gpu_camera, &samplers, &device); + + let sprites_static = SpritesStatic::new(texture_format, &device); + let mut sprites_data = SpritesData::new(&device); + let mut particle_data = ParticleData::new(demo.current_time(), &device); + let mut textures = SpriteTextures::new(&device, &queue, &gpu_camera, &samplers); + let mut rng = Rng::new(0); + init_sprite_textures(&mut textures, twmap.version, &device, &queue)?; + let blit = Arc::new(Blit::new(&device)); + let mut skin_manager = SkinManager::new(blit, &mut textures, device.clone(), queue.clone()); + + Self { window } + } + pub fn redraw() {} +} diff --git a/client/src/window.rs b/client/src/window.rs index f003574..d0296e7 100644 --- a/client/src/window.rs +++ b/client/src/window.rs @@ -1,3 +1,4 @@ +use crate::renderer::Renderer; use winit::{ application::ApplicationHandler, event::WindowEvent, @@ -6,7 +7,7 @@ use winit::{ }; pub struct WindowState { - window: Option, + window: Option<(Window, Renderer<'static>)>, } impl WindowState { @@ -16,11 +17,11 @@ impl WindowState { } impl ApplicationHandler for WindowState { fn resumed(&mut self, event_loop: &ActiveEventLoop) { - self.window = Some( - event_loop - .create_window(WindowAttributes::default().with_maximized(true)) - .unwrap(), - ) + let window = event_loop + .create_window(WindowAttributes::default().with_maximized(true)) + .unwrap(); + let renderer = Renderer::new(unsafe { std::mem::transmute(&window) }); + self.window = Some((window, renderer)) } fn window_event( @@ -29,7 +30,7 @@ impl ApplicationHandler for WindowState { window_id: WindowId, event: WindowEvent, ) { - if let Some(win) = &self.window { + if let Some((win, ren)) = &self.window { match event { WindowEvent::RedrawRequested => {} _ => (), @@ -37,3 +38,12 @@ impl ApplicationHandler for WindowState { } } } + +impl Drop for WindowState { + fn drop(&mut self) { + if let Some((win, ren)) = self.window.take() { + drop(ren); + drop(win); + } + } +} -- cgit v1.2.3-70-g09d2