Refactor the demo some

This commit is contained in:
Patrick Walton 2019-02-08 15:39:47 -08:00
parent 725834285b
commit 3cc8f7a11f
1 changed files with 196 additions and 175 deletions

View File

@ -59,6 +59,8 @@ const SWITCH_HALF_SIZE: i32 = 96;
const APPROX_FONT_SIZE: f32 = 16.0;
const WORLD_SCALE: f32 = 1.0 / 800.0;
static EFFECTS_PNG_NAME: &'static str = "demo-effects";
static OPEN_PNG_NAME: &'static str = "demo-open";
@ -83,6 +85,12 @@ struct DemoApp {
camera_yaw: f32,
camera_pitch: f32,
frame_counter: u32,
events: Vec<Event>,
exit: bool,
mouselook_enabled: bool,
ui_event_handled_last_frame: bool,
ui: DemoUI,
scene_thread_proxy: SceneThreadProxy,
renderer: Renderer,
@ -134,6 +142,12 @@ impl DemoApp {
camera_yaw: 0.0,
camera_pitch: 0.0,
frame_counter: 0,
events: vec![],
exit: false,
mouselook_enabled: false,
ui_event_handled_last_frame: false,
ui: DemoUI::new(options),
scene_thread_proxy,
renderer: Renderer::new(&drawable_size),
@ -141,17 +155,24 @@ impl DemoApp {
}
fn run(&mut self) {
let mut exit = false;
let mut events = vec![];
let mut frame_counter = 0;
let mut mouselook_enabled = false;
let mut ui_event_handled_last_frame = false;
let (drawable_width, drawable_height) = self.window.drawable_size();
let mut drawable_size = Size2D::new(drawable_width, drawable_height);
while !exit {
while !self.exit {
// Update the scene.
self.build_scene();
// Handle events.
// FIXME(pcwalton): This can cause us to miss UI events if things get backed up...
let ui_event = self.handle_events();
// Draw the scene.
let render_msg = self.scene_thread_proxy.receiver.recv().unwrap();
self.draw_scene(render_msg, ui_event);
}
}
fn build_scene(&mut self) {
let (drawable_width, drawable_height) = self.window.drawable_size();
let drawable_size = Size2D::new(drawable_width, drawable_height);
let perspective = if self.ui.threed_enabled {
let rotation = Transform3DF32::from_rotation(-self.camera_yaw,
-self.camera_pitch,
@ -162,9 +183,9 @@ impl DemoApp {
let aspect = drawable_size.width as f32 / drawable_size.height as f32;
let mut transform = Transform3DF32::from_perspective(FRAC_PI_4, aspect, 0.025, 100.0);
transform = transform.post_mul(&Transform3DF32::from_scale(1.0 / 800.0,
1.0 / 800.0,
1.0 / 800.0));
transform = transform.post_mul(&Transform3DF32::from_scale(WORLD_SCALE,
WORLD_SCALE,
WORLD_SCALE));
transform = transform.post_mul(&Transform3DF32::from_rotation(self.camera_yaw,
self.camera_pitch,
0.0));
@ -178,7 +199,7 @@ impl DemoApp {
None
};
let count = if frame_counter == 0 { 2 } else { 1 };
let count = if self.frame_counter == 0 { 2 } else { 1 };
for _ in 0..count {
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
perspective,
@ -189,31 +210,29 @@ impl DemoApp {
},
})).unwrap();
}
}
// FIXME(pcwalton): This can cause us to miss UI events if things get backed up...
fn handle_events(&mut self) -> UIEvent {
let mut ui_event = UIEvent::None;
let mut event_handled = false;
while !event_handled {
let wait_for_event =
!self.camera_velocity.is_zero() &&
frame_counter >= 2 &&
!ui_event_handled_last_frame;
let wait_for_event = !self.camera_velocity.is_zero() && self.frame_counter >= 2 &&
!self.ui_event_handled_last_frame;
if wait_for_event {
events.push(self.sdl_event_pump.wait_event());
self.events.push(self.sdl_event_pump.wait_event());
}
for event in self.sdl_event_pump.poll_iter() {
events.push(event);
self.events.push(event);
}
for event in events.drain(..) {
for event in self.events.drain(..) {
match event {
Event::Quit { .. } |
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
exit = true;
self.exit = true;
}
Event::Window { win_event: WindowEvent::SizeChanged(..), .. } => {
let (drawable_width, drawable_height) = self.window.drawable_size();
drawable_size = Size2D::new(drawable_width as u32,
let drawable_size = Size2D::new(drawable_width as u32,
drawable_height as u32);
self.scene_thread_proxy.set_drawable_size(&drawable_size);
self.renderer.set_main_framebuffer_size(&drawable_size);
@ -222,7 +241,7 @@ impl DemoApp {
let point = Point2DI32::new(x, y).scale(self.scale_factor as i32);
ui_event = UIEvent::MouseDown(point);
}
Event::MouseMotion { xrel, yrel, .. } if mouselook_enabled => {
Event::MouseMotion { xrel, yrel, .. } if self.mouselook_enabled => {
self.camera_yaw += xrel as f32 * MOUSELOOK_ROTATION_SPEED;
self.camera_pitch -= yrel as f32 * MOUSELOOK_ROTATION_SPEED;
}
@ -248,21 +267,14 @@ impl DemoApp {
}
_ => continue,
}
event_handled = true;
}
// FIXME(pcwalton): This is so ugly!
if !wait_for_event {
event_handled = true;
}
ui_event
}
// Draw the scene.
let SceneToMainMsg::Render {
built_scene,
tile_time
} = self.scene_thread_proxy.receiver.recv().unwrap();
fn draw_scene(&mut self, render_msg: SceneToMainMsg, mut ui_event: UIEvent) {
let SceneToMainMsg::Render { built_scene, tile_time } = render_msg;
unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
gl::ClearColor(BACKGROUND_COLOR.r as f32 / 255.0,
@ -291,17 +303,16 @@ impl DemoApp {
let had_ui_event = ui_event.is_none();
self.ui.update(&mut self.renderer.debug_ui, &mut ui_event);
ui_event_handled_last_frame = had_ui_event && ui_event.is_none();
self.ui_event_handled_last_frame = had_ui_event && ui_event.is_none();
// If nothing handled the mouse-down event, toggle mouselook.
if let UIEvent::MouseDown(_) = ui_event {
mouselook_enabled = !mouselook_enabled;
self.mouselook_enabled = !self.mouselook_enabled;
}
}
self.window.gl_swap_window();
frame_counter += 1;
}
self.frame_counter += 1;
}
}
@ -468,6 +479,7 @@ fn build_scene(scene: &Scene, build_options: BuildOptions, jobs: Option<usize>)
while let Some(batch) = scene_builder.build_batch() {
built_scene.batches.push(batch);
}
built_scene
}
@ -527,12 +539,21 @@ impl DemoUI {
self.threed_enabled);
// Draw effects window, if necessary.
if self.effects_window_visible {
self.draw_effects_window(debug_ui, event);
}
fn draw_effects_window(&mut self, debug_ui: &mut DebugUI, event: &mut UIEvent) {
if !self.effects_window_visible {
return;
}
let bottom = debug_ui.framebuffer_size().height as i32 - PADDING;
let effects_window_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_WINDOW_HEIGHT);
debug_ui.draw_solid_rect(RectI32::new(Point2DI32::new(PADDING, effects_window_y),
Point2DI32::new(EFFECTS_WINDOW_WIDTH,
EFFECTS_WINDOW_HEIGHT)),
WINDOW_COLOR);
self.gamma_correction_effect_enabled =
self.draw_effects_switch(debug_ui,
event,
@ -554,7 +575,7 @@ impl DemoUI {
2,
effects_window_y,
self.subpixel_aa_effect_enabled);
}
}
fn draw_button(&self,