diff --git a/demo/android/rust/src/lib.rs b/demo/android/rust/src/lib.rs index e676d633..c62f700d 100644 --- a/demo/android/rust/src/lib.rs +++ b/demo/android/rust/src/lib.rs @@ -15,7 +15,7 @@ use jni::{JNIEnv, JavaVM}; use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JString, JValue}; use pathfinder_demo::DemoApp; use pathfinder_demo::Options; -use pathfinder_demo::window::{Event, SVGPath, Window, WindowSize}; +use pathfinder_demo::window::{Event, SVGPath, View, Window, WindowSize}; use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::rect::RectI32; use pathfinder_gl::GLVersion; @@ -50,6 +50,7 @@ pub unsafe extern "system" fn let logical_size = Point2DI32::new(width, height); let window_size = WindowSize { logical_size, backing_scale_factor: 1.0 }; let window = WindowImpl { size: logical_size }; + let options = Options::default(); JAVA_ACTIVITY.with(|java_activity| { *java_activity.borrow_mut() = Some(JavaActivity::new(env.clone(), activity)); @@ -170,20 +171,11 @@ impl Window for WindowImpl { Point2DI32::new(0, 0) } - fn view_box_size(&self, mode: Mode) -> Point2DI32 { - let mut width = self.size.x(); - let height = self.size.y(); - if let Mode::VR = mode { - width = width / 2; - } - Point2DI32::new(width as i32, height as i32) - } - - fn make_current(&mut self, mode: Mode, index: Option) -> RectI32 { + fn viewport(&self, view: View) -> RectI32 { let mut width = self.size.x(); let mut offset_x = 0; let height = self.size.y(); - if let (Mode::VR, Some(index)) = (mode, index) { + if let View::Stereo(index) = view { width = width / 2; offset_x = (index as i32) * width; } @@ -192,6 +184,8 @@ impl Window for WindowImpl { RectI32::new(offset, size) } + fn make_current(&mut self, _view: View) {} + fn present(&mut self) {} fn resource_loader(&self) -> &dyn ResourceLoader { diff --git a/demo/common/src/lib.rs b/demo/common/src/lib.rs index 1db8e455..8973f82d 100644 --- a/demo/common/src/lib.rs +++ b/demo/common/src/lib.rs @@ -12,7 +12,7 @@ use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray}; use crate::ui::{BackgroundColor, DemoUI, UIAction}; -use crate::window::{CameraTransform, Event, Mode, Keycode, SVGPath, Window, WindowSize}; +use crate::window::{CameraTransform, Event, Keycode, SVGPath, View, Window, WindowSize}; use clap::{App, Arg}; use image::ColorType; use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32}; @@ -117,8 +117,6 @@ impl DemoApp where W: Window { options.command_line_overrides(); - let view_box_size = window.view_box_size(options.mode); - // Set up Rayon. let mut thread_pool_builder = ThreadPoolBuilder::new(); thread_pool_builder = options.adjust_thread_pool_settings(thread_pool_builder); @@ -130,14 +128,15 @@ impl DemoApp where W: Window { let scene_view_box = built_svg.scene.view_box; let monochrome_scene_color = built_svg.scene.monochrome_color(); + let viewport = window.viewport(options.mode.view(0)); let renderer = Renderer::new(device, resources, - RectI32::new(Point2DI32::default(), view_box_size), + viewport, window_size.device_size()); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); - scene_thread_proxy.set_drawable_size(view_box_size); + scene_thread_proxy.set_drawable_size(viewport.size()); - let camera = Camera::new(options.mode, scene_view_box, view_box_size); + let camera = Camera::new(options.mode, scene_view_box, viewport.size()); let ground_program = GroundProgram::new(&renderer.device, resources); let ground_solid_vertex_array = @@ -204,7 +203,10 @@ impl DemoApp where W: Window { // Begin drawing the scene. for render_scene_index in 0..render_scene_count { - self.window.make_current(self.ui.mode, Some(render_scene_index)); + let view = self.ui.mode.view(render_scene_index); + let viewport = self.window.viewport(view); + self.window.make_current(view); + self.renderer.set_viewport(viewport); self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0)); } @@ -258,8 +260,8 @@ impl DemoApp where W: Window { } Event::WindowResized(new_size) => { self.window_size = new_size; - let view_box_size = self.window.view_box_size(self.ui.mode); - self.scene_thread_proxy.set_drawable_size(view_box_size); + let viewport = self.window.viewport(self.ui.mode.view(0)); + self.scene_thread_proxy.set_drawable_size(viewport.size()); self.renderer.set_main_framebuffer_size(self.window_size.device_size()); self.dirty = true; } @@ -357,11 +359,11 @@ impl DemoApp where W: Window { let built_svg = load_scene(self.window.resource_loader(), svg_path); self.ui.message = get_svg_building_message(&built_svg); - let view_box_size = self.window.view_box_size(self.ui.mode); + let viewport_size = self.window.viewport(self.ui.mode.view(0)).size(); self.scene_view_box = built_svg.scene.view_box; self.monochrome_scene_color = built_svg.scene.monochrome_color(); - self.camera = Camera::new(self.ui.mode, self.scene_view_box, view_box_size); - self.scene_thread_proxy.load_scene(built_svg.scene, view_box_size); + self.camera = Camera::new(self.ui.mode, self.scene_view_box, viewport_size); + self.scene_thread_proxy.load_scene(built_svg.scene, viewport_size); self.dirty = true; } Event::User { message_type: event_id, message_data: expected_epoch } if @@ -385,7 +387,9 @@ impl DemoApp where W: Window { } pub fn draw_scene(&mut self, render_scene_index: u32) { - let viewport = self.window.make_current(self.ui.mode, Some(render_scene_index)); + let view = self.ui.mode.view(render_scene_index); + let viewport = self.window.viewport(view); + self.window.make_current(view); self.renderer.set_viewport(viewport); self.draw_environment(render_scene_index); self.render_vector_scene(); @@ -403,9 +407,6 @@ impl DemoApp where W: Window { let mut frame = self.current_frame.take().unwrap(); - let viewport = self.window.make_current(self.ui.mode, None); - self.renderer.set_viewport(viewport); - if self.pending_screenshot_path.is_some() { self.take_screenshot(); } @@ -420,10 +421,13 @@ impl DemoApp where W: Window { Some(frame.scene_rendering_times.iter().fold(zero, |sum, item| sum + *item)) }; self.renderer.debug_ui.add_sample(aggregate_stats, tile_time, total_rendering_time); + } - if self.options.ui != UIVisibility::None { - self.renderer.draw_debug_ui(); - } + if self.options.ui != UIVisibility::None { + let viewport = self.window.viewport(View::Mono); + self.window.make_current(View::Mono); + self.renderer.set_viewport(viewport); + self.renderer.draw_debug_ui(); } for ui_event in &frame.ui_events { @@ -449,8 +453,8 @@ impl DemoApp where W: Window { // // FIXME(pcwalton): This should really be an MVC setup. if self.camera.mode() != self.ui.mode { - let view_box_size = self.window.view_box_size(self.ui.mode); - self.camera = Camera::new(self.ui.mode, self.scene_view_box, view_box_size); + let viewport_size = self.window.viewport(self.ui.mode.view(0)).size(); + self.camera = Camera::new(self.ui.mode, self.scene_view_box, viewport_size); } for ui_event in frame.ui_events { @@ -903,6 +907,23 @@ impl Options { } } +#[derive(Clone, Copy, PartialEq)] +pub enum Mode { + TwoD = 0, + ThreeD = 1, + VR = 2, +} + +impl Mode { + pub fn viewport_count(self) -> usize { + match self { Mode::TwoD | Mode::ThreeD => 1, Mode::VR => 2 } + } + + pub fn view(self, viewport: u32) -> View { + match self { Mode::TwoD | Mode::ThreeD => View::Mono, Mode::VR => View::Stereo(viewport) } + } +} + #[derive(Clone, Copy, PartialEq)] pub enum UIVisibility { None, @@ -942,27 +963,27 @@ enum Camera { } impl Camera { - fn new(mode: Mode, view_box: RectF32, view_box_size: Point2DI32) -> Camera { + fn new(mode: Mode, view_box: RectF32, viewport_size: Point2DI32) -> Camera { if mode == Mode::TwoD { - Camera::new_2d(view_box, view_box_size) + Camera::new_2d(view_box, viewport_size) } else { - Camera::new_3d(mode, view_box, view_box_size) + Camera::new_3d(mode, view_box, viewport_size) } } - fn new_2d(view_box: RectF32, view_box_size: Point2DI32) -> Camera { - let scale = i32::min(view_box_size.x(), view_box_size.y()) as f32 * + fn new_2d(view_box: RectF32, viewport_size: Point2DI32) -> Camera { + let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 * scale_factor_for_view_box(view_box); - let origin = view_box_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5); + let origin = viewport_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5); Camera::TwoD(Transform2DF32::from_scale(&Point2DF32::splat(scale)).post_translate(origin)) } - fn new_3d(mode: Mode, view_box: RectF32, view_box_size: Point2DI32) -> Camera { + fn new_3d(mode: Mode, view_box: RectF32, viewport_size: Point2DI32) -> Camera { let viewport_count = mode.viewport_count(); - let aspect = view_box_size.x() as f32 / view_box_size.y() as f32; + let aspect = viewport_size.x() as f32 / viewport_size.y() as f32; let projection = Transform3DF32::from_perspective(FRAC_PI_4, aspect, NEAR_CLIP_PLANE, FAR_CLIP_PLANE); let transform = CameraTransform { - perspective: Perspective::new(&projection, view_box_size), + perspective: Perspective::new(&projection, viewport_size), view: Transform3DF32::default(), }; let transforms = iter::repeat(transform).take(viewport_count).collect(); @@ -980,10 +1001,10 @@ impl Camera { fn mode(&self) -> Mode { match *self { - Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR, - Camera::ThreeD { .. } => Mode::ThreeD, - Camera::TwoD { .. } => Mode::TwoD, - } + Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR, + Camera::ThreeD { .. } => Mode::ThreeD, + Camera::TwoD { .. } => Mode::TwoD, + } } } diff --git a/demo/common/src/window.rs b/demo/common/src/window.rs index ca3a243e..7a837bd0 100644 --- a/demo/common/src/window.rs +++ b/demo/common/src/window.rs @@ -25,8 +25,8 @@ pub trait Window { fn gl_version(&self) -> GLVersion; fn gl_default_framebuffer(&self) -> GLuint { 0 } fn mouse_position(&self) -> Point2DI32; - fn view_box_size(&self, mode: Mode) -> Point2DI32; - fn make_current(&mut self, mode: Mode, index: Option) -> RectI32; + fn viewport(&self, view: View) -> RectI32; + fn make_current(&mut self, view: View); fn present(&mut self); fn resource_loader(&self) -> &dyn ResourceLoader; fn create_user_event_id(&self) -> u32; @@ -79,6 +79,12 @@ impl WindowSize { } } +#[derive(Clone, Copy, Debug)] +pub enum View { + Mono, + Stereo(u32), +} + #[derive(Clone, Copy, Debug)] pub struct CameraTransform { // The perspective which converts from camera coordinates to display coordinates @@ -94,16 +100,3 @@ pub enum SVGPath { Resource(String), Path(PathBuf), } - -#[derive(Clone, Copy, PartialEq)] -pub enum Mode { - TwoD = 0, - ThreeD = 1, - VR = 2, -} - -impl Mode { - pub fn viewport_count(self) -> usize { - match self { Mode::TwoD | Mode::ThreeD => 1, Mode::VR => 2 } - } -} diff --git a/demo/native/src/main.rs b/demo/native/src/main.rs index f56d2269..6ec72b1b 100644 --- a/demo/native/src/main.rs +++ b/demo/native/src/main.rs @@ -14,7 +14,7 @@ use jemallocator; use nfd::Response; use pathfinder_demo::DemoApp; use pathfinder_demo::Options; -use pathfinder_demo::window::{Event, Keycode, Mode, SVGPath, Window, WindowSize}; +use pathfinder_demo::window::{Event, Keycode, SVGPath, View, Window, WindowSize}; use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::rect::RectI32; use pathfinder_gl::GLVersion; @@ -82,30 +82,23 @@ impl Window for WindowImpl { Point2DI32::new(mouse_state.x(), mouse_state.y()) } - fn view_box_size(&self, mode: Mode) -> Point2DI32 { - let (mut width, height) = self.window.drawable_size(); - if let Mode::VR = mode { + fn viewport(&self, view: View) -> RectI32 { + let (width, height) = self.window.drawable_size(); + let mut width = width as i32; + let height = height as i32; + let mut x_offset = 0; + if let View::Stereo(index) = view { width = width / 2; + x_offset = width * (index as i32); } - Point2DI32::new(width as i32, height as i32) + RectI32::new ( + Point2DI32::new(x_offset, 0), + Point2DI32::new(width, height), + ) } - fn make_current(&mut self, mode: Mode, index: Option) -> RectI32 { - let (width, height) = self.window.drawable_size(); - let mut width = width as i32; - let height = height as i32; - let mut offset_x = 0; - if let (Mode::VR, Some(index)) = (mode, index) { - width = width / 2; - offset_x = (index as i32) * width; - } - let size = Point2DI32::new(width, height); - let offset = Point2DI32::new(offset_x, 0); - + fn make_current(&mut self, _view: View) { self.window.gl_make_current(&self.gl_context).unwrap(); - unsafe { gl::Viewport(offset_x, 0, width, height); } - - RectI32::new(offset, size) } fn present(&mut self) {