clear_screen/
clear_screen.rs1use std::sync::Arc;
9use std::time::Instant;
10
11use llimphi_hal::winit::application::ApplicationHandler;
12use llimphi_hal::winit::dpi::LogicalSize;
13use llimphi_hal::winit::event::WindowEvent;
14use llimphi_hal::winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
15use llimphi_hal::winit::window::{Window, WindowAttributes, WindowId};
16use llimphi_hal::{wgpu, Hal, Surface, WinitSurface};
17
18const LEAD_GRAY: wgpu::Color = wgpu::Color {
19 r: 0.235,
20 g: 0.239,
21 b: 0.247,
22 a: 1.0,
23};
24
25struct State {
26 window: Arc<Window>,
27 hal: Hal,
28 surface: WinitSurface,
29}
30
31struct App {
32 state: Option<State>,
33 frames: u64,
34 last_report: Instant,
35}
36
37impl ApplicationHandler for App {
38 fn resumed(&mut self, event_loop: &ActiveEventLoop) {
39 if self.state.is_some() {
40 return;
41 }
42 let window = event_loop
43 .create_window(
44 WindowAttributes::default()
45 .with_title("llimphi · clear_screen")
46 .with_inner_size(LogicalSize::new(960u32, 540u32)),
47 )
48 .expect("create window");
49 let window = Arc::new(window);
50 let hal = pollster::block_on(Hal::new(None)).expect("hal");
51 let surface = WinitSurface::new(&hal, window.clone()).expect("surface");
52 window.request_redraw();
53 self.state = Some(State {
54 window,
55 hal,
56 surface,
57 });
58 }
59
60 fn window_event(
61 &mut self,
62 event_loop: &ActiveEventLoop,
63 _id: WindowId,
64 event: WindowEvent,
65 ) {
66 let Some(state) = self.state.as_mut() else {
67 return;
68 };
69 match event {
70 WindowEvent::CloseRequested => event_loop.exit(),
71 WindowEvent::Resized(size) => {
72 state.surface.resize(size.width, size.height);
73 state.window.request_redraw();
74 }
75 WindowEvent::RedrawRequested => {
76 let frame = match state.surface.acquire() {
77 Ok(f) => f,
78 Err(_) => {
79 let (w, h) = state.surface.size();
80 state.surface.resize(w, h);
81 state.window.request_redraw();
82 return;
83 }
84 };
85 let mut encoder =
86 state
87 .hal
88 .device
89 .create_command_encoder(&wgpu::CommandEncoderDescriptor {
90 label: Some("clear_screen-encoder"),
91 });
92 {
93 let _pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
94 label: Some("clear_screen-pass"),
95 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
96 view: frame.view(),
97 resolve_target: None,
98 depth_slice: None,
99 ops: wgpu::Operations {
100 load: wgpu::LoadOp::Clear(LEAD_GRAY),
101 store: wgpu::StoreOp::Store,
102 },
103 })],
104 depth_stencil_attachment: None,
105 timestamp_writes: None,
106 occlusion_query_set: None,
107 });
108 }
109 state.hal.queue.submit(std::iter::once(encoder.finish()));
110 state.surface.present(frame, &state.hal);
111
112 self.frames += 1;
113 let elapsed = self.last_report.elapsed();
114 if elapsed.as_secs() >= 1 {
115 let fps = self.frames as f64 / elapsed.as_secs_f64();
116 eprintln!("llimphi · clear_screen — {fps:.1} fps");
117 self.frames = 0;
118 self.last_report = Instant::now();
119 }
120 state.window.request_redraw();
121 }
122 _ => {}
123 }
124 }
125}
126
127fn main() {
128 let event_loop = EventLoop::new().expect("event loop");
129 event_loop.set_control_flow(ControlFlow::Poll);
130 let mut app = App {
131 state: None,
132 frames: 0,
133 last_report: Instant::now(),
134 };
135 event_loop.run_app(&mut app).expect("run app");
136}