use crate::ecs::world::World;
use crate::render::wgpu::rendergraph::{PassExecutionContext, PassNode};
pub struct EguiPass {
renderer: egui_wgpu::Renderer,
screen_descriptor: egui_wgpu::ScreenDescriptor,
paint_jobs: Vec<egui::ClippedPrimitive>,
}
impl EguiPass {
pub fn new(device: &wgpu::Device, surface_format: wgpu::TextureFormat) -> Self {
let renderer = egui_wgpu::Renderer::new(
device,
surface_format,
egui_wgpu::RendererOptions {
depth_stencil_format: None,
msaa_samples: 1,
..Default::default()
},
);
Self {
renderer,
screen_descriptor: egui_wgpu::ScreenDescriptor {
size_in_pixels: [1, 1],
pixels_per_point: 1.0,
},
paint_jobs: Vec::new(),
}
}
pub fn update_textures(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
textures_delta: &egui::TexturesDelta,
) {
for (id, image_delta) in &textures_delta.set {
self.renderer
.update_texture(device, queue, *id, image_delta);
}
for id in &textures_delta.free {
self.renderer.free_texture(id);
}
}
pub fn set_paint_jobs(&mut self, paint_jobs: Vec<egui::ClippedPrimitive>) {
self.paint_jobs = paint_jobs;
}
pub fn set_screen_descriptor(&mut self, screen_descriptor: egui_wgpu::ScreenDescriptor) {
self.screen_descriptor = screen_descriptor;
}
}
impl PassNode<World> for EguiPass {
fn name(&self) -> &str {
"egui_pass"
}
fn reads(&self) -> Vec<&str> {
vec![]
}
fn writes(&self) -> Vec<&str> {
vec![]
}
fn reads_writes(&self) -> Vec<&str> {
vec!["color"]
}
fn execute<'r, 'e>(
&mut self,
context: PassExecutionContext<'r, 'e, World>,
) -> Result<
Vec<crate::render::wgpu::rendergraph::SubGraphRunCommand<'r>>,
crate::render::wgpu::rendergraph::RenderGraphError,
> {
if !context.is_pass_enabled() {
return Ok(context.into_sub_graph_commands());
}
let (color_view, color_load, color_store) = context.get_color_attachment("color")?;
let (target_width, target_height) = context.get_texture_size("color")?;
self.screen_descriptor.size_in_pixels = [target_width, target_height];
if !self.paint_jobs.is_empty() {
self.renderer.update_buffers(
context.device,
context.queue,
context.encoder,
&self.paint_jobs,
&self.screen_descriptor,
);
self.renderer.render(
&mut context
.encoder
.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Egui Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: color_view,
resolve_target: None,
ops: wgpu::Operations {
load: color_load,
store: color_store,
},
depth_slice: None,
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
})
.forget_lifetime(),
&self.paint_jobs,
&self.screen_descriptor,
);
}
Ok(context.into_sub_graph_commands())
}
}