wip: add init egui impl
This commit is contained in:
parent
f71f0d8e10
commit
b1c164dc6a
4 changed files with 790 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
|
egui.workspace = true
|
||||||
ash.workspace = true
|
ash.workspace = true
|
||||||
ash-window.workspace = true
|
ash-window.workspace = true
|
||||||
|
color-eyre.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
winit.workspace = true
|
winit.workspace = true
|
||||||
|
|
@ -17,3 +18,4 @@ gfx_hal = { path = "../gfx_hal" }
|
||||||
renderer = { path = "../renderer" }
|
renderer = { path = "../renderer" }
|
||||||
resource_manager = { path = "../resource_manager" }
|
resource_manager = { path = "../resource_manager" }
|
||||||
clap = { version = "4.5.34", features = ["derive"] }
|
clap = { version = "4.5.34", features = ["derive"] }
|
||||||
|
egui-winit = "0.31.1"
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ use std::{
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use egui::{Context, ViewportId};
|
||||||
|
use egui_winit::State;
|
||||||
use gfx_hal::{
|
use gfx_hal::{
|
||||||
device::Device, error::GfxHalError, instance::Instance, instance::InstanceConfig,
|
device::Device, error::GfxHalError, instance::Instance, instance::InstanceConfig,
|
||||||
physical_device::PhysicalDevice, queue::Queue, surface::Surface,
|
physical_device::PhysicalDevice, queue::Queue, surface::Surface,
|
||||||
|
|
@ -57,6 +59,10 @@ struct Application {
|
||||||
// Renderer
|
// Renderer
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
|
||||||
|
egui_ctx: Context,
|
||||||
|
egui_winit: State,
|
||||||
|
egui_app: EditorUI,
|
||||||
|
|
||||||
// Windowing
|
// Windowing
|
||||||
window: Arc<Window>, // Use Arc for potential multi-threading later
|
window: Arc<Window>, // Use Arc for potential multi-threading later
|
||||||
|
|
||||||
|
|
@ -65,6 +71,19 @@ struct Application {
|
||||||
last_frame_time: Instant,
|
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)]
|
#[derive(Default)]
|
||||||
struct ApplicationWrapper {
|
struct ApplicationWrapper {
|
||||||
app: Option<Application>,
|
app: Option<Application>,
|
||||||
|
|
@ -223,14 +242,6 @@ impl Application {
|
||||||
// Get specific queues (assuming graphics and present are the same for simplicity)
|
// Get specific queues (assuming graphics and present are the same for simplicity)
|
||||||
let graphics_queue = device.get_graphics_queue();
|
let graphics_queue = device.get_graphics_queue();
|
||||||
let queue_associated_device_handle = graphics_queue.device().raw().handle();
|
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 ---
|
// --- 4. Resource Manager ---
|
||||||
let resource_manager = Arc::new(ResourceManager::new(instance.clone(), device.clone())?);
|
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_device_handle_to_pass = device.raw().handle();
|
||||||
let renderer_queue_device_handle_to_pass = graphics_queue.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 ---
|
// --- 5. Renderer ---
|
||||||
let initial_size = window.inner_size();
|
let initial_size = window.inner_size();
|
||||||
|
|
@ -258,6 +261,18 @@ impl Application {
|
||||||
initial_size.width,
|
initial_size.width,
|
||||||
initial_size.height,
|
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.");
|
info!("Renderer initialized.");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
@ -269,6 +284,9 @@ impl Application {
|
||||||
_resource_manager: resource_manager,
|
_resource_manager: resource_manager,
|
||||||
renderer,
|
renderer,
|
||||||
window,
|
window,
|
||||||
|
egui_winit,
|
||||||
|
egui_ctx,
|
||||||
|
egui_app,
|
||||||
frame_count: 0,
|
frame_count: 0,
|
||||||
last_fps_update_time: Instant::now(),
|
last_fps_update_time: Instant::now(),
|
||||||
last_frame_time: Instant::now(),
|
last_frame_time: Instant::now(),
|
||||||
|
|
@ -320,8 +338,29 @@ impl Application {
|
||||||
self.last_fps_update_time = now;
|
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.egui_winit
|
||||||
|
.handle_platform_output(&self.window, platform_output);
|
||||||
|
|
||||||
|
let clipped_primitives = self.egui_ctx.tessellate(shapes, pixels_per_point);
|
||||||
|
|
||||||
// --- Render Frame ---
|
// --- Render Frame ---
|
||||||
match self.renderer.render_frame() {
|
match self.renderer.render_frame(
|
||||||
|
pixels_per_point,
|
||||||
|
textures_delta,
|
||||||
|
&clipped_primitives,
|
||||||
|
) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
|
|
@ -450,6 +489,7 @@ struct Args {
|
||||||
|
|
||||||
// --- Entry Point ---
|
// --- Entry Point ---
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
color_eyre::install()?;
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let fmt_layer = tracing_subscriber::fmt::layer()
|
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
use egui::{ClippedPrimitive, TextureId, TexturesDelta};
|
||||||
use egui_ash_renderer::{DynamicRendering, Options, Renderer as EguiRenderer};
|
use egui_ash_renderer::{DynamicRendering, Options, Renderer as EguiRenderer};
|
||||||
use gfx_hal::{
|
use gfx_hal::{
|
||||||
device::Device, error::GfxHalError, queue::Queue, surface::Surface, swapchain::Swapchain,
|
device::Device, error::GfxHalError, queue::Queue, surface::Surface, swapchain::Swapchain,
|
||||||
|
|
@ -61,6 +62,7 @@ struct FrameData {
|
||||||
command_buffer: vk::CommandBuffer,
|
command_buffer: vk::CommandBuffer,
|
||||||
image_available_semaphore: Semaphore,
|
image_available_semaphore: Semaphore,
|
||||||
render_finished_semaphore: Semaphore,
|
render_finished_semaphore: Semaphore,
|
||||||
|
textures_to_free: Option<Vec<TextureId>>,
|
||||||
in_flight_fence: Fence,
|
in_flight_fence: Fence,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,7 +142,10 @@ impl Renderer {
|
||||||
color_attachment_format: swapchain.format().format,
|
color_attachment_format: swapchain.format().format,
|
||||||
depth_attachment_format: Some(depth_format),
|
depth_attachment_format: Some(depth_format),
|
||||||
},
|
},
|
||||||
Options::default(),
|
Options {
|
||||||
|
srgb_framebuffer: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
@ -178,7 +183,12 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_frame(&mut self) -> Result<(), RendererError> {
|
pub fn render_frame(
|
||||||
|
&mut self,
|
||||||
|
pixels_per_point: f32,
|
||||||
|
textures_delta: TexturesDelta,
|
||||||
|
clipped_primitives: &[ClippedPrimitive],
|
||||||
|
) -> Result<(), RendererError> {
|
||||||
// --- Handle Resize ---
|
// --- Handle Resize ---
|
||||||
if self.window_resized {
|
if self.window_resized {
|
||||||
self.window_resized = false;
|
self.window_resized = false;
|
||||||
|
|
@ -190,7 +200,7 @@ impl Renderer {
|
||||||
|
|
||||||
// --- Wait for Previous Frame ---
|
// --- Wait for Previous Frame ---
|
||||||
let frame_index = self.current_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
|
frame_data.in_flight_fence.wait(None)?; // Wait indefinitely
|
||||||
|
|
||||||
|
|
@ -219,6 +229,11 @@ impl Renderer {
|
||||||
// --- Reset Fence (only after successful acquisition) ---
|
// --- Reset Fence (only after successful acquisition) ---
|
||||||
frame_data.in_flight_fence.reset()?;
|
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 ---
|
// --- Record Command Buffer ---
|
||||||
unsafe {
|
unsafe {
|
||||||
// Need unsafe for Vulkan commands
|
// Need unsafe for Vulkan commands
|
||||||
|
|
@ -238,6 +253,29 @@ impl Renderer {
|
||||||
.begin_command_buffer(command_buffer, &cmd_begin_info)?;
|
.begin_command_buffer(command_buffer, &cmd_begin_info)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !textures_delta.free.is_empty() {
|
||||||
|
tracing::debug!("Setting textures to free");
|
||||||
|
frame_data.textures_to_free = Some(textures_delta.free.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !textures_delta.set.is_empty() {
|
||||||
|
tracing::trace!("Setting EGUI textures");
|
||||||
|
self.egui_renderer.set_textures(
|
||||||
|
self.device.get_graphics_queue().handle(),
|
||||||
|
frame_data.command_pool,
|
||||||
|
textures_delta.set.as_slice(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!("Rendering EGUI");
|
||||||
|
self.egui_renderer.cmd_draw(
|
||||||
|
command_buffer,
|
||||||
|
self.swapchain_extent,
|
||||||
|
pixels_per_point,
|
||||||
|
clipped_primitives,
|
||||||
|
)?;
|
||||||
|
tracing::debug!("Rendered EGUI");
|
||||||
|
|
||||||
let current_swapchain_image = swapchain_ref.images()[image_index as usize];
|
let current_swapchain_image = swapchain_ref.images()[image_index as usize];
|
||||||
|
|
||||||
let initial_layout_transition_barrier = vk::ImageMemoryBarrier::default()
|
let initial_layout_transition_barrier = vk::ImageMemoryBarrier::default()
|
||||||
|
|
@ -862,6 +900,7 @@ impl Renderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
frames_data.push(FrameData {
|
frames_data.push(FrameData {
|
||||||
|
textures_to_free: None,
|
||||||
command_pool,
|
command_pool,
|
||||||
command_buffer, // Stays allocated, just reset/rerecorded
|
command_buffer, // Stays allocated, just reset/rerecorded
|
||||||
image_available_semaphore,
|
image_available_semaphore,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue