diff --git a/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs b/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs index f4006822f3436..1ab2f1dda86ac 100644 --- a/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs +++ b/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs @@ -6,7 +6,7 @@ use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, - render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, + render_phase::RenderPhase, render_resource::{LoadOp, Operations, RenderPassDescriptor}, renderer::RenderContext, view::{ExtractedView, ViewTarget}, @@ -77,21 +77,13 @@ impl Node for MainPass2dNode { depth_stencil_attachment: None, }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &transparent_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + transparent_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } // WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't diff --git a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs index cf3a3d38fa603..3ba8e3c0d4a68 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs @@ -6,7 +6,7 @@ use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, - render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, + render_phase::RenderPhase, render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor}, renderer::RenderContext, view::{ExtractedView, ViewDepthTexture, ViewTarget}, @@ -95,20 +95,13 @@ impl Node for MainPass3dNode { }), }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &opaque_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + opaque_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } if !alpha_mask_phase.items.is_empty() { @@ -134,20 +127,13 @@ impl Node for MainPass3dNode { }), }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &alpha_mask_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + alpha_mask_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } if !transparent_phase.items.is_empty() { @@ -178,20 +164,13 @@ impl Node for MainPass3dNode { }), }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &transparent_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + transparent_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } // WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index e23c1c811c4d7..a499511602693 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -1785,16 +1785,7 @@ impl Node for ShadowPassNode { }), }; - let draw_functions = world.resource::>(); - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - for item in &shadow_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_light_entity, item); - } + shadow_phase.render(world, render_context, view_entity, None, pass_descriptor); } } diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 29564481ca454..c4f0ce1abb0c7 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -1,10 +1,15 @@ mod draw; mod draw_state; +use bevy_ecs::entity::Entity; pub use draw::*; pub use draw_state::*; +use wgpu::RenderPassDescriptor; +use crate::camera::Viewport; +use crate::renderer::RenderContext; use bevy_ecs::prelude::{Component, Query}; +use bevy_ecs::world::World; /// A resource to collect and sort draw requests for specific [`PhaseItems`](PhaseItem). #[derive(Component)] @@ -29,6 +34,32 @@ impl RenderPhase { pub fn sort(&mut self) { I::sort(&mut self.items); } + + pub fn render( + &self, + world: &World, + render_context: &mut RenderContext, + view: Entity, + viewport: Option<&Viewport>, + pass_descriptor: RenderPassDescriptor, + ) { + let render_pass = render_context + .command_encoder + .begin_render_pass(&pass_descriptor); + let mut render_pass = TrackedRenderPass::new(render_pass); + + if let Some(viewport) = viewport { + render_pass.set_camera_viewport(viewport); + } + + let draw_functions = world.resource::>(); + let mut draw_functions = draw_functions.write(); + + for item in &self.items { + let draw_function = draw_functions.get_mut(item.draw_function()).unwrap(); + draw_function.draw(world, &mut render_pass, view, item); + } + } } impl RenderPhase { diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 527e96538f1f3..eddb6c1809b49 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -85,18 +85,7 @@ impl Node for UiPassNode { depth_stencil_attachment: None, }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - for item in &transparent_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + transparent_phase.render(world, render_context, view_entity, None, pass_descriptor); Ok(()) } }