#gui #imgui #immediate #portable #gamedev


Egui immediate mode gui integration with winit and Vulkano

8 releases (breaking)

0.17.0 Apr 7, 2022
0.16.0 Mar 21, 2022
0.15.0 Feb 2, 2022
0.14.0 Dec 13, 2021
0.1.0 Sep 4, 2021

#172 in GUI

Download history 8/week @ 2022-03-08 44/week @ 2022-03-15 41/week @ 2022-03-22 12/week @ 2022-03-29 56/week @ 2022-04-05 15/week @ 2022-04-12 22/week @ 2022-04-19 57/week @ 2022-04-26 60/week @ 2022-05-03 136/week @ 2022-05-10 47/week @ 2022-05-17 49/week @ 2022-05-24 84/week @ 2022-05-31 26/week @ 2022-06-07 19/week @ 2022-06-14 18/week @ 2022-06-21

155 downloads per month
Used in bevy_vulkano


821 lines


Crates.io Apache CI

This is an egui integration for winit and vulkano.

You'll need a Vulkano target image as an input to which the UI will be painted. The aim of this is to allow a simple enough API to separate UI nicely out of your renderer and make it easy to build your immediate mode UI with Egui.


  1. Create your own renderer with Vulkano, and allow access to Vulkano's gfx queue Arc<Queue> and Vulkano's winit surface Arc<Surface<Window>>
  2. Create Gui integration with the surface & gfx queue
// Has its own renderpass (is_overlay = false means that the renderpass will clear the image, true means
// that the caller is responsible for clearing the image
let mut gui = Gui::new(renderer.surface(), renderer.queue(), false);
// Or with subpass
let mut gui = Gui::new_with_subpass(renderer.surface(), renderer.queue(), subpass);
  1. Inside your event loop, update gui integration with WindowEvent
  1. Fill immediate mode UI through the integration in Event::RedrawRequested before you render
gui.immediate_ui(|gui| {
    let ctx = gui.context();
    // Fill egui UI layout here

// Or

// fill egui layout...

// And when you render with `gui.draw_on_image(..)`, this will finish the egui frame
  1. Render gui via your renderer on any image or most likely on your swapchain images:
renderer.render(&mut gui); //... and inside render function:
// Draw, where
// future = acquired future from previous_frame_end.join(swapchain_acquire_future) and
// image_view_to_draw_on = the final image onto which you wish to render UI, usually e.g.
// self.final_images[image_num].clone() = one of your swap chain images.
let after_future = gui.draw_on_image(future, image_view_to_draw_on);

// Or if you created the integration with subpass
let cb = gui.draw_on_subpass_image(framebuffer_dimensions);
  1. Finish your render by waiting on the future gui.draw returns. See finish function in example renderers. Or in the case of subpass, execute your commands.

See the examples directory for a more wholesome example which uses Vulkano developers' frame system to organize rendering.

Remember, on Linux, you need to install following to run Egui

sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev


cargo run --example wholesome
cargo run --example minimal
cargo run --example subpass


This integration would not have been possible without the examples from vulkano-examples or egui_winit_ash_vk_mem.


~1M SLoC