use egui::Context;
use egui_wgpu::wgpu::{CommandEncoder, Device, Queue, StoreOp, TextureFormat, TextureView};
use egui_wgpu::{wgpu, Renderer, ScreenDescriptor};
use egui_winit::State;
use winit::event::WindowEvent;
use winit::window::Window;
pub struct Egui {
state: State,
renderer: Renderer,
}
impl Egui {
pub fn context(&self) -> &Context {
self.state.egui_ctx()
}
pub fn new(
device: &Device,
output_color_format: TextureFormat,
output_depth_format: Option<TextureFormat>,
msaa_samples: u32,
window: &Window,
) -> Egui {
let egui_context = Context::default();
let state = egui_winit::State::new(
egui_context,
egui::viewport::ViewportId::ROOT,
&window,
Some(window.scale_factor() as f32),
None,
Some(2 * 1024),
);
let renderer = Renderer::new(
device,
output_color_format,
output_depth_format,
msaa_samples,
true,
);
Egui { state, renderer }
}
pub fn handle_input(&mut self, window: &Window, event: &WindowEvent) {
let _ = self.state.on_window_event(window, event);
}
pub fn begin_frame(&mut self, window: &Window) {
let raw_input = self.state.take_egui_input(window);
self.state.egui_ctx().begin_pass(raw_input);
}
pub fn end_frame_and_draw(
&mut self,
device: &Device,
queue: &Queue,
encoder: &mut CommandEncoder,
window: &Window,
window_surface_view: &TextureView,
screen_descriptor: ScreenDescriptor,
) {
self.context()
.set_pixels_per_point(screen_descriptor.pixels_per_point);
let full_output = self.state.egui_ctx().end_pass();
self.state
.handle_platform_output(window, full_output.platform_output);
let primitives = self
.state
.egui_ctx()
.tessellate(full_output.shapes, self.state.egui_ctx().pixels_per_point());
for (id, image_delta) in &full_output.textures_delta.set {
self.renderer
.update_texture(device, queue, *id, image_delta);
}
self.renderer
.update_buffers(device, queue, encoder, &primitives, &screen_descriptor);
let render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: window_surface_view,
resolve_target: None,
ops: egui_wgpu::wgpu::Operations {
load: egui_wgpu::wgpu::LoadOp::Load,
store: StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
label: Some("egui main render pass"),
occlusion_query_set: None,
});
self.renderer.render(
&mut render_pass.forget_lifetime(),
&primitives,
&screen_descriptor,
);
for x in &full_output.textures_delta.free {
self.renderer.free_texture(x)
}
}
}