From 3fd5b09a9401ac6655578e18ff7db31a32fb6f74 Mon Sep 17 00:00:00 2001 From: reo Date: Sat, 6 Sep 2025 11:52:49 +0300 Subject: [PATCH] Initial implementation of imgui support --- game/src/main.rs | 6 ++- glium_platform/Cargo.toml | 5 +- glium_platform/src/lib.rs | 2 +- glium_platform/src/platform.rs | 7 ++- glium_platform/src/render/debug_ui.rs | 77 +++++++++++++++++++++++++++ glium_platform/src/render/mod.rs | 2 + 6 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 glium_platform/src/render/debug_ui.rs diff --git a/game/src/main.rs b/game/src/main.rs index fe810dd..e72db32 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -44,7 +44,11 @@ impl System for RenderingTestSystem { )); } - fn update(&mut self, ctx: &mut SystemContext) {} + fn update(&mut self, ctx: &mut SystemContext) { + // if let Some(mut debug_ui) = ctx.platform_context.imgui_ui.as_ref().map(|ui| ui.borrow_mut()) { + // debug_ui.text("Hello World!"); + // } + } } fn main() { diff --git a/glium_platform/Cargo.toml b/glium_platform/Cargo.toml index c206b4e..ebae599 100644 --- a/glium_platform/Cargo.toml +++ b/glium_platform/Cargo.toml @@ -13,4 +13,7 @@ raidillon_core = { path = "../core" } raidillon_assets = { path = "../asset" } raidillon_ecs = { path = "../ecs" } winit = "0.30.12" -indexmap = "2.10.0" \ No newline at end of file +indexmap = "2.10.0" +imgui = "0.12.0" +imgui-winit-support = "0.13.0" +imgui-glium-renderer = "0.13.0" diff --git a/glium_platform/src/lib.rs b/glium_platform/src/lib.rs index 7d91b4d..6fd924f 100644 --- a/glium_platform/src/lib.rs +++ b/glium_platform/src/lib.rs @@ -5,6 +5,6 @@ pub mod gltf_loader; pub mod system; mod render; -pub use assets::{GliumAssetManager}; +pub use assets::GliumAssetManager; pub use platform::GliumPlatform; pub use system::RenderingSystem; diff --git a/glium_platform/src/platform.rs b/glium_platform/src/platform.rs index 478974f..bf1aeac 100644 --- a/glium_platform/src/platform.rs +++ b/glium_platform/src/platform.rs @@ -14,6 +14,7 @@ use winit::event::{Event, WindowEvent}; use raidillon_assets::{ModelManager, ModelManagerRef}; use raidillon_core::Engine; use crate::{GliumAssetManager}; +use crate::render::debug_ui::ImguiBridge; use crate::render::BasicMeshRenderingSystem; pub const MESH_RENDERER: &str = "mesh_renderer"; @@ -25,6 +26,7 @@ pub struct GliumPlatform { rendering_system_manager: RenderingSystemManager, asset_manager: ModelManagerRef, engine: Engine, + imgui_bridge: ImguiBridge, } impl Platform for GliumPlatform { @@ -47,13 +49,16 @@ impl Platform for GliumPlatform { Box::new(BasicMeshRenderingSystem::initialize(&display)) ); + let imgui_bridge = ImguiBridge::new(&display, &window).unwrap(); + Self { event_loop, window, display, rendering_system_manager, asset_manager, - engine + engine, + imgui_bridge, } } diff --git a/glium_platform/src/render/debug_ui.rs b/glium_platform/src/render/debug_ui.rs new file mode 100644 index 0000000..796be6d --- /dev/null +++ b/glium_platform/src/render/debug_ui.rs @@ -0,0 +1,77 @@ +use std::cell::RefCell; +use std::rc::Rc; +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::raw_window_handle::DisplayHandle; +use winit::window::Window; +use anyhow::Result; +use crate::RenderingSystem; +use crate::system::RenderingContext; +use glium::Frame; + +pub struct ImguiBridge { + imgui: ImguiContext, + platform: WinitPlatform, + renderer: ImguiGliumRenderer, +} + +impl ImguiBridge { + pub fn new(display: &Display, window: &Window) -> Result { + 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)?; + + Ok(Self { + imgui, + platform, + renderer, + }) + } + + pub fn render(&mut self, target: &mut Frame, window: &Window, build_ui: F) + where + F: FnOnce(&imgui::Ui), + { + let ui = self.imgui.frame(); + + build_ui(&ui); + + self.platform.prepare_render(ui, window); + let draw_data = self.imgui.render(); + + self + .renderer + .render(target, draw_data) + .expect("imgui rendering failed"); + } + + pub fn initialize_frame(&mut self) -> &mut imgui::Ui { + self.imgui.frame() + } + + pub fn finish_frame(&mut self, target: &mut Frame, window: &Window, ui: imgui::Ui) { + self.platform.prepare_render(&ui, window); + let draw_data = self.imgui.render(); + self.renderer.render(target, draw_data).expect("imgui rendering failed"); + } +} + +impl RenderingSystem for ImguiBridge { + fn render(&mut self, ctx: &mut RenderingContext) { + todo!() + } + + fn initialize(display: &Display) -> Self + where + Self: Sized, + { + todo!() + } +} \ No newline at end of file diff --git a/glium_platform/src/render/mod.rs b/glium_platform/src/render/mod.rs index 01028df..e98554f 100644 --- a/glium_platform/src/render/mod.rs +++ b/glium_platform/src/render/mod.rs @@ -1,2 +1,4 @@ mod basic; +pub mod debug_ui; + pub use basic::BasicMeshRenderingSystem; \ No newline at end of file