use std::num::NonZeroU32; use glium::Surface; use glutin::{ config::ConfigTemplateBuilder, context::ContextAttributesBuilder, display::GetGlDisplay, prelude::*, surface::{SurfaceAttributesBuilder, WindowSurface}, }; use imgui_winit_support::winit::{dpi::LogicalSize, event_loop::EventLoop}; use raw_window_handle::HasWindowHandle; use winit::{ event::{Event, WindowEvent}, window::{Window, WindowAttributes}, }; const TITLE: &str = "Hello, imgui-rs!"; fn main() { // Common setup for creating a winit window and imgui context, not specifc // to this renderer at all except that glutin is used to create the window // since it will give us access to a GL context let (event_loop, window, display) = create_window(); let (mut winit_platform, mut imgui_context) = imgui_init(&window); // Create renderer from this crate let mut renderer = imgui_glium_renderer::Renderer::new(&mut imgui_context, &display) .expect("Failed to initialize renderer"); // Timer for FPS calculation let mut last_frame = std::time::Instant::now(); // Standard winit event loop #[allow(deprecated)] event_loop .run(move |event, window_target| match event { Event::NewEvents(_) => { let now = std::time::Instant::now(); imgui_context.io_mut().update_delta_time(now - last_frame); last_frame = now; } Event::AboutToWait => { winit_platform .prepare_frame(imgui_context.io_mut(), &window) .expect("Failed to prepare frame"); window.request_redraw(); } Event::WindowEvent { event: WindowEvent::RedrawRequested, .. } => { // Create frame for the all important `&imgui::Ui` let ui = imgui_context.frame(); // Draw our example content ui.show_demo_window(&mut true); // Setup for drawing let mut target = display.draw(); // Renderer doesn't automatically clear window target.clear_color_srgb(1.0, 1.0, 1.0, 1.0); // Perform rendering winit_platform.prepare_render(ui, &window); let draw_data = imgui_context.render(); renderer .render(&mut target, draw_data) .expect("Rendering failed"); target.finish().expect("Failed to swap buffers"); } Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => window_target.exit(), winit::event::Event::WindowEvent { event: winit::event::WindowEvent::Resized(new_size), .. } => { if new_size.width > 0 && new_size.height > 0 { display.resize((new_size.width, new_size.height)); } winit_platform.handle_event(imgui_context.io_mut(), &window, &event); } event => { winit_platform.handle_event(imgui_context.io_mut(), &window, &event); } }) .expect("EventLoop error"); } fn create_window() -> (EventLoop<()>, Window, glium::Display) { let event_loop = EventLoop::new().expect("Failed to create EventLoop"); let window_attributes = WindowAttributes::default() .with_title(TITLE) .with_inner_size(LogicalSize::new(1024, 768)); let (window, cfg) = glutin_winit::DisplayBuilder::new() .with_window_attributes(Some(window_attributes.clone())) .build(&event_loop, ConfigTemplateBuilder::new(), |mut configs| { configs.next().unwrap() }) .expect("Failed to create OpenGL window"); let window = window.unwrap(); let context_attribs = ContextAttributesBuilder::new().build(Some(window.window_handle().unwrap().as_raw())); let context = unsafe { cfg.display() .create_context(&cfg, &context_attribs) .expect("Failed to create OpenGL context") }; let surface_attribs = SurfaceAttributesBuilder::::new().build( window.window_handle().unwrap().as_raw(), NonZeroU32::new(1024).unwrap(), NonZeroU32::new(768).unwrap(), ); let surface = unsafe { cfg.display() .create_window_surface(&cfg, &surface_attribs) .expect("Failed to create OpenGL surface") }; let context = context .make_current(&surface) .expect("Failed to make OpenGL context current"); let display = glium::Display::from_context_surface(context, surface) .expect("Failed to create glium Display"); (event_loop, window, display) } fn imgui_init(window: &Window) -> (imgui_winit_support::WinitPlatform, imgui::Context) { let mut imgui_context = imgui::Context::create(); imgui_context.set_ini_filename(None); let mut winit_platform = imgui_winit_support::WinitPlatform::new(&mut imgui_context); let dpi_mode = imgui_winit_support::HiDpiMode::Default; winit_platform.attach_window(imgui_context.io_mut(), window, dpi_mode); imgui_context .fonts() .add_font(&[imgui::FontSource::DefaultFontData { config: None }]); (winit_platform, imgui_context) }