diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index f02c78cf6d0f6..befa69a3a65e8 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -11,6 +11,7 @@ pub mod graph { pub const BLOOM: &str = "bloom"; pub const TONEMAPPING: &str = "tonemapping"; pub const FXAA: &str = "fxaa"; + pub const GIZMO: &str = "gizmo"; pub const UPSCALING: &str = "upscaling"; pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing"; } diff --git a/crates/bevy_core_pipeline/src/gizmo_2d/mod.rs b/crates/bevy_core_pipeline/src/gizmo_2d/mod.rs new file mode 100644 index 0000000000000..7ee2afbd68d39 --- /dev/null +++ b/crates/bevy_core_pipeline/src/gizmo_2d/mod.rs @@ -0,0 +1,104 @@ +use bevy_app::Plugin; +use bevy_ecs::{ + prelude::Entity, + query::With, + system::{Commands, Query}, +}; +use bevy_render::{ + prelude::Camera, + render_graph::RenderGraph, + render_phase::{ + sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, + RenderPhase, + }, + render_resource::*, + Extract, ExtractSchedule, RenderApp, +}; +use bevy_utils::FloatOrd; + +use crate::core_2d::{self, Camera2d}; + +use self::node::Gizmo2dNode; + +pub mod node; + +pub struct Gizmo2dPlugin; + +impl Plugin for Gizmo2dPlugin { + fn build(&self, app: &mut bevy_app::App) { + let Ok(render_app) = app.get_sub_app_mut(RenderApp) else { return; }; + + render_app + .init_resource::>() + .add_system(sort_phase_system::) + .add_system_to_schedule(ExtractSchedule, extract_gizmo_line_2d_camera_phase); + + let gizmo_node = Gizmo2dNode::new(&mut render_app.world); + let mut binding = render_app.world.resource_mut::(); + let graph = binding.get_sub_graph_mut(core_2d::graph::NAME).unwrap(); + + graph.add_node(core_2d::graph::node::GIZMO, gizmo_node); + graph.add_slot_edge( + graph.input_node().id, + core_2d::graph::input::VIEW_ENTITY, + core_2d::graph::node::GIZMO, + Gizmo2dNode::IN_VIEW, + ); + graph.add_node_edge( + core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING, + core_2d::graph::node::GIZMO, + ); + graph.add_node_edge(core_2d::graph::node::GIZMO, core_2d::graph::node::UPSCALING); + } +} + +pub struct GizmoLine2d { + pub sort_key: FloatOrd, + pub pipeline: CachedRenderPipelineId, + pub entity: Entity, + pub draw_function: DrawFunctionId, +} + +impl PhaseItem for GizmoLine2d { + type SortKey = FloatOrd; + + #[inline] + fn entity(&self) -> Entity { + self.entity + } + + #[inline] + fn sort_key(&self) -> Self::SortKey { + self.sort_key + } + + #[inline] + fn draw_function(&self) -> DrawFunctionId { + self.draw_function + } + + #[inline] + fn sort(items: &mut [Self]) { + items.sort_by_key(|item| item.sort_key()); + } +} + +impl CachedRenderPipelinePhaseItem for GizmoLine2d { + #[inline] + fn cached_pipeline(&self) -> CachedRenderPipelineId { + self.pipeline + } +} + +pub fn extract_gizmo_line_2d_camera_phase( + mut commands: Commands, + cameras_2d: Extract>>, +) { + for (entity, camera) in &cameras_2d { + if camera.is_active { + commands + .get_or_spawn(entity) + .insert(RenderPhase::::default()); + } + } +} diff --git a/crates/bevy_gizmos/src/node_2d.rs b/crates/bevy_core_pipeline/src/gizmo_2d/node.rs similarity index 91% rename from crates/bevy_gizmos/src/node_2d.rs rename to crates/bevy_core_pipeline/src/gizmo_2d/node.rs index 80cd428aa43f2..8b089c5f8b0ef 100644 --- a/crates/bevy_gizmos/src/node_2d.rs +++ b/crates/bevy_core_pipeline/src/gizmo_2d/node.rs @@ -6,17 +6,18 @@ use bevy_render::{ renderer::RenderContext, view::{ExtractedView, ViewTarget}, }; +#[cfg(feature = "trace")] +use bevy_utils::tracing::info_span; -use crate::pipeline_2d::GizmoLine2d; +use super::GizmoLine2d; -pub struct GizmoNode2d { +pub struct Gizmo2dNode { view_query: QueryState<(&'static ViewTarget, &'static RenderPhase), With>, } -impl GizmoNode2d { +impl Gizmo2dNode { pub const IN_VIEW: &'static str = "view"; - pub const NAME: &'static str = "gizmo_node_2d"; pub fn new(world: &mut World) -> Self { Self { @@ -25,7 +26,7 @@ impl GizmoNode2d { } } -impl Node for GizmoNode2d { +impl Node for Gizmo2dNode { fn input(&self) -> Vec { vec![SlotInfo::new(Self::IN_VIEW, SlotType::Entity)] } diff --git a/crates/bevy_core_pipeline/src/lib.rs b/crates/bevy_core_pipeline/src/lib.rs index 5b0fe9eaea21c..d459dae6ff7c0 100644 --- a/crates/bevy_core_pipeline/src/lib.rs +++ b/crates/bevy_core_pipeline/src/lib.rs @@ -4,6 +4,7 @@ pub mod core_2d; pub mod core_3d; pub mod fullscreen_vertex_shader; pub mod fxaa; +pub mod gizmo_2d; pub mod prepass; pub mod tonemapping; pub mod upscaling; diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index b866e7ad98774..e053f99e53f6c 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -2,7 +2,10 @@ use std::mem; use bevy_app::{CoreSet, Plugin}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; -use bevy_core_pipeline::{core_2d, core_3d}; +use bevy_core_pipeline::{ + core_3d, + gizmo_2d::{Gizmo2dPlugin, GizmoLine2d}, +}; use bevy_ecs::{ prelude::{Component, DetectChanges}, schedule::IntoSystemConfig, @@ -26,7 +29,6 @@ use bevy_sprite::{Mesh2dHandle, Mesh2dUniform}; pub mod gizmos; -mod node_2d; mod node_3d; #[cfg(feature = "bevy_sprite")] @@ -34,7 +36,7 @@ mod pipeline_2d; #[cfg(feature = "bevy_pbr")] mod pipeline_3d; -use crate::{gizmos::GizmoStorage, node_2d::GizmoNode2d, node_3d::GizmoNode3d}; +use crate::{gizmos::GizmoStorage, node_3d::GizmoNode3d}; /// The `bevy_gizmos` prelude. pub mod prelude { @@ -56,6 +58,9 @@ impl Plugin for GizmoPlugin { .init_resource::() .add_system(update_gizmo_meshes.in_base_set(CoreSet::Last)); + #[cfg(feature = "bevy_sprite")] + app.add_plugin(Gizmo2dPlugin); + let Ok(render_app) = app.get_sub_app_mut(RenderApp) else { return; }; render_app.add_system_to_schedule(ExtractSchedule, extract_gizmo_data); @@ -67,28 +72,8 @@ impl Plugin for GizmoPlugin { render_app .init_resource::() .init_resource::>() - .init_resource::>() .add_render_command::() - .add_system(sort_phase_system::) - .add_system_to_schedule(ExtractSchedule, extract_gizmo_line_2d_camera_phase) .add_system(queue_gizmos_2d.in_set(RenderSet::Queue)); - - let gizmo_node = GizmoNode2d::new(&mut render_app.world); - let mut binding = render_app.world.resource_mut::(); - let graph = binding.get_sub_graph_mut(core_2d::graph::NAME).unwrap(); - - graph.add_node(GizmoNode2d::NAME, gizmo_node); - graph.add_slot_edge( - graph.input_node().id, - core_2d::graph::input::VIEW_ENTITY, - GizmoNode2d::NAME, - GizmoNode2d::IN_VIEW, - ); - graph.add_node_edge( - core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING, - GizmoNode2d::NAME, - ); - graph.add_node_edge(GizmoNode2d::NAME, core_2d::graph::node::UPSCALING); } #[cfg(feature = "bevy_pbr")] diff --git a/crates/bevy_gizmos/src/pipeline_2d.rs b/crates/bevy_gizmos/src/pipeline_2d.rs index 33bb52b384caa..e2162e995e0d6 100644 --- a/crates/bevy_gizmos/src/pipeline_2d.rs +++ b/crates/bevy_gizmos/src/pipeline_2d.rs @@ -1,23 +1,18 @@ use bevy_asset::Handle; -use bevy_core_pipeline::prelude::Camera2d; +use bevy_core_pipeline::gizmo_2d::GizmoLine2d; use bevy_ecs::{ prelude::Entity, query::With, - system::{Commands, Query, Res, ResMut, Resource}, + system::{Query, Res, ResMut, Resource}, world::{FromWorld, World}, }; use bevy_render::{ mesh::{Mesh, MeshVertexBufferLayout}, - prelude::Camera, render_asset::RenderAssets, - render_phase::{ - CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, RenderPhase, - SetItemPipeline, - }, + render_phase::{DrawFunctions, RenderPhase, SetItemPipeline}, render_resource::*, texture::BevyDefault, view::Msaa, - Extract, }; use bevy_sprite::*; use bevy_utils::FloatOrd; @@ -97,57 +92,6 @@ pub(crate) type DrawGizmoLines = ( DrawMesh2d, ); -pub struct GizmoLine2d { - pub sort_key: FloatOrd, - pub pipeline: CachedRenderPipelineId, - pub entity: Entity, - pub draw_function: DrawFunctionId, -} - -impl PhaseItem for GizmoLine2d { - type SortKey = FloatOrd; - - #[inline] - fn entity(&self) -> Entity { - self.entity - } - - #[inline] - fn sort_key(&self) -> Self::SortKey { - self.sort_key - } - - #[inline] - fn draw_function(&self) -> DrawFunctionId { - self.draw_function - } - - #[inline] - fn sort(items: &mut [Self]) { - items.sort_by_key(|item| item.sort_key()); - } -} - -impl CachedRenderPipelinePhaseItem for GizmoLine2d { - #[inline] - fn cached_pipeline(&self) -> CachedRenderPipelineId { - self.pipeline - } -} - -pub fn extract_gizmo_line_2d_camera_phase( - mut commands: Commands, - cameras_2d: Extract>>, -) { - for (entity, camera) in &cameras_2d { - if camera.is_active { - commands - .get_or_spawn(entity) - .insert(RenderPhase::::default()); - } - } -} - #[allow(clippy::too_many_arguments)] pub(crate) fn queue_gizmos_2d( draw_functions: Res>,