diff options
Diffstat (limited to 'src/eguictx.rs')
| -rw-r--r-- | src/eguictx.rs | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/eguictx.rs b/src/eguictx.rs new file mode 100644 index 0000000..572d352 --- /dev/null +++ b/src/eguictx.rs @@ -0,0 +1,143 @@ +use egui::{Context}; +use egui_wgpu::Renderer; +use egui_winit::{EventResponse, State}; +use wgpu::{CommandEncoder, CommandEncoderDescriptor, Operations, RenderPassDescriptor, TextureView}; +use winit::{event::WindowEvent, window::{Theme, Window}}; + +use crate::wgpuctx::WgpuCtx; + + +pub struct EguiCtx { + state: State, + renderer: Renderer, + context: Context, + ready: bool +} + +impl EguiCtx +{ + pub fn new( + window: &winit::window::Window, + wgpuctx: &WgpuCtx) + -> Self { + let ctx = egui::Context::default(); + + let viewport_id = ctx.viewport_id(); + let state = egui_winit::State::new( + ctx.clone(), + viewport_id, + window, + Some(window.scale_factor() as _), + Some(Theme::Light), + None); + + let renderer = Renderer::new( + wgpuctx.device(), + wgpuctx.surface_config().format, + egui_wgpu::RendererOptions { + depth_stencil_format: None, + msaa_samples: 1, + ..Default::default() + } + ); + + Self { + context: ctx, + state: state, + renderer: renderer, + ready: false + } + } + + pub fn context(&self) -> &Context + { self.state.egui_ctx() } + + pub fn window_event( + &mut self, + window: &Window, + event: &WindowEvent) + -> EventResponse + { + self.state.on_window_event(window, event) + } + + pub fn prepare( + &mut self, + window: &Window) + { + let raw_input = self.state.take_egui_input(window); + self.context().begin_pass(raw_input); + self.ready = true; + } + + pub fn present( + &mut self, + window: &Window, + wgpuctx: &WgpuCtx, + encoder: &mut CommandEncoder, + view: &TextureView) + + { + if !self.ready { + return; + } + self.ready = false; + + let full_output = self.context().end_pass(); + self.state.handle_platform_output(window, full_output.platform_output); + + let jobs = self.context().tessellate( + full_output.shapes, + full_output.pixels_per_point + ); + + let screen_descriptor = { + let view_size = view.texture().size(); + let (width, height) = (view_size.width, view_size.height); + egui_wgpu::ScreenDescriptor { + size_in_pixels: [width, height], + pixels_per_point: full_output.pixels_per_point + } + }; + + for (id, image_delta) in full_output.textures_delta.set { + self.renderer.update_texture(wgpuctx.device(), wgpuctx.queue(), id, &image_delta); + } + + self.renderer.update_buffers( + wgpuctx.device(), + wgpuctx.queue(), + encoder, + &jobs, + &screen_descriptor + ); + + { + let mut render_pass = encoder.begin_render_pass(&RenderPassDescriptor { + label: Some("EguiCtx render pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: view, + resolve_target: None, + ops: Operations { + load: wgpu::LoadOp::Load, + store: wgpu::StoreOp::Store + }, + depth_slice: None + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None + }); + + self.renderer.render( + &mut render_pass.forget_lifetime(), + &jobs, + &screen_descriptor + ); + } + + for id in &full_output.textures_delta.free { + self.renderer.free_texture(id); + } + } +} |
