Moved egui state to own struct, cleaned up a bunch of stuff

This commit is contained in:
Ben Wallis 2021-05-04 20:37:43 +01:00
parent 4d1da112c1
commit 8c57091401
13 changed files with 78 additions and 166 deletions

View File

@ -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

View File

@ -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<String>,
@ -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<String>,
pub egui_demo_app: egui_demo_lib::WrapApp, // TODO: Remove
pub repaint_signal: Option<Arc<ExampleRepaintSignal>>,
}
impl GlobalState {

View File

@ -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);

View File

@ -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 */
// );
}
}

View File

@ -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();

View File

@ -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,

View File

@ -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<ManualOwningScope<'frame, wgpu::CommandEncoder>>,
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<wgpu::CommandEncoder> {
// 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<ShadowPassDrawer> {
@ -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>>,
}

View File

@ -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<winit::event_loop::EventLoopProxy<CustomEvent>>);
/// 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<Box<dyn PlayState>> = 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));

View File

@ -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,
);
}
}

View File

@ -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<DebugInfo>) {
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));
});
}
}

View File

@ -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<CustomEvent>,
event: &winit::event::Event<()>,
window: &winit::window::Window,
) -> Option<Self> {
use conrod_winit::*;

View File

@ -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};

View File

@ -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<CustomEvent>;
pub type EventLoop = winit::event_loop::EventLoop<()>;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub enum KeyMouse {