Skip to content

Commit

Permalink
Update winit, egui and vulkano (#53)
Browse files Browse the repository at this point in the history
* Updated winit and egui.

* Pulled from upstream

* Fix clippy

* Batched/Linear uploads (#56)

* Batch upload images, skip 2 copies per image

* Batch upload meshes, map only twice.

* lints

* Integrate packed fonts

* Lints again, oops

* Updated the vulkano from the upstream version

* clippy + add +nightly in run_checks.sh so that script works for everyone

* update ahash and image

* formatting

* updated egui to 0.26

* Make checks succeed

* Made checks succeed

* fixed example lints

* vulkano update

* fix vulkano in the examples

* Remove unnecessary feature of winit

* Update image to 0.25 to make deps.rs green again

* vulkano update + examples fix

* update egui - 0.26 -> 0.27

* update egui to 0.28.1

* make new nightly clippy compile

* Update dependencies

vulkano -> upstream, winit -> 0.30, egui -> 0.29

* add Cargo.lock

This is in order to avoid random breakage when Vulkano gets an update.

Gets removed as soon as Vulkano releases a new version.

* Update Vulkano

rename RecordingCommandBuffers and CommandBuffers back to AutoCommandBufferBuilder and their previous names

* Update Vulkano

Use PrimaryCommandBufferAbstract again

* Update Vulkano -> 0.35, egui -> 0.31

---------

Co-authored-by: Okko Hakola <[email protected]>
Co-authored-by: Aspen <[email protected]>
  • Loading branch information
3 people authored Feb 13, 2025
1 parent 00bd40b commit 0e2f347
Show file tree
Hide file tree
Showing 17 changed files with 4,049 additions and 569 deletions.
3,244 changes: 3,244 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ wayland = ["winit/wayland", "winit/wayland-dlopen", "egui-winit/wayland"]
x11 = ["winit/x11", "egui-winit/x11"]

[dependencies]
ahash = "0.8.3"
egui-winit = { version = "0.24", default-features = false }
egui = "0.24"
image = { version = "0.24.5", optional = true }
winit = { version = "0.28", default-features = false }
vulkano = "0.34"
vulkano-shaders = "0.34"
ahash = "0.8"
egui-winit = { version = "0.31", default-features = false }
egui = "0.31"
image = { version = "0.25", optional = true }
winit = { version = "0.30", default-features = false, features = [ "rwh_06" ] }
vulkano = { version = "0.35"}
vulkano-shaders = "0.35"

[dev-dependencies]
cgmath = "0.18.0"
egui_demo_lib = "0.24"
vulkano-util = "0.34"
egui_demo_lib = "0.31.0"
vulkano-util = { version = "0.35"}
282 changes: 165 additions & 117 deletions examples/demo_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,135 +7,183 @@
// notice may not be copied, modified, or distributed except
// according to those terms.

use egui_demo_lib::{ColorTest, DemoWindows};
use egui_winit_vulkano::{Gui, GuiConfig};
use vulkano_util::{
context::{VulkanoConfig, VulkanoContext},
window::{VulkanoWindows, WindowDescriptor},
};
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
application::ApplicationHandler, error::EventLoopError, event::WindowEvent,
event_loop::EventLoop, window::WindowId,
};

// Simply create egui demo apps to test everything works correctly.
// Creates two windows with different color formats for their swapchain.

pub fn main() {
// Winit event loop
let event_loop = EventLoop::new();
// Vulkano context
let context = VulkanoContext::new(VulkanoConfig::default());
// Vulkano windows (create one)
let mut windows = VulkanoWindows::default();
let window1 = windows.create_window(
&event_loop,
&context,
&WindowDescriptor {
title: String::from("egui_winit_vulkano SRGB"),
..WindowDescriptor::default()
},
|ci| {
ci.image_format = vulkano::format::Format::B8G8R8A8_SRGB;
ci.min_image_count = ci.min_image_count.max(2);
},
);
let window2 = windows.create_window(
&event_loop,
&context,
&WindowDescriptor {
title: String::from("egui_winit_vulkano UNORM"),
..WindowDescriptor::default()
},
|ci| {
ci.image_format = vulkano::format::Format::B8G8R8A8_UNORM;
ci.min_image_count = ci.min_image_count.max(2);
},
);
// Create gui as main render pass (no overlay means it clears the image each frame)
let mut gui1 = {
let renderer = windows.get_renderer_mut(window1).unwrap();
Gui::new(
&event_loop,
renderer.surface(),
renderer.graphics_queue(),
renderer.swapchain_format(),
GuiConfig { allow_srgb_render_target: true, ..GuiConfig::default() },
)
};
let mut gui2 = {
let renderer = windows.get_renderer_mut(window2).unwrap();
Gui::new(
&event_loop,
renderer.surface(),
renderer.graphics_queue(),
renderer.swapchain_format(),
GuiConfig::default(),
)
};
// Display the demo application that ships with egui.
let mut demo_app1 = egui_demo_lib::DemoWindows::default();
let mut demo_app2 = egui_demo_lib::DemoWindows::default();
let mut egui_test1 = egui_demo_lib::ColorTest::default();
let mut egui_test2 = egui_demo_lib::ColorTest::default();

event_loop.run(move |event, _, control_flow| {
for (wi, renderer) in windows.iter_mut() {
// Quick and ugly...
let gui = if *wi == window1 { &mut gui1 } else { &mut gui2 };
let demo_app = if *wi == window1 { &mut demo_app1 } else { &mut demo_app2 };
let egui_test = if *wi == window1 { &mut egui_test1 } else { &mut egui_test2 };
match &event {
Event::WindowEvent { event, window_id } if window_id == wi => {
// Update Egui integration so the UI works!
let _pass_events_to_game = !gui.update(event);
match event {
WindowEvent::Resized(_) => {
renderer.resize();
}
WindowEvent::ScaleFactorChanged { .. } => {
renderer.resize();
}
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
_ => (),
}
}
Event::RedrawRequested(window_id) if window_id == wi => {
// Set immediate UI in redraw here
gui.immediate_ui(|gui| {
let ctx = gui.context();
demo_app.ui(&ctx);

egui::Window::new("Colors").vscroll(true).show(&ctx, |ui| {
egui_test.ui(ui);
});
pub struct App {
context: VulkanoContext,
windows: VulkanoWindows,
window1: Option<Window>,
window2: Option<Window>,
}

pub struct Window {
id: WindowId,
gui: Gui,
demo_app: DemoWindows,
egui_test: ColorTest,
}

impl Default for App {
fn default() -> Self {
// Vulkano context
let context = VulkanoContext::new(VulkanoConfig::default());
// Vulkano windows (create one)
let windows = VulkanoWindows::default();

Self { context, windows, window1: None, window2: None }
}
}

impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
// Display the demo application that ships with egui.
let demo_app1 = DemoWindows::default();
let demo_app2 = DemoWindows::default();
let egui_test1 = ColorTest::default();
let egui_test2 = ColorTest::default();

let window1 = self.windows.create_window(
event_loop,
&self.context,
&WindowDescriptor {
title: String::from("egui_winit_vulkano SRGB"),
..WindowDescriptor::default()
},
|ci| {
ci.image_format = vulkano::format::Format::B8G8R8A8_SRGB;
ci.min_image_count = ci.min_image_count.max(2);
},
);

let window2 = self.windows.create_window(
event_loop,
&self.context,
&WindowDescriptor {
title: String::from("egui_winit_vulkano UNORM"),
..WindowDescriptor::default()
},
|ci| {
ci.image_format = vulkano::format::Format::B8G8R8A8_UNORM;
ci.min_image_count = ci.min_image_count.max(2);
},
);

// Create gui as main render pass (no overlay means it clears the image each frame)
let gui1 = {
let renderer = self.windows.get_renderer_mut(window1).unwrap();
Gui::new(
event_loop,
renderer.surface(),
renderer.graphics_queue(),
renderer.swapchain_format(),
GuiConfig { allow_srgb_render_target: true, ..GuiConfig::default() },
)
};

let gui2 = {
let renderer = self.windows.get_renderer_mut(window2).unwrap();
Gui::new(
event_loop,
renderer.surface(),
renderer.graphics_queue(),
renderer.swapchain_format(),
GuiConfig::default(),
)
};

self.window1 =
Some(Window { id: window1, gui: gui1, demo_app: demo_app1, egui_test: egui_test1 });

self.window2 =
Some(Window { id: window2, gui: gui2, demo_app: demo_app2, egui_test: egui_test2 });
}

fn window_event(
&mut self,
event_loop: &winit::event_loop::ActiveEventLoop,
window_id: winit::window::WindowId,
event: WindowEvent,
) {
let renderer = self.windows.get_renderer_mut(window_id).unwrap();

let w1 = self.window1.as_mut().unwrap();
let w2 = self.window2.as_mut().unwrap();

// Quick and ugly...
let gui = if window_id == w1.id { &mut w1.gui } else { &mut w2.gui };
let demo_app = if window_id == w1.id { &mut w1.demo_app } else { &mut w2.demo_app };
let egui_test = if window_id == w1.id { &mut w1.egui_test } else { &mut w2.egui_test };

// Update Egui integration so the UI works!
let _pass_events_to_game = !gui.update(&event);
match event {
WindowEvent::Resized(_) => {
renderer.resize();
}
WindowEvent::ScaleFactorChanged { .. } => {
renderer.resize();
}
WindowEvent::CloseRequested => {
event_loop.exit();
}
WindowEvent::RedrawRequested => {
// Set immediate UI in redraw here
gui.immediate_ui(|gui| {
let ctx = gui.context();
demo_app.ui(&ctx);

egui::Window::new("Colors").vscroll(true).show(&ctx, |ui| {
egui_test.ui(ui);
});
// Alternatively you could
// gui.begin_frame();
// let ctx = gui.context();
// demo_app.ui(&ctx);

// Render UI
// Acquire swapchain future
match renderer.acquire() {
Ok(future) => {
let after_future =
gui.draw_on_image(future, renderer.swapchain_image_view());
// Present swapchain
renderer.present(after_future, true);
}
Err(vulkano::VulkanError::OutOfDate) => {
renderer.resize();
}
Err(e) => panic!("Failed to acquire swapchain future: {}", e),
};
}
Event::MainEventsCleared => {
renderer.window().request_redraw();
}
_ => (),
});
// Alternatively you could
// gui.begin_frame();
// let ctx = gui.context();
// demo_app.ui(&ctx);

// Render UI
// Acquire swapchain future
match renderer.acquire(Some(std::time::Duration::from_millis(10)), |_| {}) {
Ok(future) => {
let after_future =
gui.draw_on_image(future, renderer.swapchain_image_view());
// Present swapchain
renderer.present(after_future, true);
}
Err(vulkano::VulkanError::OutOfDate) => {
renderer.resize();
}
Err(e) => panic!("Failed to acquire swapchain future: {}", e),
};
}
_ => (),
}
}

fn about_to_wait(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) {
for (_, renderer) in self.windows.iter_mut() {
renderer.window().request_redraw();
}
});
}
}

pub fn main() -> Result<(), EventLoopError> {
// Winit event loop
let event_loop = EventLoop::new().unwrap();

let mut app = App::default();

event_loop.run_app(&mut app)
}
Loading

0 comments on commit 0e2f347

Please sign in to comment.