use std::time::Instant; use glium::Display; use glium::glutin::surface::WindowSurface; use imgui::{Context as ImguiContext}; use imgui_winit_support::{HiDpiMode, WinitPlatform}; use imgui_glium_renderer::Renderer as ImguiGliumRenderer; use winit::window::Window; use winit::event::Event; use glium::Frame; use crate::RenderingSystem; use crate::system::RenderingContext; pub struct ImguiBridge { imgui: ImguiContext, platform: WinitPlatform, renderer: ImguiGliumRenderer, last_frame: Instant, rendered_this_frame: bool, } impl RenderingSystem for ImguiBridge { fn handle_event(&mut self, window: &mut Window, event: Event<()>) { self.platform.handle_event(self.imgui.io_mut(), window, &event); } fn prepare_frame(&mut self, window: &mut Window) { self.rendered_this_frame = false; let now = Instant::now(); self.imgui.io_mut().update_delta_time(now - self.last_frame); self.last_frame = now; self.platform .prepare_frame(self.imgui.io_mut(), window) .expect("Failed to prepare frame"); } fn render(&mut self, ctx: &mut RenderingContext) { if self.rendered_this_frame { return; } self.rendered_this_frame = true; let ui = self.imgui.frame(); ctx.debug_ui_buffer.borrow().write_buffer(&ui); self.platform.prepare_render(&ui, ctx.window); let draw_data = self.imgui.render(); if draw_data.total_vtx_count == 0 && draw_data.total_idx_count == 0 { return; } self.renderer.render(ctx.target, draw_data).expect("imgui rendering failed"); } fn initialize(display: &Display, window: &Window) -> Self { let mut imgui = ImguiContext::create(); imgui.set_ini_filename(None); let mut platform = WinitPlatform::new(&mut imgui); platform.attach_window(imgui.io_mut(), window, HiDpiMode::Default); imgui.fonts().add_font(&[imgui::FontSource::DefaultFontData { config: None }]); let renderer = ImguiGliumRenderer::new(&mut imgui, display).unwrap(); Self { imgui, platform, renderer, last_frame: Instant::now(), rendered_this_frame: false, } } }