diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index f758f76669..5b668ced75 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -66,6 +66,7 @@ egui_demo_lib = "0.11" # egui_wgpu_backend = "0.7" egui_wgpu_backend = { path = "../../egui_wgpu_backend" } egui_winit_platform = "0.6" +#egui_winit_platform = { path = "../../egui_winit_platform" } epi = "0.11" # ECS diff --git a/voxygen/src/lib.rs b/voxygen/src/lib.rs index bf7270f3f4..dedc9773c6 100644 --- a/voxygen/src/lib.rs +++ b/voxygen/src/lib.rs @@ -41,9 +41,9 @@ use crate::singleplayer::Singleplayer; use crate::{ audio::AudioFrontend, profile::Profile, - run::ExampleRepaintSignal, settings::Settings, window::{Event, Window}, + ui::egui::EguiState, }; use common::clock::Clock; use common_base::span; @@ -56,7 +56,7 @@ pub struct GlobalState { pub settings: Settings, pub profile: Profile, pub window: Window, - pub egui_platform: Platform, + pub egui_state: EguiState, pub lazy_init: scene::terrain::SpriteRenderContextLazy, pub audio: AudioFrontend, pub info_message: Option, @@ -70,8 +70,6 @@ pub struct GlobalState { // enter the game before confirmation of successful character load /// An error returned by Client that needs to be displayed by the UI pub client_error: Option, - pub egui_demo_app: egui_demo_lib::WrapApp, // TODO: Remove - pub repaint_signal: Option>, } impl GlobalState { diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 16ec3ddcbc..efb203ed6d 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -22,6 +22,7 @@ use egui::FontDefinitions; use egui_winit_platform::{Platform, PlatformDescriptor}; use std::panic; use tracing::{error, info, warn}; +use veloren_voxygen::ui::egui::EguiState; #[allow(clippy::manual_unwrap_or)] fn main() { @@ -187,19 +188,13 @@ fn main() { let lazy_init = SpriteRenderContext::new(window.renderer_mut()); - let mut egui_platform = Platform::new(PlatformDescriptor { - physical_width: window.window().inner_size().width as u32, - physical_height: window.window().inner_size().height as u32, - scale_factor: window.scale_factor(), - font_definitions: FontDefinitions::default(), - style: Default::default(), - }); + let mut egui_state = EguiState::new(&window); let global_state = GlobalState { audio, profile, window, - egui_platform, + egui_state, lazy_init, clock: Clock::new(std::time::Duration::from_secs_f64( 1.0 / get_fps(settings.graphics.max_fps) as f64, @@ -211,8 +206,6 @@ fn main() { i18n, clipboard, client_error: None, - egui_demo_app: egui_demo_lib::WrapApp::default(), - repaint_signal: None, }; run::run(global_state, event_loop); diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index a8788052b7..7f357141da 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -1,10 +1,8 @@ mod ui; use crate::{ - render::Renderer, scene::simple::{self as scene, Scene}, session::SessionState, - settings::Settings, window::Event as WinEvent, Direction, GlobalState, PlayState, PlayStateResult, }; @@ -269,11 +267,5 @@ impl PlayState for CharSelectionState { if let Some(mut ui_drawer) = third_pass.draw_ui() { self.char_selection_ui.render(&mut ui_drawer); }; - - // drawer.draw_egui( - // egui_platform, - // egui_paint_jobs, - // 1.0, /* TODO: pass in winit window scale factor */ - // ); } } diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 657a75982a..07ba1767ef 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -20,12 +20,12 @@ use client::{ use client_init::{ClientInit, Error as InitError, Msg as InitMsg}; use common::comp; use common_base::span; -use egui_wgpu_backend::epi::App; use scene::Scene; use std::sync::Arc; use tokio::runtime; use tracing::error; use ui::{Event as MainMenuEvent, MainMenuUi}; +use egui::CentralPanel; // TODO: show status messages for waiting on server creation, client init, and // pipeline creation (we can show progress of pipeline creation) @@ -322,7 +322,7 @@ impl PlayState for MainMenuState { fn name(&self) -> &'static str { "Title" } fn render(&mut self, global_state: &mut GlobalState) { - let mut renderer = global_state.window.renderer_mut(); + let renderer = global_state.window.renderer_mut(); let mut drawer = match renderer .start_recording_frame(self.scene.global_bind_group()) @@ -339,57 +339,9 @@ impl PlayState for MainMenuState { self.main_menu_ui.render(&mut ui_drawer); }; drop(third_pass); - - global_state.egui_platform.begin_frame(); - let mut app_output = epi::backend::AppOutput::default(); - let mut frame = epi::backend::FrameBuilder { - info: epi::IntegrationInfo { - web_info: None, - cpu_usage: None, // TODO - seconds_since_midnight: Some(seconds_since_midnight()), - native_pixels_per_point: Some(1.25 /* TODO */), - }, - tex_allocator: drawer.egui_renderpass(), - output: &mut app_output, - repaint_signal: global_state.repaint_signal.as_ref().unwrap().clone(), - } - .build(); - - // let ctx = &global_state.egui_platform.context(); - // egui::Window::new("Test Window") - // .default_width(200.0) - // .default_height(200.0) - // .show(ctx, |ui| { - // ui.label("Hello World!"); - // }); - - global_state - .egui_demo_app - .update(&global_state.egui_platform.context(), &mut frame); - - let (_output, paint_commands) = global_state.egui_platform.end_frame(); - let paint_jobs = global_state - .egui_platform - .context() - .tessellate(paint_commands); - // let frame_time = (Instant::now() - egui_start).as_secs_f64() as f32; - // previous_frame_time = Some(frame_time); - - drawer.draw_egui( - // renderer.egui_renderpass(), - &global_state.egui_platform, - &paint_jobs, - 1.25, /* TODO: pass in winit window scale factor */ - ); } } -/// Time of day as seconds since midnight. Used for clock in demo app. -pub fn seconds_since_midnight() -> f64 { - let time = chrono::Local::now().time(); - time.num_seconds_from_midnight() as f64 + 1e-9 * (time.nanosecond() as f64) -} - fn get_client_msg_error(e: client_init::Error, localized_strings: &LocalizationHandle) -> String { let localization = localized_strings.read(); diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 737df51935..c963d31285 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -364,7 +364,7 @@ impl Renderer { profiler.enable_debug_marker = mode.profiler_enabled; let egui_renderpass = - egui_wgpu_backend::RenderPass::new(&device, TextureFormat::Bgra8UnormSrgb); + egui_wgpu_backend::RenderPass::new(&*device, TextureFormat::Bgra8UnormSrgb); Ok(Self { device, diff --git a/voxygen/src/render/renderer/drawer.rs b/voxygen/src/render/renderer/drawer.rs index c00a4e64a1..eea548097f 100644 --- a/voxygen/src/render/renderer/drawer.rs +++ b/voxygen/src/render/renderer/drawer.rs @@ -15,7 +15,6 @@ use egui_wgpu_backend::ScreenDescriptor; use egui_winit_platform::Platform; use std::sync::Arc; use vek::Aabr; -use wgpu::TextureFormat; use wgpu_profiler::scope::{ManualOwningScope, OwningScope, Scope}; // Currently available pipelines @@ -70,7 +69,7 @@ struct RendererBorrow<'frame> { pub struct Drawer<'frame> { encoder: Option>, borrow: RendererBorrow<'frame>, - pub swap_tex: wgpu::SwapChainTexture, + swap_tex: wgpu::SwapChainTexture, globals: &'frame GlobalsBindGroup, // Texture and other info for taking a screenshot // Writes to this instead in the third pass if it is present @@ -131,10 +130,6 @@ impl<'frame> Drawer<'frame> { /// Get the render mode. pub fn render_mode(&self) -> &super::super::RenderMode { self.borrow.mode } - // pub fn encoder(&mut self) -> &mut ManualOwningScope { - // self.encoder.as_mut().unwrap() - // } - /// Returns None if the shadow renderer is not enabled at some level or the /// pipelines are not available yet pub fn shadow_pass(&mut self) -> Option { @@ -271,27 +266,21 @@ impl<'frame> Drawer<'frame> { } } - pub fn egui_pass(&mut self) -> EguiPassDrawer { - let render_pass = - egui_wgpu_backend::RenderPass::new(self.borrow.device, TextureFormat::Bgra8UnormSrgb); - - EguiPassDrawer { - render_pass, - borrow: &self.borrow, - } - } - pub fn draw_egui( &mut self, - //egui_renderpass: &mut egui_wgpu_backend::RenderPass, - platform: &Platform, - paint_jobs: &[egui::paint::ClippedMesh], + platform: &mut Platform, scale_factor: f32, ) { + let (_output, paint_commands) = platform.end_frame(); + + let paint_jobs = platform + .context() + .tessellate(paint_commands); + let screen_descriptor = ScreenDescriptor { physical_width: self.borrow.sc_desc.width, physical_height: self.borrow.sc_desc.height, - scale_factor, + scale_factor: scale_factor as f32, }; self.borrow.egui_render_pass.update_texture( @@ -310,10 +299,9 @@ impl<'frame> Drawer<'frame> { ); self.borrow.egui_render_pass.execute( - self.encoder.as_mut().unwrap(), - self.borrow.device, + &mut self.encoder.as_mut().unwrap(), &self.swap_tex.view, - paint_jobs, + &paint_jobs, &screen_descriptor, None, ); @@ -860,11 +848,6 @@ impl<'pass> ThirdPassDrawer<'pass> { } } -pub struct EguiPassDrawer<'pass> { - render_pass: egui_wgpu_backend::RenderPass, - borrow: &'pass RendererBorrow<'pass>, -} - pub struct UiDrawer<'pass_ref, 'pass: 'pass_ref> { render_pass: Scope<'pass_ref, wgpu::RenderPass<'pass>>, } diff --git a/voxygen/src/run.rs b/voxygen/src/run.rs index 41a304bb66..ca2d9efae3 100644 --- a/voxygen/src/run.rs +++ b/voxygen/src/run.rs @@ -9,23 +9,6 @@ use common_base::{no_guard_span, span, GuardlessSpan}; use std::{mem, time::Duration}; use tracing::debug; -pub struct ExampleRepaintSignal(std::sync::Mutex>); - -/// A custom event type for the winit app. -pub enum CustomEvent { - RequestRedraw, -} - -impl epi::RepaintSignal for ExampleRepaintSignal { - fn request_repaint(&self) { - self.0 - .lock() - .unwrap() - .send_event(CustomEvent::RequestRedraw) - .ok(); - } -} - pub fn run(mut global_state: GlobalState, event_loop: EventLoop) { // Set up the initial play state. let mut states: Vec> = vec![Box::new(MainMenuState::new(&mut global_state))]; @@ -44,15 +27,11 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) { let mut poll_span = None; let mut event_span = None; - global_state.repaint_signal = Some(std::sync::Arc::new(ExampleRepaintSignal( - std::sync::Mutex::new(event_loop.create_proxy()), - ))); - event_loop.run(move |event, _, control_flow| { // Continuously run loop since we handle sleeping *control_flow = winit::event_loop::ControlFlow::Poll; - global_state.egui_platform.handle_event(&event); + global_state.egui_state.platform.handle_event(&event); // Get events for the ui. if let Some(event) = ui::Event::try_from(&event, global_state.window.window()) { global_state.window.send_event(Event::Ui(event)); diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index 7c0df36c96..1b7bb37e78 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -1014,6 +1014,9 @@ impl PlayState for SessionState { self.interactable, ); + // Maintain egui (debug interface) + global_state.egui_state.maintain(&self.client.borrow(), &debug_info,); + // Look for changes in the localization files if global_state.i18n.reloaded() { hud_events.push(HudEvent::SettingsChange( @@ -1393,6 +1396,7 @@ impl PlayState for SessionState { /// This method should be called once per frame. fn render(&mut self, global_state: &mut GlobalState) { + let scale_factor = global_state.window.window().scale_factor() as f32; let renderer = global_state.window.renderer_mut(); let settings = &global_state.settings; @@ -1452,46 +1456,9 @@ impl PlayState for SessionState { drop(third_pass); - global_state.egui_platform.begin_frame(); - let mut app_output = epi::backend::AppOutput::default(); - let mut frame = epi::backend::FrameBuilder { - info: epi::IntegrationInfo { - web_info: None, - cpu_usage: None, // TODO - seconds_since_midnight: Some(seconds_since_midnight()), - native_pixels_per_point: Some(1.25 /* TODO */), - }, - tex_allocator: drawer.egui_renderpass(), - output: &mut app_output, - repaint_signal: global_state.repaint_signal.as_ref().unwrap().clone(), - } - .build(); - - // let ctx = &global_state.egui_platform.context(); - // egui::Window::new("Test Window") - // .default_width(200.0) - // .default_height(200.0) - // .show(ctx, |ui| { - // ui.label("Hello World!"); - // }); - - global_state - .egui_demo_app - .update(&global_state.egui_platform.context(), &mut frame); - - let (_output, paint_commands) = global_state.egui_platform.end_frame(); - let paint_jobs = global_state - .egui_platform - .context() - .tessellate(paint_commands); - // let frame_time = (Instant::now() - egui_start).as_secs_f64() as f32; - // previous_frame_time = Some(frame_time); - println!("drawing {} paint jobs from session", paint_jobs.len()); drawer.draw_egui( - // renderer.egui_renderpass(), - &global_state.egui_platform, - &paint_jobs, - 1.25, /* TODO: pass in winit window scale factor */ + &mut global_state.egui_state.platform, + scale_factor, ); } } diff --git a/voxygen/src/ui/egui/mod.rs b/voxygen/src/ui/egui/mod.rs new file mode 100644 index 0000000000..31b5ee7c88 --- /dev/null +++ b/voxygen/src/ui/egui/mod.rs @@ -0,0 +1,48 @@ +use egui_winit_platform::{Platform, PlatformDescriptor}; +use crate::window::Window; +use egui::FontDefinitions; +use winit::event::Event; +use client::Client; +use crate::hud::DebugInfo; + +pub struct EguiState { + pub platform: Platform, +} + +impl EguiState { + pub fn new(window: &Window) -> Self { + let platform = Platform::new(PlatformDescriptor { + physical_width: window.window().inner_size().width as u32, + physical_height: window.window().inner_size().height as u32, + scale_factor: window.scale_factor(), + font_definitions: FontDefinitions::default(), + style: Default::default(), + }); + + Self { + platform + } + } + + pub fn maintain(&mut self, + client: &Client, + debug_info: &Option) { + self.platform.begin_frame(); + + egui::Window::new("Test Window") + .default_width(200.0) + .default_height(200.0) + .show(&self.platform.context(), |ui| { + ui.heading("My egui Application"); + ui.horizontal(|ui| { + ui.label("Your name: "); + ui.text_edit_singleline(&mut "hello".to_owned()); + }); + ui.add(egui::Slider::new(&mut 99, 0..=120).text("age")); + if ui.button("Click each year").clicked() { + println!("button clicked"); + } + ui.label(format!("Hello '{}', age {}", "Ben", 99)); + }); + } +} \ No newline at end of file diff --git a/voxygen/src/ui/event.rs b/voxygen/src/ui/event.rs index cf93fca808..fa26c03eb4 100644 --- a/voxygen/src/ui/event.rs +++ b/voxygen/src/ui/event.rs @@ -1,4 +1,3 @@ -use crate::run::CustomEvent; use conrod_core::{event::Input, input::Button}; use vek::*; @@ -6,7 +5,7 @@ use vek::*; pub struct Event(pub Input); impl Event { pub fn try_from( - event: &winit::event::Event, + event: &winit::event::Event<()>, window: &winit::window::Window, ) -> Option { use conrod_winit::*; diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index 415a83be6f..2179b7fbb8 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -9,6 +9,7 @@ pub mod img_ids; pub mod fonts; pub mod ice; pub mod keyed_jobs; +pub mod egui; pub use event::Event; pub use graphic::{Graphic, Id as GraphicId, Rotation, SampleStrat, Transform}; diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index d2e16bc613..b96428cec0 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -1,7 +1,6 @@ use crate::{ controller::*, render::Renderer, - run::CustomEvent, settings::{ControlSettings, Settings}, ui, Error, }; @@ -319,7 +318,7 @@ pub enum Event { pub type MouseButton = winit::event::MouseButton; pub type PressState = winit::event::ElementState; -pub type EventLoop = winit::event_loop::EventLoop; +pub type EventLoop = winit::event_loop::EventLoop<()>; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] pub enum KeyMouse {