1pub mod render;
2
3use crate::display::render::Renderer;
4use std::sync::Arc;
5use wgpu::{
6 CurrentSurfaceTexture, Device, Instance, Queue, RequestAdapterOptions, Surface,
7 SurfaceConfiguration, TextureViewDescriptor,
8};
9use winit::{application::ApplicationHandler, event::WindowEvent, window::Window as WinitWindow};
10
11struct GpuState {
12 surface: Surface<'static>,
13 device: Device,
14 queue: Queue,
15 config: SurfaceConfiguration,
16}
17
18#[derive(Default)]
19pub struct Window {
20 pub inner: Option<Arc<WinitWindow>>,
21 gpu: Option<GpuState>,
22 renderer: Option<Box<dyn Renderer>>,
23}
24impl ApplicationHandler for Window {
25 fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
26 let window = Arc::new(
27 event_loop
28 .create_window(WinitWindow::default_attributes())
29 .unwrap(),
30 );
31 self.inner = Some(window.clone());
32 let instance = Instance::default();
33 let surface = instance
34 .create_surface(window.clone())
35 .expect("Could not create surface.");
36 let adapter = pollster::block_on(instance.request_adapter(&RequestAdapterOptions {
37 compatible_surface: Some(&surface),
38 ..Default::default()
39 }))
40 .expect("Could not find an appropriate adapter.");
41 let (device, queue) =
42 pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor::default()))
43 .expect("Failed to create device");
44 let size = window.inner_size();
45 let config = surface
46 .get_default_config(&adapter, size.width, size.height)
47 .unwrap();
48 self.gpu = Some(GpuState {
49 surface,
50 device,
51 queue,
52 config,
53 })
54 }
55 fn window_event(
56 &mut self,
57 event_loop: &winit::event_loop::ActiveEventLoop,
58 _window_id: winit::window::WindowId,
59 event: winit::event::WindowEvent,
60 ) {
61 let (Some(gpu), Some(renderer), Some(window)) =
62 (&mut self.gpu, &mut self.renderer, &self.inner)
63 else {
64 return;
65 };
66 match event {
67 WindowEvent::CloseRequested => {
68 event_loop.exit();
69 }
70 WindowEvent::Resized(new_size) => {
71 gpu.config.width = new_size.width;
72 gpu.config.height = new_size.height;
73 gpu.surface.configure(&gpu.device, &gpu.config);
74 }
75 WindowEvent::RedrawRequested => {
76 let frame = gpu.surface.get_current_texture();
77 match frame {
78 CurrentSurfaceTexture::Success(frame) => {
79 let view = frame.texture.create_view(&TextureViewDescriptor::default());
80 renderer
81 .render(&gpu.device, &gpu.queue, &view, window.inner_size())
82 .expect("Redraw failed: Renderer panic.");
83 frame.present();
84 }
85 CurrentSurfaceTexture::Outdated => {
86 gpu.surface.configure(&gpu.device, &gpu.config);
87 }
88 _ => {
89 eprintln!("Dropped frame: {:?}", frame);
90 }
91 }
92 }
93 _ => {}
94 }
95 }
96}