Refactor editor into Application struct
This commit is contained in:
parent
a7a4fc82ac
commit
e8fdd82119
|
@ -1,51 +1,126 @@
|
||||||
|
use egui_wgpu_backend::RenderPass as EguiRenderPass;
|
||||||
|
use std::sync::Arc;
|
||||||
use egui_wgpu_backend::wgpu;
|
use egui_wgpu_backend::wgpu;
|
||||||
use egui_winit::winit::{
|
use egui_winit::winit::{
|
||||||
self,
|
self,
|
||||||
event::{Event, WindowEvent},
|
event::{Event, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::WindowBuilder,
|
window::WindowBuilder,
|
||||||
|
dpi::PhysicalSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
async fn get_device(
|
struct Application {
|
||||||
window: &winit::window::Window,
|
window: winit::window::Window,
|
||||||
) -> (
|
device: Arc<wgpu::Device>,
|
||||||
wgpu::Device,
|
queue: Arc<wgpu::Queue>,
|
||||||
wgpu::Queue,
|
size: winit::dpi::PhysicalSize<u32>,
|
||||||
wgpu::Surface,
|
surface: wgpu::Surface,
|
||||||
wgpu::SurfaceConfiguration,
|
config: wgpu::SurfaceConfiguration,
|
||||||
) {
|
egui_state: egui_winit::State,
|
||||||
let size = window.inner_size();
|
egui_ctx: egui::Context,
|
||||||
let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY);
|
egui_rp: EguiRenderPass,
|
||||||
let surface = unsafe { instance.create_surface(window) };
|
}
|
||||||
let adapter = instance
|
|
||||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
|
||||||
power_preference: wgpu::PowerPreference::LowPower,
|
|
||||||
compatible_surface: Some(&surface),
|
|
||||||
force_fallback_adapter: false,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let (device, queue) = adapter
|
|
||||||
.request_device(
|
|
||||||
&wgpu::DeviceDescriptor {
|
|
||||||
features: wgpu::Features::empty(),
|
|
||||||
limits: wgpu::Limits::default(),
|
|
||||||
label: None,
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let config = wgpu::SurfaceConfiguration {
|
|
||||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
|
||||||
format: surface.get_preferred_format(&adapter).unwrap(),
|
|
||||||
width: size.width,
|
|
||||||
height: size.height,
|
|
||||||
present_mode: wgpu::PresentMode::Mailbox,
|
|
||||||
};
|
|
||||||
surface.configure(&device, &config);
|
|
||||||
|
|
||||||
(device, queue, surface, config)
|
impl Application {
|
||||||
|
pub async fn new(window: winit::window::Window) -> Self {
|
||||||
|
let size = window.inner_size();
|
||||||
|
let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY);
|
||||||
|
let surface = unsafe { instance.create_surface(&window) };
|
||||||
|
let adapter = instance
|
||||||
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
|
power_preference: wgpu::PowerPreference::LowPower,
|
||||||
|
compatible_surface: Some(&surface),
|
||||||
|
force_fallback_adapter: false,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let (device, queue) = adapter
|
||||||
|
.request_device(
|
||||||
|
&wgpu::DeviceDescriptor {
|
||||||
|
features: wgpu::Features::empty(),
|
||||||
|
limits: wgpu::Limits::default(),
|
||||||
|
label: None,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let config = wgpu::SurfaceConfiguration {
|
||||||
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
|
format: surface.get_preferred_format(&adapter).unwrap(),
|
||||||
|
width: size.width,
|
||||||
|
height: size.height,
|
||||||
|
present_mode: wgpu::PresentMode::Mailbox,
|
||||||
|
};
|
||||||
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
|
let device = Arc::new(device);
|
||||||
|
let queue = Arc::new(queue);
|
||||||
|
|
||||||
|
let egui_state = egui_winit::State::new(4096, &window);
|
||||||
|
let egui_ctx = egui::Context::default();
|
||||||
|
let egui_rp = egui_wgpu_backend::RenderPass::new(&device, config.format, 1);
|
||||||
|
|
||||||
|
Self { window, device, queue, size, surface, config, egui_state, egui_ctx, egui_rp }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self) {
|
||||||
|
self.window.request_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_resize(&mut self, new_size: PhysicalSize<u32>) {
|
||||||
|
if new_size.width > 0 && new_size.height > 0 {
|
||||||
|
self.size = new_size;
|
||||||
|
self.config.width = new_size.width;
|
||||||
|
self.config.height = new_size.height;
|
||||||
|
self.surface.configure(&self.device, &self.config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(&mut self) {
|
||||||
|
match self.surface.get_current_texture() {
|
||||||
|
Err(wgpu::SurfaceError::Lost) => self.on_resize(self.size),
|
||||||
|
Err(e) => panic!("Surface error: {:?}", e),
|
||||||
|
Ok(surface_texture) => {
|
||||||
|
let raw_input = self.egui_state.take_egui_input(&self.window);
|
||||||
|
let output = self.egui_ctx.run(raw_input, |ctx| {
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
egui::Window::new("example_window").show(ctx, |ui| {
|
||||||
|
ui.heading("Hello world!");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
self.egui_state.handle_platform_output(
|
||||||
|
&self.window,
|
||||||
|
&self.egui_ctx,
|
||||||
|
output.platform_output,
|
||||||
|
);
|
||||||
|
|
||||||
|
let meshes = self.egui_ctx.tessellate(output.shapes);
|
||||||
|
|
||||||
|
let screen_desc = egui_wgpu_backend::ScreenDescriptor {
|
||||||
|
physical_width: self.config.width,
|
||||||
|
physical_height: self.config.height,
|
||||||
|
scale_factor: 1.0, // TODO ???
|
||||||
|
};
|
||||||
|
|
||||||
|
self.egui_rp.update_buffers(&self.device, &self.queue, &meshes, &screen_desc);
|
||||||
|
self.egui_rp
|
||||||
|
.add_textures(&self.device, &self.queue, &output.textures_delta)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let output_view = surface_texture.texture.create_view(&Default::default());
|
||||||
|
let mut cmds = self.device.create_command_encoder(&Default::default());
|
||||||
|
self.egui_rp
|
||||||
|
.execute(&mut cmds, &output_view, &meshes, &screen_desc, None)
|
||||||
|
.unwrap();
|
||||||
|
self.queue.submit(std::iter::once(cmds.finish()));
|
||||||
|
surface_texture.present();
|
||||||
|
self.egui_rp.remove_textures(output.textures_delta).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -56,69 +131,33 @@ fn main() {
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut egui_state = egui_winit::State::new(4096, &window);
|
let mut app = pollster::block_on(Application::new(window));
|
||||||
let egui_ctx = egui::Context::default();
|
|
||||||
|
|
||||||
let (device, queue, surface, surface_config) = pollster::block_on(get_device(&window));
|
|
||||||
|
|
||||||
let mut egui_rp = egui_wgpu_backend::RenderPass::new(&device, surface_config.format, 1);
|
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
println!("{:?}", event);
|
println!("{:?}", event);
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event, window_id } if window_id == window.id() => match event {
|
Event::RedrawRequested(window_id) if window_id == app.window.id() => {
|
||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
app.render();
|
||||||
event => {
|
|
||||||
egui_state.on_event(&egui_ctx, &event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::RedrawRequested(window_id) if window_id == window.id() => {
|
|
||||||
match surface.get_current_texture() {
|
|
||||||
// Err(wgpu::SurfaceError::Lost) => resize(),
|
|
||||||
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
|
|
||||||
Err(e) => eprintln!("Surface error: {:?}", e),
|
|
||||||
Ok(surface_texture) => {
|
|
||||||
let raw_input = egui_state.take_egui_input(&window);
|
|
||||||
let output = egui_ctx.run(raw_input, |ctx| {
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
|
||||||
ui.heading("Hello world!");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
egui_state.handle_platform_output(
|
|
||||||
&window,
|
|
||||||
&egui_ctx,
|
|
||||||
output.platform_output,
|
|
||||||
);
|
|
||||||
|
|
||||||
let meshes = egui_ctx.tessellate(output.shapes);
|
|
||||||
|
|
||||||
let screen_desc = egui_wgpu_backend::ScreenDescriptor {
|
|
||||||
physical_width: surface_config.width,
|
|
||||||
physical_height: surface_config.height,
|
|
||||||
scale_factor: 1.0, // TODO ???
|
|
||||||
};
|
|
||||||
|
|
||||||
egui_rp.update_buffers(&device, &queue, &meshes, &screen_desc);
|
|
||||||
egui_rp
|
|
||||||
.add_textures(&device, &queue, &output.textures_delta)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let output_view = surface_texture.texture.create_view(&Default::default());
|
|
||||||
let mut cmds = device.create_command_encoder(&Default::default());
|
|
||||||
egui_rp
|
|
||||||
.execute(&mut cmds, &output_view, &meshes, &screen_desc, None)
|
|
||||||
.unwrap();
|
|
||||||
queue.submit(std::iter::once(cmds.finish()));
|
|
||||||
surface_texture.present();
|
|
||||||
egui_rp.remove_textures(output.textures_delta).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
window.request_redraw();
|
app.update();
|
||||||
}
|
}
|
||||||
|
Event::WindowEvent { event, window_id } if window_id == app.window.id() => {
|
||||||
|
match &event {
|
||||||
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
|
WindowEvent::Resized(physical_size) => {
|
||||||
|
app.on_resize(*physical_size);
|
||||||
|
}
|
||||||
|
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||||
|
app.on_resize(**new_inner_size);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.egui_state.on_event(&app.egui_ctx, &event);
|
||||||
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue