|
1 | 1 | use cgmath::{Angle, EuclideanSpace, Matrix4, Point3, Rad, Vector3};
|
2 |
| -use glium::backend::glutin::SimpleWindowBuilder; |
| 2 | +use glium::backend::glutin::{Display, SimpleWindowBuilder}; |
| 3 | + |
| 4 | +use glium::glutin::surface::WindowSurface; |
3 | 5 | use glium::index::{IndexBuffer, PrimitiveType};
|
4 | 6 | use glium::{Depth, DepthTest, DrawParameters, Program, Surface, VertexBuffer};
|
5 | 7 | use rand::Rng;
|
6 |
| -use winit::event::{ElementState, Event, KeyEvent, WindowEvent}; |
7 |
| -use winit::event_loop::EventLoop; |
| 8 | +use winit::application::ApplicationHandler; |
| 9 | + |
| 10 | +use winit::event::{ElementState, KeyEvent, WindowEvent}; |
| 11 | +use winit::event_loop::{ActiveEventLoop, EventLoop}; |
8 | 12 | use winit::keyboard::{Key, NamedKey};
|
| 13 | +use winit::window::{Window, WindowId}; |
9 | 14 |
|
10 | 15 | use crate::nbody::nbody::NBodyBenchmark;
|
11 | 16 | use crate::nbody::ExecutionMode;
|
@@ -76,14 +81,117 @@ struct Instance {
|
76 | 81 |
|
77 | 82 | glium::implement_vertex!(Instance, color, world_position);
|
78 | 83 |
|
79 |
| -pub fn visualize_benchmarks(num_bodies: usize, mut mode: ExecutionMode) { |
| 84 | +struct State { |
| 85 | + window: Option<Window>, |
| 86 | + mode: ExecutionMode, |
| 87 | + instance_buffer: VertexBuffer<Instance>, |
| 88 | + benchmark: NBodyBenchmark, |
| 89 | + display: Display<WindowSurface>, |
| 90 | + vertex_buffer: VertexBuffer<Vertex>, |
| 91 | + index_buffer: IndexBuffer<u8>, |
| 92 | + program: Program, |
| 93 | +} |
| 94 | + |
| 95 | +impl ApplicationHandler for State { |
| 96 | + fn resumed(&mut self, _event_loop: &ActiveEventLoop) {} |
| 97 | + |
| 98 | + fn window_event( |
| 99 | + &mut self, |
| 100 | + event_loop: &ActiveEventLoop, |
| 101 | + _window_id: WindowId, |
| 102 | + event: WindowEvent, |
| 103 | + ) { |
| 104 | + match event { |
| 105 | + WindowEvent::CloseRequested => event_loop.exit(), |
| 106 | + WindowEvent::KeyboardInput { |
| 107 | + event: |
| 108 | + KeyEvent { |
| 109 | + state: ElementState::Pressed, |
| 110 | + logical_key, |
| 111 | + .. |
| 112 | + }, |
| 113 | + .. |
| 114 | + } => match logical_key { |
| 115 | + Key::Named(NamedKey::Escape) => event_loop.exit(), |
| 116 | + Key::Character(s) => match s.as_str() { |
| 117 | + "p" => self.mode = ExecutionMode::Par, |
| 118 | + "r" => self.mode = ExecutionMode::ParReduce, |
| 119 | + "s" => self.mode = ExecutionMode::Seq, |
| 120 | + _ => (), |
| 121 | + }, |
| 122 | + _ => (), |
| 123 | + }, |
| 124 | + WindowEvent::RedrawRequested => { |
| 125 | + let params = DrawParameters { |
| 126 | + depth: Depth { |
| 127 | + test: DepthTest::IfLess, |
| 128 | + write: true, |
| 129 | + ..Default::default() |
| 130 | + }, |
| 131 | + ..Default::default() |
| 132 | + }; |
| 133 | + |
| 134 | + let mut target = self.display.draw(); |
| 135 | + |
| 136 | + let (width, height) = target.get_dimensions(); |
| 137 | + let aspect = width as f32 / height as f32; |
| 138 | + |
| 139 | + let proj = cgmath::perspective(Rad::full_turn() / 6.0, aspect, 0.1, 3000.0); |
| 140 | + let view = Matrix4::look_at_rh( |
| 141 | + Point3::new(10.0, 10.0, 10.0), |
| 142 | + Point3::origin(), |
| 143 | + Vector3::unit_z(), |
| 144 | + ); |
| 145 | + let view_proj: [[f32; 4]; 4] = (proj * view).into(); |
| 146 | + |
| 147 | + target.clear_color_and_depth((0.1, 0.1, 0.1, 1.0), 1.0); |
| 148 | + target |
| 149 | + .draw( |
| 150 | + ( |
| 151 | + &self.vertex_buffer, |
| 152 | + self.instance_buffer.per_instance().unwrap(), |
| 153 | + ), |
| 154 | + &self.index_buffer, |
| 155 | + &self.program, |
| 156 | + &glium::uniform! { matrix: view_proj }, |
| 157 | + ¶ms, |
| 158 | + ) |
| 159 | + .unwrap(); |
| 160 | + target.finish().unwrap(); |
| 161 | + } |
| 162 | + _ => (), |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { |
| 167 | + if let Some(window) = self.window.as_ref() { |
| 168 | + let bodies = match self.mode { |
| 169 | + ExecutionMode::Par => self.benchmark.tick_par(), |
| 170 | + ExecutionMode::ParReduce => self.benchmark.tick_par_reduce(), |
| 171 | + ExecutionMode::Seq => self.benchmark.tick_seq(), |
| 172 | + }; |
| 173 | + |
| 174 | + let mut mapping = self.instance_buffer.map(); |
| 175 | + for (body, instance) in bodies.iter().zip(mapping.iter_mut()) { |
| 176 | + instance.world_position = [ |
| 177 | + body.position.x as f32, |
| 178 | + body.position.y as f32, |
| 179 | + body.position.z as f32, |
| 180 | + ]; |
| 181 | + } |
| 182 | + window.request_redraw(); |
| 183 | + } |
| 184 | + } |
| 185 | +} |
| 186 | + |
| 187 | +pub fn visualize_benchmarks(num_bodies: usize, mode: ExecutionMode) { |
80 | 188 | let event_loop = EventLoop::new().unwrap();
|
81 | 189 | let (window, display) = SimpleWindowBuilder::new()
|
82 | 190 | .with_inner_size(800, 600)
|
83 | 191 | .with_title("nbody demo")
|
84 | 192 | .build(&event_loop);
|
85 | 193 |
|
86 |
| - let mut benchmark = NBodyBenchmark::new(num_bodies, &mut rand::thread_rng()); |
| 194 | + let benchmark = NBodyBenchmark::new(num_bodies, &mut rand::thread_rng()); |
87 | 195 |
|
88 | 196 | let vertex_shader_src = r#"
|
89 | 197 | #version 100
|
@@ -131,85 +239,18 @@ pub fn visualize_benchmarks(num_bodies: usize, mut mode: ExecutionMode) {
|
131 | 239 | })
|
132 | 240 | .collect();
|
133 | 241 |
|
134 |
| - let mut instance_buffer = VertexBuffer::dynamic(&display, &instances).unwrap(); |
| 242 | + let instance_buffer = VertexBuffer::dynamic(&display, &instances).unwrap(); |
135 | 243 |
|
136 |
| - event_loop |
137 |
| - .run(move |event, target| match event { |
138 |
| - Event::AboutToWait => { |
139 |
| - let bodies = match mode { |
140 |
| - ExecutionMode::Par => benchmark.tick_par(), |
141 |
| - ExecutionMode::ParReduce => benchmark.tick_par_reduce(), |
142 |
| - ExecutionMode::Seq => benchmark.tick_seq(), |
143 |
| - }; |
| 244 | + let mut state = State { |
| 245 | + window: Some(window), |
| 246 | + mode, |
| 247 | + instance_buffer, |
| 248 | + benchmark, |
| 249 | + display, |
| 250 | + vertex_buffer, |
| 251 | + index_buffer, |
| 252 | + program, |
| 253 | + }; |
144 | 254 |
|
145 |
| - let mut mapping = instance_buffer.map(); |
146 |
| - for (body, instance) in bodies.iter().zip(mapping.iter_mut()) { |
147 |
| - instance.world_position = [ |
148 |
| - body.position.x as f32, |
149 |
| - body.position.y as f32, |
150 |
| - body.position.z as f32, |
151 |
| - ]; |
152 |
| - } |
153 |
| - window.request_redraw(); |
154 |
| - } |
155 |
| - Event::WindowEvent { event, .. } => match event { |
156 |
| - WindowEvent::CloseRequested => target.exit(), |
157 |
| - WindowEvent::KeyboardInput { |
158 |
| - event: |
159 |
| - KeyEvent { |
160 |
| - state: ElementState::Pressed, |
161 |
| - logical_key, |
162 |
| - .. |
163 |
| - }, |
164 |
| - .. |
165 |
| - } => match logical_key { |
166 |
| - Key::Named(NamedKey::Escape) => target.exit(), |
167 |
| - Key::Character(s) => match s.as_str() { |
168 |
| - "p" => mode = ExecutionMode::Par, |
169 |
| - "r" => mode = ExecutionMode::ParReduce, |
170 |
| - "s" => mode = ExecutionMode::Seq, |
171 |
| - _ => (), |
172 |
| - }, |
173 |
| - _ => (), |
174 |
| - }, |
175 |
| - WindowEvent::RedrawRequested => { |
176 |
| - let params = DrawParameters { |
177 |
| - depth: Depth { |
178 |
| - test: DepthTest::IfLess, |
179 |
| - write: true, |
180 |
| - ..Default::default() |
181 |
| - }, |
182 |
| - ..Default::default() |
183 |
| - }; |
184 |
| - |
185 |
| - let mut target = display.draw(); |
186 |
| - |
187 |
| - let (width, height) = target.get_dimensions(); |
188 |
| - let aspect = width as f32 / height as f32; |
189 |
| - |
190 |
| - let proj = cgmath::perspective(Rad::full_turn() / 6.0, aspect, 0.1, 3000.0); |
191 |
| - let view = Matrix4::look_at_rh( |
192 |
| - Point3::new(10.0, 10.0, 10.0), |
193 |
| - Point3::origin(), |
194 |
| - Vector3::unit_z(), |
195 |
| - ); |
196 |
| - let view_proj: [[f32; 4]; 4] = (proj * view).into(); |
197 |
| - |
198 |
| - target.clear_color_and_depth((0.1, 0.1, 0.1, 1.0), 1.0); |
199 |
| - target |
200 |
| - .draw( |
201 |
| - (&vertex_buffer, instance_buffer.per_instance().unwrap()), |
202 |
| - &index_buffer, |
203 |
| - &program, |
204 |
| - &glium::uniform! { matrix: view_proj }, |
205 |
| - ¶ms, |
206 |
| - ) |
207 |
| - .unwrap(); |
208 |
| - target.finish().unwrap(); |
209 |
| - } |
210 |
| - _ => (), |
211 |
| - }, |
212 |
| - _ => (), |
213 |
| - }) |
214 |
| - .unwrap(); |
| 255 | + let _ = event_loop.run_app(&mut state); |
215 | 256 | }
|
0 commit comments