pub mod render;
use crate::display::render::Renderer;
use std::sync::Arc;
use wgpu::{
CurrentSurfaceTexture, Device, Instance, Queue, RequestAdapterOptions, Surface,
SurfaceConfiguration, TextureViewDescriptor,
};
use winit::{application::ApplicationHandler, event::WindowEvent, window::Window as WinitWindow};
struct GpuState {
surface: Surface<'static>,
device: Device,
queue: Queue,
config: SurfaceConfiguration,
}
#[derive(Default)]
pub struct Window {
pub inner: Option<Arc<WinitWindow>>,
gpu: Option<GpuState>,
renderer: Option<Box<dyn Renderer>>,
}
impl ApplicationHandler for Window {
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
let window = Arc::new(
event_loop
.create_window(WinitWindow::default_attributes())
.unwrap(),
);
self.inner = Some(window.clone());
let instance = Instance::default();
let surface = instance
.create_surface(window.clone())
.expect("Could not create surface.");
let adapter = pollster::block_on(instance.request_adapter(&RequestAdapterOptions {
compatible_surface: Some(&surface),
..Default::default()
}))
.expect("Could not find an appropriate adapter.");
let (device, queue) =
pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor::default()))
.expect("Failed to create device");
let size = window.inner_size();
let config = surface
.get_default_config(&adapter, size.width, size.height)
.unwrap();
self.gpu = Some(GpuState {
surface,
device,
queue,
config,
})
}
fn window_event(
&mut self,
event_loop: &winit::event_loop::ActiveEventLoop,
_window_id: winit::window::WindowId,
event: winit::event::WindowEvent,
) {
let (Some(gpu), Some(renderer), Some(window)) =
(&mut self.gpu, &mut self.renderer, &self.inner)
else {
return;
};
match event {
WindowEvent::CloseRequested => {
event_loop.exit();
}
WindowEvent::Resized(new_size) => {
gpu.config.width = new_size.width;
gpu.config.height = new_size.height;
gpu.surface.configure(&gpu.device, &gpu.config);
}
WindowEvent::RedrawRequested => {
let frame = gpu.surface.get_current_texture();
match frame {
CurrentSurfaceTexture::Success(frame) => {
let view = frame.texture.create_view(&TextureViewDescriptor::default());
renderer
.render(&gpu.device, &gpu.queue, &view, window.inner_size())
.expect("Redraw failed: Renderer panic.");
frame.present();
}
CurrentSurfaceTexture::Outdated => {
gpu.surface.configure(&gpu.device, &gpu.config);
}
_ => {
eprintln!("Dropped frame: {:?}", frame);
}
}
}
_ => {}
}
}
}