Skip to content

Commit

Permalink
Paint callback functionality improvements (#306)
Browse files Browse the repository at this point in the history
* Support executing additional render passes or adding command buffers from paint callback

* Call prepare_render paint callback function in egui render to texture node
  • Loading branch information
PPakalns authored Sep 29, 2024
1 parent 3aed12f commit 479025f
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 18 deletions.
69 changes: 54 additions & 15 deletions src/egui_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,11 +382,11 @@ impl Node for EguiNode {
}
}

fn run(
fn run<'w>(
&self,
_graph: &mut RenderGraphContext,
render_context: &mut RenderContext,
world: &World,
render_context: &mut RenderContext<'w>,
world: &'w World,
) -> Result<(), NodeRunError> {
let egui_pipelines = &world.get_resource::<EguiPipelines>().unwrap().0;
let pipeline_cache = world.get_resource::<PipelineCache>().unwrap();
Expand All @@ -409,6 +409,40 @@ impl Node for EguiNode {
render_queue.write_buffer(vertex_buffer, 0, &self.vertex_data);
render_queue.write_buffer(index_buffer, 0, &self.index_data);

let (physical_width, physical_height, pipeline_key) = match extracted_window {
Some(window) => (
window.physical_width,
window.physical_height,
EguiPipelineKey::from_extracted_window(window),
),
None => unreachable!(),
};
let Some(key) = pipeline_key else {
return Ok(());
};

for draw_command in &self.draw_commands {
match &draw_command.primitive {
DrawPrimitive::Egui(_command) => {}
DrawPrimitive::PaintCallback(command) => {
let info = egui::PaintCallbackInfo {
viewport: command.rect,
clip_rect: draw_command.clip_rect,
pixels_per_point: self.pixels_per_point,
screen_size_px: [physical_width, physical_height],
};

command.callback.cb().prepare_render(
info,
render_context,
self.window_entity,
key,
world,
);
}
}
}

let bind_groups = &world.get_resource::<EguiTextureBindGroups>().unwrap();

let egui_transforms = world.get_resource::<EguiTransforms>().unwrap();
Expand All @@ -434,18 +468,6 @@ impl Node for EguiNode {
});
let mut render_pass = TrackedRenderPass::new(device, render_pass);

let (physical_width, physical_height, pipeline_key) = match extracted_window {
Some(window) => (
window.physical_width,
window.physical_height,
EguiPipelineKey::from_extracted_window(window),
),
None => unreachable!(),
};
let Some(key) = pipeline_key else {
return Ok(());
};

let pipeline_id = egui_pipelines.get(&self.window_entity).unwrap();
let Some(pipeline) = pipeline_cache.get_render_pipeline(*pipeline_id) else {
return Ok(());
Expand Down Expand Up @@ -671,6 +693,23 @@ pub trait EguiBevyPaintCallbackImpl: Send + Sync {
world: &mut World,
);

/// Paint callback call before render step
///
///
/// Can be used to implement custom render passes
/// or to submit command buffers for execution before egui render pass
fn prepare_render<'w>(
&self,
info: egui::PaintCallbackInfo,
render_context: &mut RenderContext<'w>,
window_entity: Entity,
pipeline_key: EguiPipelineKey,
world: &'w World,
) {
let _ = (info, render_context, window_entity, pipeline_key, world);
// Do nothing by default
}

/// Paint callback render step
///
/// Native wgpu RenderPass can be retrieved from [`TrackedRenderPass`] by calling
Expand Down
28 changes: 25 additions & 3 deletions src/egui_render_to_texture_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,11 @@ impl Node for EguiRenderToTextureNode {
}
}

fn run(
fn run<'w>(
&self,
_graph: &mut RenderGraphContext,
render_context: &mut RenderContext,
world: &World,
render_context: &mut RenderContext<'w>,
world: &'w World,
) -> Result<(), NodeRunError> {
let egui_pipelines = &world.get_resource::<EguiPipelines>().unwrap().0;
let pipeline_cache = world.get_resource::<PipelineCache>().unwrap();
Expand All @@ -260,6 +260,28 @@ impl Node for EguiRenderToTextureNode {
render_queue.write_buffer(vertex_buffer, 0, &self.vertex_data);
render_queue.write_buffer(index_buffer, 0, &self.index_data);

for draw_command in &self.draw_commands {
match &draw_command.primitive {
DrawPrimitive::Egui(_command) => {}
DrawPrimitive::PaintCallback(command) => {
let info = egui::PaintCallbackInfo {
viewport: command.rect,
clip_rect: draw_command.clip_rect,
pixels_per_point: self.pixels_per_point,
screen_size_px: [gpu_image.size.x, gpu_image.size.y],
};

command.callback.cb().prepare_render(
info,
render_context,
self.render_to_texture_target,
key,
world,
);
}
}
}

let bind_groups = &world.get_resource::<EguiTextureBindGroups>().unwrap();

let egui_transforms = world.get_resource::<EguiTransforms>().unwrap();
Expand Down

0 comments on commit 479025f

Please sign in to comment.