From 99c2c050069114b22baea0e9c382197fc70cb493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Mon, 25 Oct 2021 19:46:54 +0200 Subject: [PATCH 1/8] add egui example --- README.md | 1 + templates/apps/egui/.gitignore.hbs | 10 + templates/apps/egui/Cargo.toml.hbs | 29 +++ templates/apps/egui/README.md | 5 + templates/apps/egui/gen/bin/desktop.rs.hbs | 4 + templates/apps/egui/src/lib.rs | 207 +++++++++++++++++++++ 6 files changed, 256 insertions(+) create mode 100644 templates/apps/egui/.gitignore.hbs create mode 100644 templates/apps/egui/Cargo.toml.hbs create mode 100644 templates/apps/egui/README.md create mode 100644 templates/apps/egui/gen/bin/desktop.rs.hbs create mode 100644 templates/apps/egui/src/lib.rs diff --git a/README.md b/README.md index 8cd2b6ad..25e70dbe 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ After some straightforward prompts, you'll be asked to select a template pack. T | --------- | --------------------------------------------------------------------------------------------------------------------------------- | | bevy | Minimal Bevy project derived from [sprite](https://github.com/bevyengine/bevy/blob/master/examples/2d/sprite.rs) example | | bevy-demo | Bevy [breakout](https://github.com/bevyengine/bevy/blob/master/examples/game/breakout.rs) demo | +| egui | Full egui + winit + wgpu example inspired by [egui_example](https://github.com/hasenbanck/egui_example) | | wgpu | Minimal wgpu project derived from [hello-triangle](https://github.com/gfx-rs/wgpu-rs/tree/master/examples/hello-triangle) example | | winit | Minimal winit project derived from [window](https://github.com/rust-windowing/winit/tree/master/examples/window) example | diff --git a/templates/apps/egui/.gitignore.hbs b/templates/apps/egui/.gitignore.hbs new file mode 100644 index 00000000..c3cb0ce4 --- /dev/null +++ b/templates/apps/egui/.gitignore.hbs @@ -0,0 +1,10 @@ +# Rust +target/ +**/*.rs.bk + +# cargo-mobile +.cargo/ +/gen + +# macOS +.DS_Store diff --git a/templates/apps/egui/Cargo.toml.hbs b/templates/apps/egui/Cargo.toml.hbs new file mode 100644 index 00000000..344ebe10 --- /dev/null +++ b/templates/apps/egui/Cargo.toml.hbs @@ -0,0 +1,29 @@ +[package] +name = "{{app.name}}" +version = "0.1.0" +authors = ["{{author}}"] +edition = "2018" +resolver = "2" + +[lib] +crate-type = ["staticlib", "cdylib", "rlib"] + +[[bin]] +name = "{{app.name}}-desktop" +path = "gen/bin/desktop.rs" + +[dependencies] +egui_wgpu_backend = { git = "https://github.com/hasenbanck/egui_wgpu_backend.git", rev = "961125e7bd2c71c5ead1d61a7ca7ffa8c0d17f48" } +chrono = "0.4" +pollster = "0.2" +egui = "0.15" +epi = "0.15" +wgpu = "0.11" +winit = "0.25" +egui_demo_lib = "0.15" +mobile-entry-point = "0.1" +egui-winit = "0.15" + +[target.'cfg(target_os = "android")'.dependencies] +log = "0.4.11" +ndk-glue = "0.3.0" diff --git a/templates/apps/egui/README.md b/templates/apps/egui/README.md new file mode 100644 index 00000000..b1544ec5 --- /dev/null +++ b/templates/apps/egui/README.md @@ -0,0 +1,5 @@ +# egui + +This is an example inspired by [this repo](https://github.com/hasenbanck/egui_example), using `egui`, `winit` and `wgpu` to run [egui_demo_app](https://github.com/emilk/egui/tree/master/egui_demo_app). + +To run this on desktop, just do `cargo run` like normal! For mobile, use `cargo android run` and `cargo apple run` respectively (or use `cargo android open` and `cargo apple open` to open in Android Studio and Xcode respectively). \ No newline at end of file diff --git a/templates/apps/egui/gen/bin/desktop.rs.hbs b/templates/apps/egui/gen/bin/desktop.rs.hbs new file mode 100644 index 00000000..df976373 --- /dev/null +++ b/templates/apps/egui/gen/bin/desktop.rs.hbs @@ -0,0 +1,4 @@ +fn main() { + #[cfg(not(any(target_os = "android", target_os = "ios")))] + {{snake-case app.name}}::start_app(); +} diff --git a/templates/apps/egui/src/lib.rs b/templates/apps/egui/src/lib.rs new file mode 100644 index 00000000..123696c1 --- /dev/null +++ b/templates/apps/egui/src/lib.rs @@ -0,0 +1,207 @@ +use std::iter; +use std::time::Instant; + +use epi::*; +use winit::event_loop::ControlFlow; +use winit::event::{Event::*}; +use egui_wgpu_backend::{RenderPass, ScreenDescriptor}; + +use mobile_entry_point::mobile_entry_point; +#[cfg(target_os = "android")] +use ndk_glue; + +/// A custom event type for the winit app. +#[derive(Debug)] +enum Event { + RequestRedraw, +} + +/// This is the repaint signal type that egui needs for requesting a repaint from another thread. +/// It sends the custom RequestRedraw event to the winit event loop. +struct ExampleRepaintSignal(std::sync::Mutex>); + +impl epi::RepaintSignal for ExampleRepaintSignal { + fn request_repaint(&self) { + self.0.lock().unwrap().send_event(Event::RequestRedraw).ok(); + } +} + +#[cfg(target_os = "android")] +fn wait_for_native_screen() { + log::info!("App started. Waiting for NativeScreen"); + loop { + match ndk_glue::native_window().as_ref() { + Some(_) => { + log::info!("NativeScreen Found:{:?}", ndk_glue::native_window()); + break; + } + None => (), + } + } +} + +/// A simple egui + wgpu + winit based example. +#[mobile_entry_point] +fn main() { + let event_loop = winit::event_loop::EventLoop::with_user_event(); + let window = winit::window::WindowBuilder::new() + .with_decorations(true) + .with_transparent(false) + .with_title("A fantastic window!") + .with_inner_size(winit::dpi::LogicalSize { + width: 128.0, + height: 128.0, + }) + .build(&event_loop) + .unwrap(); + + #[cfg(target_os = "android")] + wait_for_native_screen(); + + let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY); + + let surface = unsafe { instance.create_surface(&window) }; + + // WGPU 0.11+ support force fallback (if HW implementation not supported), set it to true or false (optional). + let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::HighPerformance, + compatible_surface: Some(&surface), + force_fallback_adapter: false, + })) + .unwrap(); + + let (device, queue) = pollster::block_on(adapter.request_device( + &wgpu::DeviceDescriptor { + features: wgpu::Features::default(), + limits: wgpu::Limits::default(), + label: None, + }, + None, + )) + .unwrap(); + + let size = window.inner_size(); + let surface_format = surface.get_preferred_format(&adapter).unwrap(); + let mut surface_config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: surface_format, + width: size.width as u32, + height: size.height as u32, + present_mode: wgpu::PresentMode::Mailbox, + }; + surface.configure(&device, &surface_config); + + let repaint_signal = std::sync::Arc::new(ExampleRepaintSignal(std::sync::Mutex::new( + event_loop.create_proxy(), + ))); + + + // We use the egui_wgpu_backend crate as the render backend. + let mut egui_rpass = RenderPass::new(&device, surface_format, 1); + + // Display the demo application that ships with egui. + let mut demo_app = egui_demo_lib::WrapApp::default(); + + let mut previous_frame_time = None; + + let mut state = egui_winit::State::new(&window); + let mut ctx = egui::CtxRef::default(); + + event_loop.run(move |event, _, control_flow| { + let mut redraw = || { + let output_frame = match surface.get_current_texture() { + Ok(frame) => frame, + Err(e) => { + eprintln!("Dropped frame with error: {}", e); + return; + } + }; + let output_view = output_frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + + let egui_start = Instant::now(); + let raw_input: egui::RawInput = state.take_egui_input(&window); + ctx.begin_frame(raw_input); + let mut app_output = epi::backend::AppOutput::default(); + + let mut frame = epi::backend::FrameBuilder { + info: epi::IntegrationInfo { + name: "egui_winit", + web_info: None, + cpu_usage: previous_frame_time, + native_pixels_per_point: Some(window.scale_factor() as _), + prefer_dark_mode: None, + }, + tex_allocator: &mut egui_rpass, + output: &mut app_output, + repaint_signal: repaint_signal.clone(), + } + .build(); + + // Draw the demo application. + demo_app.update(&ctx, &mut frame); + + // End the UI frame. We could now handle the output and draw the UI with the backend. + let (_output, paint_commands) = ctx.end_frame(); + let paint_jobs = ctx.tessellate(paint_commands); + + let frame_time = (Instant::now() - egui_start).as_secs_f64() as f32; + previous_frame_time = Some(frame_time); + + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("encoder"), + }); + + // Upload all resources for the GPU. + let screen_descriptor = ScreenDescriptor { + physical_width: surface_config.width, + physical_height: surface_config.height, + scale_factor: window.scale_factor() as f32, + }; + egui_rpass.update_texture(&device, &queue, &ctx.texture()); + egui_rpass.update_user_textures(&device, &queue); + egui_rpass.update_buffers(&device, &queue, &paint_jobs, &screen_descriptor); + + // Record all render passes. + egui_rpass + .execute( + &mut encoder, + &output_view, + &paint_jobs, + &screen_descriptor, + Some(wgpu::Color::BLACK), + ) + .unwrap(); + // Submit the commands. + queue.submit(iter::once(encoder.finish())); + + // Redraw egui + output_frame.present(); + }; + match event { + RedrawRequested(..) | UserEvent(Event::RequestRedraw) => { + redraw(); + } + MainEventsCleared => { + repaint_signal.request_repaint(); + } + WindowEvent { event, .. } => { + match event { + winit::event::WindowEvent::Resized(size) => { + surface_config.width = size.width; + surface_config.height = size.height; + surface.configure(&device, &surface_config); + }, + winit::event::WindowEvent::CloseRequested => { + *control_flow = ControlFlow::Exit; + }, + _ => () + }; + state.on_event(&ctx, &event); + repaint_signal.request_repaint(); + }, + _ => (), + } + }); +} From 549adddbfa9d1544cfec28b8a607c8cf4e46de7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Mon, 25 Oct 2021 21:50:36 +0200 Subject: [PATCH 2/8] fix egui template on desktop --- templates/apps/egui/src/lib.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/templates/apps/egui/src/lib.rs b/templates/apps/egui/src/lib.rs index 123696c1..16896718 100644 --- a/templates/apps/egui/src/lib.rs +++ b/templates/apps/egui/src/lib.rs @@ -48,9 +48,9 @@ fn main() { .with_decorations(true) .with_transparent(false) .with_title("A fantastic window!") - .with_inner_size(winit::dpi::LogicalSize { - width: 128.0, - height: 128.0, + .with_inner_size(winit::dpi::PhysicalSize { + width: 1280.0, + height: 720.0, }) .build(&event_loop) .unwrap(); @@ -108,6 +108,8 @@ fn main() { let mut ctx = egui::CtxRef::default(); event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + let mut redraw = || { let output_frame = match surface.get_current_texture() { Ok(frame) => frame, @@ -180,12 +182,9 @@ fn main() { output_frame.present(); }; match event { - RedrawRequested(..) | UserEvent(Event::RequestRedraw) => { + RedrawRequested(..) | UserEvent(Event::RequestRedraw) | MainEventsCleared => { redraw(); } - MainEventsCleared => { - repaint_signal.request_repaint(); - } WindowEvent { event, .. } => { match event { winit::event::WindowEvent::Resized(size) => { @@ -196,10 +195,10 @@ fn main() { winit::event::WindowEvent::CloseRequested => { *control_flow = ControlFlow::Exit; }, - _ => () + _ => { + state.on_event(&ctx, &event); + } }; - state.on_event(&ctx, &event); - repaint_signal.request_repaint(); }, _ => (), } From ff8916eaf39f205c23d3a7d872327bc56e7e5d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Thu, 28 Oct 2021 23:16:49 +0200 Subject: [PATCH 3/8] bump egui_wgpu_backend to 0.14 in egui template --- templates/apps/egui/Cargo.toml.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/apps/egui/Cargo.toml.hbs b/templates/apps/egui/Cargo.toml.hbs index 344ebe10..27400d26 100644 --- a/templates/apps/egui/Cargo.toml.hbs +++ b/templates/apps/egui/Cargo.toml.hbs @@ -13,7 +13,7 @@ name = "{{app.name}}-desktop" path = "gen/bin/desktop.rs" [dependencies] -egui_wgpu_backend = { git = "https://github.com/hasenbanck/egui_wgpu_backend.git", rev = "961125e7bd2c71c5ead1d61a7ca7ffa8c0d17f48" } +egui_wgpu_backend = "0.14" chrono = "0.4" pollster = "0.2" egui = "0.15" From a394f85ee69dfcddcaff83171f82ce4366681c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Sat, 30 Oct 2021 11:01:40 +0200 Subject: [PATCH 4/8] egui template: handle Resumed/Suspended events, start without a surface on Android --- templates/apps/egui/Cargo.toml.hbs | 4 + templates/apps/egui/src/lib.rs | 210 ++++++++++++++++------------- 2 files changed, 121 insertions(+), 93 deletions(-) diff --git a/templates/apps/egui/Cargo.toml.hbs b/templates/apps/egui/Cargo.toml.hbs index 27400d26..2a0ae01f 100644 --- a/templates/apps/egui/Cargo.toml.hbs +++ b/templates/apps/egui/Cargo.toml.hbs @@ -25,5 +25,9 @@ mobile-entry-point = "0.1" egui-winit = "0.15" [target.'cfg(target_os = "android")'.dependencies] +android_logger = "0.10" log = "0.4.11" ndk-glue = "0.3.0" + +[target.'cfg(not(target_os = "android"))'.dependencies] +simple_logger = "1.11.0" diff --git a/templates/apps/egui/src/lib.rs b/templates/apps/egui/src/lib.rs index 16896718..62a7bda1 100644 --- a/templates/apps/egui/src/lib.rs +++ b/templates/apps/egui/src/lib.rs @@ -16,6 +16,9 @@ enum Event { RequestRedraw, } +static INITIAL_WIDTH: u32 = 1280; +static INITIAL_HEIGHT: u32 = 720; + /// This is the repaint signal type that egui needs for requesting a repaint from another thread. /// It sends the custom RequestRedraw event to the winit event loop. struct ExampleRepaintSignal(std::sync::Mutex>); @@ -27,45 +30,42 @@ impl epi::RepaintSignal for ExampleRepaintSignal { } #[cfg(target_os = "android")] -fn wait_for_native_screen() { - log::info!("App started. Waiting for NativeScreen"); - loop { - match ndk_glue::native_window().as_ref() { - Some(_) => { - log::info!("NativeScreen Found:{:?}", ndk_glue::native_window()); - break; - } - None => (), - } - } +fn init_logging() { + android_logger::init_once( + android_logger::Config::default() + .with_min_level(log::Level::Trace) + .with_tag("{{app.name}}"), + ); +} + +#[cfg(not(target_os = "android"))] +fn init_logging() { + simple_logger::SimpleLogger::new().init().unwrap(); } /// A simple egui + wgpu + winit based example. #[mobile_entry_point] fn main() { + init_logging(); let event_loop = winit::event_loop::EventLoop::with_user_event(); let window = winit::window::WindowBuilder::new() - .with_decorations(true) - .with_transparent(false) .with_title("A fantastic window!") - .with_inner_size(winit::dpi::PhysicalSize { - width: 1280.0, - height: 720.0, - }) + .with_inner_size(winit::dpi::LogicalSize::new(INITIAL_WIDTH, INITIAL_HEIGHT)) .build(&event_loop) .unwrap(); - #[cfg(target_os = "android")] - wait_for_native_screen(); - let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY); - let surface = unsafe { instance.create_surface(&window) }; + let mut surface = if cfg!(target_os = "android") { + None + } else { + Some(unsafe { instance.create_surface(&window) }) + }; // WGPU 0.11+ support force fallback (if HW implementation not supported), set it to true or false (optional). let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, - compatible_surface: Some(&surface), + compatible_surface: surface.as_ref(), force_fallback_adapter: false, })) .unwrap(); @@ -80,16 +80,24 @@ fn main() { )) .unwrap(); - let size = window.inner_size(); - let surface_format = surface.get_preferred_format(&adapter).unwrap(); + let surface_format = if let Some(surface) = &surface { + surface.get_preferred_format(&adapter).unwrap() + } else { + // if Surface is none, we're guaranteed to be on android + wgpu::TextureFormat::Rgba8UnormSrgb + }; + let mut surface_config = wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT, format: surface_format, - width: size.width as u32, - height: size.height as u32, + width: INITIAL_WIDTH, + height: INITIAL_HEIGHT, present_mode: wgpu::PresentMode::Mailbox, }; - surface.configure(&device, &surface_config); + + if let Some(surface) = &mut surface { + surface.configure(&device, &surface_config); + } let repaint_signal = std::sync::Arc::new(ExampleRepaintSignal(std::sync::Mutex::new( event_loop.create_proxy(), @@ -111,86 +119,102 @@ fn main() { *control_flow = ControlFlow::Wait; let mut redraw = || { - let output_frame = match surface.get_current_texture() { - Ok(frame) => frame, - Err(e) => { - eprintln!("Dropped frame with error: {}", e); - return; + if let Some(surface) = &surface { + let output_frame = match surface.get_current_texture() { + Ok(frame) => frame, + Err(e) => { + eprintln!("Dropped frame with error: {}", e); + return; + } + }; + let output_view = output_frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + + let egui_start = Instant::now(); + let raw_input: egui::RawInput = state.take_egui_input(&window); + ctx.begin_frame(raw_input); + let mut app_output = epi::backend::AppOutput::default(); + + let mut frame = epi::backend::FrameBuilder { + info: epi::IntegrationInfo { + name: "egui_winit", + web_info: None, + cpu_usage: previous_frame_time, + native_pixels_per_point: Some(window.scale_factor() as _), + prefer_dark_mode: None, + }, + tex_allocator: &mut egui_rpass, + output: &mut app_output, + repaint_signal: repaint_signal.clone(), } - }; - let output_view = output_frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - - let egui_start = Instant::now(); - let raw_input: egui::RawInput = state.take_egui_input(&window); - ctx.begin_frame(raw_input); - let mut app_output = epi::backend::AppOutput::default(); - - let mut frame = epi::backend::FrameBuilder { - info: epi::IntegrationInfo { - name: "egui_winit", - web_info: None, - cpu_usage: previous_frame_time, - native_pixels_per_point: Some(window.scale_factor() as _), - prefer_dark_mode: None, - }, - tex_allocator: &mut egui_rpass, - output: &mut app_output, - repaint_signal: repaint_signal.clone(), - } - .build(); + .build(); - // Draw the demo application. - demo_app.update(&ctx, &mut frame); + // Draw the demo application. + demo_app.update(&ctx, &mut frame); - // End the UI frame. We could now handle the output and draw the UI with the backend. - let (_output, paint_commands) = ctx.end_frame(); - let paint_jobs = ctx.tessellate(paint_commands); + // End the UI frame. We could now handle the output and draw the UI with the backend. + let (_output, paint_commands) = ctx.end_frame(); + let paint_jobs = ctx.tessellate(paint_commands); - let frame_time = (Instant::now() - egui_start).as_secs_f64() as f32; - previous_frame_time = Some(frame_time); + let frame_time = (Instant::now() - egui_start).as_secs_f64() as f32; + previous_frame_time = Some(frame_time); - let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: Some("encoder"), - }); + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("encoder"), + }); - // Upload all resources for the GPU. - let screen_descriptor = ScreenDescriptor { - physical_width: surface_config.width, - physical_height: surface_config.height, - scale_factor: window.scale_factor() as f32, + // Upload all resources for the GPU. + let screen_descriptor = ScreenDescriptor { + physical_width: surface_config.width, + physical_height: surface_config.height, + scale_factor: window.scale_factor() as f32, + }; + egui_rpass.update_texture(&device, &queue, &ctx.texture()); + egui_rpass.update_user_textures(&device, &queue); + egui_rpass.update_buffers(&device, &queue, &paint_jobs, &screen_descriptor); + + // Record all render passes. + egui_rpass + .execute( + &mut encoder, + &output_view, + &paint_jobs, + &screen_descriptor, + Some(wgpu::Color::BLACK), + ) + .unwrap(); + // Submit the commands. + queue.submit(iter::once(encoder.finish())); + + // Redraw egui + output_frame.present(); }; - egui_rpass.update_texture(&device, &queue, &ctx.texture()); - egui_rpass.update_user_textures(&device, &queue); - egui_rpass.update_buffers(&device, &queue, &paint_jobs, &screen_descriptor); - - // Record all render passes. - egui_rpass - .execute( - &mut encoder, - &output_view, - &paint_jobs, - &screen_descriptor, - Some(wgpu::Color::BLACK), - ) - .unwrap(); - // Submit the commands. - queue.submit(iter::once(encoder.finish())); - - // Redraw egui - output_frame.present(); }; match event { - RedrawRequested(..) | UserEvent(Event::RequestRedraw) | MainEventsCleared => { + RedrawRequested(..) | MainEventsCleared => { redraw(); } + Resumed => { + let s = unsafe { instance.create_surface(&window) }; + surface_config.format = s.get_preferred_format(&adapter).unwrap(); + s.configure(&device, &surface_config); + surface = Some(s); + } + Suspended => { + surface = None; + } WindowEvent { event, .. } => { match event { winit::event::WindowEvent::Resized(size) => { - surface_config.width = size.width; - surface_config.height = size.height; - surface.configure(&device, &surface_config); + if size.width != 0 && size.height != 0 { + // Recreate the swap chain with the new size + surface_config.width = size.width; + surface_config.height = size.height; + if let Some(surface) = &surface { + surface.configure(&device, &surface_config); + } + } }, winit::event::WindowEvent::CloseRequested => { *control_flow = ControlFlow::Exit; From a6783d3cf46f60ff65079ead247d1553464e01e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Sun, 31 Oct 2021 00:54:48 +0200 Subject: [PATCH 5/8] enable fullscreen in android by default --- .../platforms/android-studio/app/src/main/res/values/styles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/platforms/android-studio/app/src/main/res/values/styles.xml b/templates/platforms/android-studio/app/src/main/res/values/styles.xml index 9785e0c9..e47a20d8 100644 --- a/templates/platforms/android-studio/app/src/main/res/values/styles.xml +++ b/templates/platforms/android-studio/app/src/main/res/values/styles.xml @@ -3,6 +3,7 @@ From 5ce078a7b777ec229fff8f62cce49e845138ee5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Mon, 3 Jan 2022 21:20:29 +0100 Subject: [PATCH 6/8] update dependencies and adapt to winit=0.26 and egui=0.16 --- templates/apps/egui/Cargo.toml.hbs | 16 +++++++------- templates/apps/egui/src/lib.rs | 34 ++++++++++++++++-------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/templates/apps/egui/Cargo.toml.hbs b/templates/apps/egui/Cargo.toml.hbs index 2a0ae01f..1badd5f5 100644 --- a/templates/apps/egui/Cargo.toml.hbs +++ b/templates/apps/egui/Cargo.toml.hbs @@ -13,21 +13,21 @@ name = "{{app.name}}-desktop" path = "gen/bin/desktop.rs" [dependencies] -egui_wgpu_backend = "0.14" +egui_wgpu_backend = "0.16" chrono = "0.4" pollster = "0.2" -egui = "0.15" -epi = "0.15" -wgpu = "0.11" -winit = "0.25" -egui_demo_lib = "0.15" +egui = "0.16.1" +epi = "0.16" +wgpu = "0.12" +winit = "0.26" +egui_demo_lib = "0.16" mobile-entry-point = "0.1" -egui-winit = "0.15" +egui-winit = "0.16" [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.10" log = "0.4.11" -ndk-glue = "0.3.0" +ndk-glue = "0.5.0" [target.'cfg(not(target_os = "android"))'.dependencies] simple_logger = "1.11.0" diff --git a/templates/apps/egui/src/lib.rs b/templates/apps/egui/src/lib.rs index 62a7bda1..4d6a5ed4 100644 --- a/templates/apps/egui/src/lib.rs +++ b/templates/apps/egui/src/lib.rs @@ -1,10 +1,10 @@ use std::iter; use std::time::Instant; +use egui_wgpu_backend::{RenderPass, ScreenDescriptor}; use epi::*; +use winit::event::Event::*; use winit::event_loop::ControlFlow; -use winit::event::{Event::*}; -use egui_wgpu_backend::{RenderPass, ScreenDescriptor}; use mobile_entry_point::mobile_entry_point; #[cfg(target_os = "android")] @@ -23,7 +23,7 @@ static INITIAL_HEIGHT: u32 = 720; /// It sends the custom RequestRedraw event to the winit event loop. struct ExampleRepaintSignal(std::sync::Mutex>); -impl epi::RepaintSignal for ExampleRepaintSignal { +impl epi::backend::RepaintSignal for ExampleRepaintSignal { fn request_repaint(&self) { self.0.lock().unwrap().send_event(Event::RequestRedraw).ok(); } @@ -103,7 +103,6 @@ fn main() { event_loop.create_proxy(), ))); - // We use the egui_wgpu_backend crate as the render backend. let mut egui_rpass = RenderPass::new(&device, surface_format, 1); @@ -116,7 +115,7 @@ fn main() { let mut ctx = egui::CtxRef::default(); event_loop.run(move |event, _, control_flow| { - *control_flow = ControlFlow::Wait; + *control_flow = ControlFlow::Poll; let mut redraw = || { if let Some(surface) = &surface { @@ -134,9 +133,12 @@ fn main() { let egui_start = Instant::now(); let raw_input: egui::RawInput = state.take_egui_input(&window); ctx.begin_frame(raw_input); - let mut app_output = epi::backend::AppOutput::default(); - let mut frame = epi::backend::FrameBuilder { + let app_output = epi::backend::AppOutput { + ..Default::default() + }; + + let frame_data = epi::backend::FrameData { info: epi::IntegrationInfo { name: "egui_winit", web_info: None, @@ -144,14 +146,14 @@ fn main() { native_pixels_per_point: Some(window.scale_factor() as _), prefer_dark_mode: None, }, - tex_allocator: &mut egui_rpass, - output: &mut app_output, + output: app_output, repaint_signal: repaint_signal.clone(), - } - .build(); + }; + + let frame = Frame::new(frame_data); // Draw the demo application. - demo_app.update(&ctx, &mut frame); + demo_app.update(&ctx, &frame); // End the UI frame. We could now handle the output and draw the UI with the backend. let (_output, paint_commands) = ctx.end_frame(); @@ -170,7 +172,7 @@ fn main() { physical_height: surface_config.height, scale_factor: window.scale_factor() as f32, }; - egui_rpass.update_texture(&device, &queue, &ctx.texture()); + egui_rpass.update_texture(&device, &queue, &ctx.font_image()); egui_rpass.update_user_textures(&device, &queue); egui_rpass.update_buffers(&device, &queue, &paint_jobs, &screen_descriptor); @@ -215,15 +217,15 @@ fn main() { surface.configure(&device, &surface_config); } } - }, + } winit::event::WindowEvent::CloseRequested => { *control_flow = ControlFlow::Exit; - }, + } _ => { state.on_event(&ctx, &event); } }; - }, + } _ => (), } }); From 86570c94ac94de25cf84a9e6df48239917d3c1db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Mon, 3 Jan 2022 21:43:37 +0100 Subject: [PATCH 7/8] use utc timestamps in simple_logger and update dependencies to newst versions --- templates/apps/egui/Cargo.toml.hbs | 6 +++--- templates/apps/egui/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/apps/egui/Cargo.toml.hbs b/templates/apps/egui/Cargo.toml.hbs index 1badd5f5..0af3c56e 100644 --- a/templates/apps/egui/Cargo.toml.hbs +++ b/templates/apps/egui/Cargo.toml.hbs @@ -25,9 +25,9 @@ mobile-entry-point = "0.1" egui-winit = "0.16" [target.'cfg(target_os = "android")'.dependencies] -android_logger = "0.10" -log = "0.4.11" +android_logger = "0.10.1" +log = "0.4.14" ndk-glue = "0.5.0" [target.'cfg(not(target_os = "android"))'.dependencies] -simple_logger = "1.11.0" +simple_logger = "1.16.0" diff --git a/templates/apps/egui/src/lib.rs b/templates/apps/egui/src/lib.rs index 4d6a5ed4..ba0167d1 100644 --- a/templates/apps/egui/src/lib.rs +++ b/templates/apps/egui/src/lib.rs @@ -40,7 +40,7 @@ fn init_logging() { #[cfg(not(target_os = "android"))] fn init_logging() { - simple_logger::SimpleLogger::new().init().unwrap(); + simple_logger::SimpleLogger::new().with_utc_timestamps().init().unwrap(); } /// A simple egui + wgpu + winit based example. From 6fbfac6cbd62adfaf6bd9209b890d801bac19392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20St=C4=99pie=C5=84?= Date: Fri, 4 Feb 2022 22:29:36 +0100 Subject: [PATCH 8/8] [egui example] disable optional features for egui-winit breaking the build for ios --- templates/apps/egui/Cargo.toml.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/apps/egui/Cargo.toml.hbs b/templates/apps/egui/Cargo.toml.hbs index 0af3c56e..708fff8b 100644 --- a/templates/apps/egui/Cargo.toml.hbs +++ b/templates/apps/egui/Cargo.toml.hbs @@ -22,7 +22,7 @@ wgpu = "0.12" winit = "0.26" egui_demo_lib = "0.16" mobile-entry-point = "0.1" -egui-winit = "0.16" +egui-winit = { version = "0.16", default-features = false } [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.10.1"