1use winit::window::Window;
2use wgpu::util::DeviceExt;
3
4pub struct Renderer {
5 surface: wgpu::Surface<'static>,
6 device: wgpu::Device,
7 queue: wgpu::Queue,
8 config: wgpu::SurfaceConfiguration,
9 pub size: winit::dpi::PhysicalSize<u32>,
10}
11
12impl Renderer {
13 pub async fn new(window: &Window) -> Self {
14 let size = window.inner_size();
15
16 let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
19 backends: wgpu::Backends::all(),
20 ..Default::default()
21 });
22
23 let surface = unsafe {
29 let surface = instance.create_surface(window).unwrap();
30 std::mem::transmute::<wgpu::Surface<'_>, wgpu::Surface<'static>>(surface)
31 };
32
33 let adapter = instance.request_adapter(
34 &wgpu::RequestAdapterOptions {
35 power_preference: wgpu::PowerPreference::default(),
36 compatible_surface: Some(&surface),
37 force_fallback_adapter: false,
38 },
39 ).await.unwrap();
40
41 let (device, queue) = adapter.request_device(
42 &wgpu::DeviceDescriptor {
43 required_features: wgpu::Features::empty(),
44 required_limits: wgpu::Limits::default(),
45 label: None,
46 },
47 None, ).await.unwrap();
49
50 let surface_caps = surface.get_capabilities(&adapter);
51 let surface_format = surface_caps.formats.iter()
52 .copied()
53 .filter(|f| f.is_srgb())
54 .next()
55 .unwrap_or(surface_caps.formats[0]);
56
57 let config = wgpu::SurfaceConfiguration {
58 usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
59 format: surface_format,
60 width: size.width,
61 height: size.height,
62 present_mode: surface_caps.present_modes[0],
63 alpha_mode: surface_caps.alpha_modes[0],
64 view_formats: vec![],
65 desired_maximum_frame_latency: 2,
66 };
67
68 surface.configure(&device, &config);
69
70 Self {
71 surface,
72 device,
73 queue,
74 config,
75 size,
76 }
77 }
78
79 pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
80 if new_size.width > 0 && new_size.height > 0 {
81 self.size = new_size;
82 self.config.width = new_size.width;
83 self.config.height = new_size.height;
84 self.surface.configure(&self.device, &self.config);
85 }
86 }
87
88 pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
89 let output = self.surface.get_current_texture()?;
90 let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
91
92 let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
93 label: Some("Render Encoder"),
94 });
95
96 {
97 let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
98 label: Some("Render Pass"),
99 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
100 view: &view,
101 resolve_target: None,
102 ops: wgpu::Operations {
103 load: wgpu::LoadOp::Clear(wgpu::Color {
104 r: 0.1,
105 g: 0.2,
106 b: 0.3,
107 a: 1.0,
108 }),
109 store: wgpu::StoreOp::Store,
110 },
111 })],
112 depth_stencil_attachment: None,
113 timestamp_writes: None,
114 occlusion_query_set: None,
115 });
116 }
117
118 self.queue.submit(std::iter::once(encoder.finish()));
119 output.present();
120
121 Ok(())
122 }
123}