Merge branch 'feat/egui' into 'main'
feat: add init egui impl See merge request zoey/vk-rs!2
This commit is contained in:
commit
ae09e61f40
4 changed files with 799 additions and 55 deletions
724
Cargo.lock
generated
724
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||
egui.workspace = true
|
||||
ash.workspace = true
|
||||
ash-window.workspace = true
|
||||
color-eyre.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
winit.workspace = true
|
||||
|
|
@ -17,3 +18,4 @@ gfx_hal = { path = "../gfx_hal" }
|
|||
renderer = { path = "../renderer" }
|
||||
resource_manager = { path = "../resource_manager" }
|
||||
clap = { version = "4.5.34", features = ["derive"] }
|
||||
egui-winit = "0.31.1"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ use std::{
|
|||
|
||||
use ash::vk;
|
||||
use clap::Parser;
|
||||
use egui::{Context, ViewportId};
|
||||
use egui_winit::State;
|
||||
use gfx_hal::{
|
||||
device::Device, error::GfxHalError, instance::Instance, instance::InstanceConfig,
|
||||
physical_device::PhysicalDevice, queue::Queue, surface::Surface,
|
||||
|
|
@ -57,6 +59,10 @@ struct Application {
|
|||
// Renderer
|
||||
renderer: Renderer,
|
||||
|
||||
egui_ctx: Context,
|
||||
egui_winit: State,
|
||||
egui_app: EditorUI,
|
||||
|
||||
// Windowing
|
||||
window: Arc<Window>, // Use Arc for potential multi-threading later
|
||||
|
||||
|
|
@ -65,6 +71,19 @@ struct Application {
|
|||
last_frame_time: Instant,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct EditorUI {}
|
||||
|
||||
impl EditorUI {
|
||||
fn title() -> String {
|
||||
"engine".to_string()
|
||||
}
|
||||
|
||||
fn build_ui(&mut self, ctx: &egui::Context) {
|
||||
egui::Window::new(Self::title()).show(ctx, |ui| ui.label(Self::title()));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ApplicationWrapper {
|
||||
app: Option<Application>,
|
||||
|
|
@ -223,14 +242,6 @@ impl Application {
|
|||
// Get specific queues (assuming graphics and present are the same for simplicity)
|
||||
let graphics_queue = device.get_graphics_queue();
|
||||
let queue_associated_device_handle = graphics_queue.device().raw().handle();
|
||||
info!(
|
||||
"App: Queue is associated with Device handle: {:?}",
|
||||
queue_associated_device_handle
|
||||
);
|
||||
assert_eq!(
|
||||
device_handle_at_creation, queue_associated_device_handle,
|
||||
"Device handle mismatch immediately after queue creation!"
|
||||
);
|
||||
|
||||
// --- 4. Resource Manager ---
|
||||
let resource_manager = Arc::new(ResourceManager::new(instance.clone(), device.clone())?);
|
||||
|
|
@ -238,14 +249,6 @@ impl Application {
|
|||
|
||||
let renderer_device_handle_to_pass = device.raw().handle();
|
||||
let renderer_queue_device_handle_to_pass = graphics_queue.device().raw().handle();
|
||||
info!(
|
||||
"App: Passing Device handle to Renderer: {:?}",
|
||||
renderer_device_handle_to_pass
|
||||
);
|
||||
info!(
|
||||
"App: Passing Queue associated with Device handle: {:?}",
|
||||
renderer_queue_device_handle_to_pass
|
||||
);
|
||||
|
||||
// --- 5. Renderer ---
|
||||
let initial_size = window.inner_size();
|
||||
|
|
@ -258,6 +261,18 @@ impl Application {
|
|||
initial_size.width,
|
||||
initial_size.height,
|
||||
)?;
|
||||
|
||||
let egui_ctx = Context::default();
|
||||
let egui_winit = State::new(
|
||||
egui_ctx.clone(),
|
||||
ViewportId::ROOT,
|
||||
&window,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let egui_app = EditorUI::default();
|
||||
|
||||
info!("Renderer initialized.");
|
||||
|
||||
Ok(Self {
|
||||
|
|
@ -269,6 +284,9 @@ impl Application {
|
|||
_resource_manager: resource_manager,
|
||||
renderer,
|
||||
window,
|
||||
egui_winit,
|
||||
egui_ctx,
|
||||
egui_app,
|
||||
frame_count: 0,
|
||||
last_fps_update_time: Instant::now(),
|
||||
last_frame_time: Instant::now(),
|
||||
|
|
@ -276,6 +294,8 @@ impl Application {
|
|||
}
|
||||
|
||||
fn handle_event(&mut self, event: &WindowEvent, active_event_loop: &ActiveEventLoop) {
|
||||
let _ = self.egui_winit.on_window_event(&self.window, event);
|
||||
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
info!("Close requested. Exiting...");
|
||||
|
|
@ -320,8 +340,30 @@ impl Application {
|
|||
self.last_fps_update_time = now;
|
||||
}
|
||||
|
||||
let raw_input = self.egui_winit.take_egui_input(&self.window);
|
||||
|
||||
let egui::FullOutput {
|
||||
platform_output,
|
||||
textures_delta,
|
||||
shapes,
|
||||
pixels_per_point,
|
||||
..
|
||||
} = self.egui_ctx.run(raw_input, |ctx| {
|
||||
self.egui_app.build_ui(ctx);
|
||||
});
|
||||
|
||||
self.renderer.update_textures(textures_delta).unwrap();
|
||||
|
||||
self.egui_winit
|
||||
.handle_platform_output(&self.window, platform_output);
|
||||
|
||||
let clipped_primitives = self.egui_ctx.tessellate(shapes, pixels_per_point);
|
||||
|
||||
// --- Render Frame ---
|
||||
match self.renderer.render_frame() {
|
||||
match self
|
||||
.renderer
|
||||
.render_frame(pixels_per_point, &clipped_primitives)
|
||||
{
|
||||
Ok(_) => {
|
||||
self.window.request_redraw();
|
||||
}
|
||||
|
|
@ -450,6 +492,7 @@ struct Args {
|
|||
|
||||
// --- Entry Point ---
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
color_eyre::install()?;
|
||||
let args = Args::parse();
|
||||
|
||||
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use std::{
|
|||
};
|
||||
|
||||
use ash::vk;
|
||||
use egui::{ClippedPrimitive, TextureId, TexturesDelta};
|
||||
use egui_ash_renderer::{DynamicRendering, Options, Renderer as EguiRenderer};
|
||||
use gfx_hal::{
|
||||
device::Device, error::GfxHalError, queue::Queue, surface::Surface, swapchain::Swapchain,
|
||||
|
|
@ -61,6 +62,7 @@ struct FrameData {
|
|||
command_buffer: vk::CommandBuffer,
|
||||
image_available_semaphore: Semaphore,
|
||||
render_finished_semaphore: Semaphore,
|
||||
textures_to_free: Option<Vec<TextureId>>,
|
||||
in_flight_fence: Fence,
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +142,10 @@ impl Renderer {
|
|||
color_attachment_format: swapchain.format().format,
|
||||
depth_attachment_format: Some(depth_format),
|
||||
},
|
||||
Options::default(),
|
||||
Options {
|
||||
srgb_framebuffer: true,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
|
|
@ -178,7 +183,32 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn render_frame(&mut self) -> Result<(), RendererError> {
|
||||
pub fn update_textures(&mut self, textures_delta: TexturesDelta) -> Result<(), RendererError> {
|
||||
tracing::trace!("Updating EGUI textures!");
|
||||
|
||||
if !textures_delta.free.is_empty() {
|
||||
self.frames_data[self.current_frame].textures_to_free =
|
||||
Some(textures_delta.free.clone());
|
||||
}
|
||||
|
||||
if !textures_delta.set.is_empty() {
|
||||
self.egui_renderer
|
||||
.set_textures(
|
||||
self.device.get_graphics_queue().handle(),
|
||||
self.frames_data[self.current_frame].command_pool,
|
||||
textures_delta.set.as_slice(),
|
||||
)
|
||||
.expect("Failed to update texture");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn render_frame(
|
||||
&mut self,
|
||||
pixels_per_point: f32,
|
||||
clipped_primitives: &[ClippedPrimitive],
|
||||
) -> Result<(), RendererError> {
|
||||
// --- Handle Resize ---
|
||||
if self.window_resized {
|
||||
self.window_resized = false;
|
||||
|
|
@ -190,7 +220,7 @@ impl Renderer {
|
|||
|
||||
// --- Wait for Previous Frame ---
|
||||
let frame_index = self.current_frame;
|
||||
let frame_data = &self.frames_data[frame_index];
|
||||
let frame_data = &mut self.frames_data[frame_index];
|
||||
|
||||
frame_data.in_flight_fence.wait(None)?; // Wait indefinitely
|
||||
|
||||
|
|
@ -219,6 +249,11 @@ impl Renderer {
|
|||
// --- Reset Fence (only after successful acquisition) ---
|
||||
frame_data.in_flight_fence.reset()?;
|
||||
|
||||
if let Some(textures) = frame_data.textures_to_free.take() {
|
||||
tracing::debug!("Freeing EGUI Textures");
|
||||
self.egui_renderer.free_textures(&textures)?;
|
||||
}
|
||||
|
||||
// --- Record Command Buffer ---
|
||||
unsafe {
|
||||
// Need unsafe for Vulkan commands
|
||||
|
|
@ -344,6 +379,15 @@ impl Renderer {
|
|||
self.device.raw().cmd_draw(command_buffer, 3, 1, 0, 0);
|
||||
}
|
||||
|
||||
tracing::trace!("Rendering EGUI");
|
||||
self.egui_renderer.cmd_draw(
|
||||
command_buffer,
|
||||
self.swapchain_extent,
|
||||
pixels_per_point,
|
||||
clipped_primitives,
|
||||
)?;
|
||||
tracing::trace!("Rendered EGUI");
|
||||
|
||||
// --- End Dynamic Rendering ---
|
||||
unsafe {
|
||||
// Need unsafe for Vulkan commands
|
||||
|
|
@ -862,6 +906,7 @@ impl Renderer {
|
|||
};
|
||||
|
||||
frames_data.push(FrameData {
|
||||
textures_to_free: None,
|
||||
command_pool,
|
||||
command_buffer, // Stays allocated, just reset/rerecorded
|
||||
image_available_semaphore,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue