From 29ef8b57e0a5421f534e32a2024ecc51c1dceee2 Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Tue, 9 Apr 2019 14:33:33 -0500 Subject: [PATCH] Use pathfinder directly for magicleap demo cube faces rather than using pathfinder_demo --- demo/magicleap/lre/PathfinderDemo.draft | 5 - demo/magicleap/lre/pipeline/lap/project.json | 2 +- .../lre/scenes/PathfinderDemo.design | 5 - .../lre/scenes/PathfinderDemo.scene.xml | 10 +- demo/magicleap/src/landscape.cpp | 26 ++- demo/magicleap/src/landscape.h | 2 +- demo/magicleap/src/lib.rs | 192 ++++++++++++++---- demo/magicleap/src/magicleap.rs | 14 +- 8 files changed, 196 insertions(+), 60 deletions(-) diff --git a/demo/magicleap/lre/PathfinderDemo.draft b/demo/magicleap/lre/PathfinderDemo.draft index 35c232e7..e87e27ab 100644 --- a/demo/magicleap/lre/PathfinderDemo.draft +++ b/demo/magicleap/lre/PathfinderDemo.draft @@ -32,7 +32,6 @@ - @@ -60,7 +59,6 @@ - @@ -90,7 +88,6 @@ - @@ -120,7 +117,6 @@ - @@ -150,7 +146,6 @@ - diff --git a/demo/magicleap/lre/pipeline/lap/project.json b/demo/magicleap/lre/pipeline/lap/project.json index b409d80a..0b2d85e4 100644 --- a/demo/magicleap/lre/pipeline/lap/project.json +++ b/demo/magicleap/lre/pipeline/lap/project.json @@ -28,7 +28,7 @@ "lap/types/file/wav" ] }, - "checkpoint-hash": "be7c32a96b1e398705b53fe9c7347469ec0e17c02fae27bd9e0d37a793e00b26292244892a424e35094dbc7348da159a0518e37e24c94eb33188f6756fe25737", + "checkpoint-hash": "c518bac956221c272b076912359b67d645f00f14a76f2f9cc3dee2f71cbe4aa1f702f8fd2d19a0b3b59af6ab227b83fedcbef788077d6757a9b5e691bd0f4398", "templates": [ "lap/template/converted_texture_from_bmp", "lap/template/converted_texture_from_tga", diff --git a/demo/magicleap/lre/scenes/PathfinderDemo.design b/demo/magicleap/lre/scenes/PathfinderDemo.design index 35c232e7..e87e27ab 100644 --- a/demo/magicleap/lre/scenes/PathfinderDemo.design +++ b/demo/magicleap/lre/scenes/PathfinderDemo.design @@ -32,7 +32,6 @@ - @@ -60,7 +59,6 @@ - @@ -90,7 +88,6 @@ - @@ -120,7 +117,6 @@ - @@ -150,7 +146,6 @@ - diff --git a/demo/magicleap/lre/scenes/PathfinderDemo.scene.xml b/demo/magicleap/lre/scenes/PathfinderDemo.scene.xml index 09523fc6..fa1d7425 100644 --- a/demo/magicleap/lre/scenes/PathfinderDemo.scene.xml +++ b/demo/magicleap/lre/scenes/PathfinderDemo.scene.xml @@ -1,9 +1,9 @@ - - - - - + + + + + diff --git a/demo/magicleap/src/landscape.cpp b/demo/magicleap/src/landscape.cpp index ae5bcc5c..482512c3 100644 --- a/demo/magicleap/src/landscape.cpp +++ b/demo/magicleap/src/landscape.cpp @@ -19,10 +19,15 @@ int main(int argc, char **argv) return myApp.run(); } -const int NUM_QUADS = 1; +const int NUM_QUADS = 6; const char* QUAD_NAMES[NUM_QUADS] = { - "quad1" + "quad1", + "quad2", + "quad3", + "quad4", + "quad5", + "quad6", }; PathfinderDemo::PathfinderDemo() { @@ -75,10 +80,11 @@ int PathfinderDemo::init() { return 1; } + for (int i=0; ifindNode(QUAD_NAMES[0], root_node)); + lumin::QuadNode* quad_node = lumin::QuadNode::CastFrom(prism_->findNode(QUAD_NAMES[i], root_node)); if (!quad_node) { - ML_LOG(Error, "Pathfinder Failed to get quad node"); + ML_LOG(Error, "Pathfinder Failed to get quad node %d.", i); abort(); return 1; } @@ -105,13 +111,17 @@ int PathfinderDemo::init() { eglMakeCurrent(dpy, surf, surf, ctx); // Initialize pathfinder - ML_LOG(Info, "Pathfinder initializing"); - pathfinder_ = magicleap_pathfinder_init(); - ML_LOG(Info, "Pathfinder initialized"); + if (!pathfinder_) { + ML_LOG(Info, "Pathfinder initializing"); + pathfinder_ = magicleap_pathfinder_init(dpy, surf); + ML_LOG(Info, "Pathfinder initialized"); + } // Render the SVG - magicleap_pathfinder_render(pathfinder_, dpy, surf, svg_filenames_[0]); + magicleap_pathfinder_render(pathfinder_, dpy, surf, svg_filenames_[i % svg_filecount_]); eglSwapBuffers(dpy, surf); + } + return 0; } diff --git a/demo/magicleap/src/landscape.h b/demo/magicleap/src/landscape.h index 3268e25e..e8fd466b 100644 --- a/demo/magicleap/src/landscape.h +++ b/demo/magicleap/src/landscape.h @@ -114,6 +114,6 @@ private: extern "C" uint64_t magicleap_pathfinder_svg_filecount(); extern "C" char** magicleap_pathfinder_svg_filenames(); -extern "C" void* magicleap_pathfinder_init(); +extern "C" void* magicleap_pathfinder_init(EGLDisplay, EGLSurface); extern "C" void magicleap_pathfinder_render(void*, EGLDisplay, EGLSurface, char*); extern "C" void magicleap_pathfinder_deinit(void*); diff --git a/demo/magicleap/src/lib.rs b/demo/magicleap/src/lib.rs index ef7356b2..c2a7dca2 100644 --- a/demo/magicleap/src/lib.rs +++ b/demo/magicleap/src/lib.rs @@ -7,6 +7,8 @@ use egl::EGLContext; use egl::EGLDisplay; use egl::EGLSurface; +use gl::types::GLuint; + use log::debug; use log::info; @@ -18,12 +20,35 @@ use pathfinder_demo::window::Mode; use pathfinder_demo::window::SVGPath; use pathfinder_demo::window::WindowSize; use pathfinder_geometry::basic::point::Point2DI32; +use pathfinder_geometry::basic::point::Point2DF32; +use pathfinder_geometry::basic::rect::RectI32; +use pathfinder_geometry::basic::transform2d::Transform2DF32; +use pathfinder_gl::GLDevice; +use pathfinder_gl::GLVersion; +use pathfinder_gpu::Device; +use pathfinder_gpu::resources::FilesystemResourceLoader; +use pathfinder_renderer::gpu::renderer::Renderer; +use pathfinder_simd::default::F32x4; +use pathfinder_renderer::scene::Scene; +use pathfinder_renderer::z_buffer::ZBuffer; +use pathfinder_renderer::gpu_data::BuiltScene; +use pathfinder_renderer::builder::SceneBuilder; +use pathfinder_renderer::builder::RenderOptions; +use pathfinder_renderer::builder::RenderTransform; +use pathfinder_svg::BuiltSVG; +use pathfinder_gpu::resources::ResourceLoader; +use rayon::ThreadPoolBuilder; + +use std::collections::HashMap; use std::ffi::CStr; use std::ffi::CString; use std::os::raw::c_char; use std::os::raw::c_void; +use usvg::Options as UsvgOptions; +use usvg::Tree; + mod c_api; mod magicleap; @@ -69,10 +94,11 @@ pub extern "C" fn magicleap_pathfinder_demo(egl_display: EGLDisplay, egl_context } const SVG_FILENAMES: &[*const c_char] = &[ - &b"svg/Ghostscript_Tiger.svg\0"[0], - &b"svg/paper.svg\0"[0], - &b"svg/julius-caesar-with-bg.svg\0"[0], &b"svg/nba-notext.svg\0"[0], + &b"svg/paper.svg\0"[0], + &b"svg/Ghostscript_Tiger.svg\0"[0], + &b"svg/julius-caesar-with-bg.svg\0"[0], + &b"svg/julius-caesar.svg\0"[0], &b"svg/pathfinder_logo.svg\0"[0], ]; @@ -86,8 +112,22 @@ pub extern "C" fn magicleap_pathfinder_svg_filenames() -> *const *const c_char { &SVG_FILENAMES[0] } +struct MagicLeapPathfinder { + surfaces: HashMap, + resources: FilesystemResourceLoader, +} + +struct MagicLeapPathfinderSurface { + surf: EGLSurface, + size: Point2DI32, + viewport: RectI32, + bg_color: F32x4, + renderer: Renderer, + scene: Scene, +} + #[no_mangle] -pub extern "C" fn magicleap_pathfinder_init() -> *mut c_void { +pub extern "C" fn magicleap_pathfinder_init(dpy: EGLDisplay, surf: EGLSurface) -> *mut c_void { unsafe { c_api::MLLoggingLog(c_api::MLLogLevel::Info, &b"Pathfinder Demo\0"[0], &b"Initializing\0"[0]) }; let tag = CString::new("Pathfinder Demo").unwrap(); @@ -97,42 +137,126 @@ pub extern "C" fn magicleap_pathfinder_init() -> *mut c_void { log::set_max_level(level); info!("Initialized logging"); - let window = MagicLeapLandscape::new(); - let window_size = window.window_size(); - let options = Options::default(); - info!("Initializing app"); - let app = DemoApp::new(window, window_size, options); - info!("Initialized app"); + let mut thread_pool_builder = ThreadPoolBuilder::new() + .build_global().unwrap(); + info!("Initialized rayon"); + + gl::load_with(|s| egl::get_proc_address(s) as *const c_void); + info!("Initialized gl"); - Box::into_raw(Box::new(app)) as *mut c_void + let pf = MagicLeapPathfinder { + surfaces: HashMap::new(), + resources: FilesystemResourceLoader::locate(), + }; + info!("Initialized pf"); + + Box::into_raw(Box::new(pf)) as *mut c_void } #[no_mangle] -pub unsafe extern "C" fn magicleap_pathfinder_render(app: *mut c_void, dpy: EGLDisplay, surf: EGLSurface, svg_filename: *const c_char) { - let app = app as *mut DemoApp; - if let Some(app) = app.as_mut() { - let mut width = 0; - let mut height = 0; - egl::query_surface(dpy, surf, egl::EGL_WIDTH, &mut width); - egl::query_surface(dpy, surf, egl::EGL_HEIGHT, &mut height); - gl::Viewport(0, 0, width, height); - let svg_filename = CStr::from_ptr(svg_filename).to_string_lossy().into_owned(); - info!("w={}, h={}.", width, height); - app.window.set_size(width, height); - let events = vec![ - Event::WindowResized(app.window.window_size()), - Event::OpenSVG(SVGPath::Resource(svg_filename)), - ]; - app.prepare_frame(events); - app.draw_scene(0); - app.finish_drawing_frame(); - app.prepare_frame(vec![]); - app.draw_scene(0); - app.finish_drawing_frame(); +pub unsafe extern "C" fn magicleap_pathfinder_render(pf: *mut c_void, dpy: EGLDisplay, surf: EGLSurface, svg_filename: *const c_char) { + let pf = pf as *mut MagicLeapPathfinder; + if let Some(pf) = pf.as_mut() { + let resources = &pf.resources; + let pfs = pf.surfaces.entry(surf).or_insert_with(|| { + let mut width = 0; + let mut height = 0; + let mut fbo = 0; + egl::query_surface(dpy, surf, egl::EGL_WIDTH, &mut width); + egl::query_surface(dpy, surf, egl::EGL_HEIGHT, &mut height); + gl::GetIntegerv(gl::DRAW_FRAMEBUFFER_BINDING, &mut fbo); + let device = GLDevice::new(GLVersion::GLES3, fbo as GLuint); + let size = Point2DI32::new(width, height); + let viewport = RectI32::new(Point2DI32::default(), size); + let renderer = Renderer::new(device, resources, viewport, size); + let bg_color = F32x4::new(0.5, 0.5, 0.5, 1.0); + let svg_filename = CStr::from_ptr(svg_filename).to_string_lossy(); + let data = resources.slurp(&*svg_filename).unwrap(); + let svg = BuiltSVG::from_tree(Tree::from_data(&data, &UsvgOptions::default()).unwrap()); + let mut scene = svg.scene; + scene.view_box = viewport.to_f32(); + MagicLeapPathfinderSurface { + surf, + size, + viewport, + bg_color, + renderer, + scene, + } + }); + pfs.renderer.set_main_framebuffer_size(pfs.size); + pfs.renderer.set_viewport(pfs.viewport); + pfs.renderer.device.bind_default_framebuffer(pfs.viewport); + pfs.renderer.device.clear(Some(pfs.bg_color), Some(1.0), Some(0)); + pfs.renderer.disable_depth(); + + let z_buffer = ZBuffer::new(pfs.scene.view_box); + + let scale = i32::min(pfs.viewport.size().x(), pfs.viewport.size().y()) as f32 / + f32::max(pfs.scene.bounds.size().x(), pfs.scene.bounds.size().y()); + let transform = Transform2DF32::from_translation(&pfs.scene.bounds.size().scale(-0.5)) + .post_mul(&Transform2DF32::from_scale(&Point2DF32::splat(scale))) + .post_mul(&Transform2DF32::from_translation(&pfs.viewport.size().to_f32().scale(0.5))); + + let render_options = RenderOptions { + transform: RenderTransform::Transform2D(transform), + dilation: Point2DF32::default(), + barrel_distortion: None, + }; + + let built_options = render_options.prepare(pfs.scene.bounds); + let quad = built_options.quad(); + + let built_objects = pfs.scene.build_objects(built_options, &z_buffer); + + let mut built_scene = BuiltScene::new(pfs.scene.view_box, &quad, pfs.scene.objects.len() as u32); + built_scene.shaders = pfs.scene.build_shaders(); + + let mut scene_builder = SceneBuilder::new(built_objects, z_buffer, pfs.scene.view_box); + built_scene.solid_tiles = scene_builder.build_solid_tiles(); + while let Some(batch) = scene_builder.build_batch() { + built_scene.batches.push(batch); + } + + pfs.renderer.render_scene(&built_scene); + + // let mut width = 0; + // let mut height = 0; + // let mut fbo = 0; + // egl::query_surface(dpy, surf, egl::EGL_WIDTH, &mut width); + // egl::query_surface(dpy, surf, egl::EGL_HEIGHT, &mut height); + // gl::GetIntegerv(gl::DRAW_FRAMEBUFFER_BINDING, &mut fbo); + // gl::Viewport(0, 0, width, height); + // let svg_filename = CStr::from_ptr(svg_filename).to_string_lossy().into_owned(); + // info!("svg={}, w={}, h={}, fbo={}.", svg_filename, width, height, fbo); + // if (app.window.dpy != dpy) || (app.window.surf != surf) { + // app.render_to_current_gl_context(); + // app.window.surf = surf; + // app.window.dpy = dpy; + // } + // app.window.fbo = fbo as GLuint; + // app.window.set_size(width, height); + // app.options.background = if let Background::Dark = app.options.background { + // Background::Light + // } else { + // Background::Dark + // }; + // let events = vec![ + // Event::WindowResized(app.window.window_size()), + // Event::OpenSVG(SVGPath::Resource(svg_filename)), + // ]; + // app.prepare_frame(events); + // app.draw_scene(0); + // app.finish_drawing_frame(); + // while app.dirty { + // app.prepare_frame(vec![]); + // app.draw_scene(0); + // app.finish_drawing_frame(); + // } } } #[no_mangle] -pub unsafe extern "C" fn magicleap_pathfinder_deinit(app: *mut c_void) { - Box::from_raw(app as *mut DemoApp); +pub unsafe extern "C" fn magicleap_pathfinder_deinit(pf: *mut c_void) { + Box::from_raw(pf as *mut MagicLeapPathfinder); } \ No newline at end of file diff --git a/demo/magicleap/src/magicleap.rs b/demo/magicleap/src/magicleap.rs index 3b55bac9..5b196f49 100644 --- a/demo/magicleap/src/magicleap.rs +++ b/demo/magicleap/src/magicleap.rs @@ -35,6 +35,7 @@ use egl; use egl::EGL_NO_SURFACE; use egl::EGLContext; use egl::EGLDisplay; +use egl::EGLSurface; use gl; use gl::types::GLuint; @@ -298,6 +299,9 @@ impl Drop for MagicLeapWindow { // Magic Leap landscape app pub struct MagicLeapLandscape { + pub dpy: EGLDisplay, + pub surf: EGLSurface, + pub fbo: GLuint, size: Point2DI32, resource_loader: FilesystemResourceLoader, } @@ -311,6 +315,10 @@ impl Window for MagicLeapLandscape { GLVersion::GLES3 } + fn gl_default_framebuffer(&self) -> GLuint { + self.fbo + } + fn mouse_position(&self) -> Point2DI32 { Point2DI32::new(0, 0) } @@ -342,11 +350,15 @@ impl Window for MagicLeapLandscape { } impl MagicLeapLandscape { - pub fn new() -> MagicLeapLandscape { + pub fn new(dpy: EGLDisplay, surf: EGLSurface) -> MagicLeapLandscape { gl::load_with(get_proc_address); let size = Point2DI32::new(512, 512); + let fbo = 0; let resource_loader = FilesystemResourceLoader::locate(); MagicLeapLandscape { + dpy, + surf, + fbo, size, resource_loader, }