mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Making bevy_render
an optional dependency for bevy_gizmos
(#14448)
# Objective This PR makes `bevy_render` an optional dependency for `bevy_gizmos`, thereby allowing `bevy_gizmos` to be used with alternative rendering backend. Previously `bevy_gizmos` assumes that one of `bevy_pbr` or `bevy_sprite` will be enabled. Here we introduced a new feature named `bevy_render` which disables all rendering-related code paths. An alternative renderer will then take the `LineGizmo` assets (made public in this PR) and issue draw calls on their own. A new field `config_ty` was added to `LineGizmo` to help looking up the related configuration info. --- ## Migration Guide No user-visible changes needed from the users.
This commit is contained in:
parent
e85c072372
commit
5fd0661c15
5 changed files with 103 additions and 67 deletions
|
@ -91,6 +91,10 @@ impl AssetProcessor {
|
|||
Self { server, data }
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &Arc<AssetProcessorData> {
|
||||
&self.data
|
||||
}
|
||||
|
||||
/// The "internal" [`AssetServer`] used by the [`AssetProcessor`]. This is _separate_ from the asset processor used by
|
||||
/// the main App. It has different processor-specific configuration and a different ID space.
|
||||
pub fn server(&self) -> &AssetServer {
|
||||
|
|
|
@ -11,6 +11,7 @@ keywords = ["bevy"]
|
|||
[features]
|
||||
webgl = []
|
||||
webgpu = []
|
||||
bevy_render = ["dep:bevy_render", "bevy_core_pipeline"]
|
||||
|
||||
[dependencies]
|
||||
# Bevy
|
||||
|
@ -21,10 +22,10 @@ bevy_color = { path = "../bevy_color", version = "0.15.0-dev" }
|
|||
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.15.0-dev" }
|
||||
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" }
|
||||
bevy_render = { path = "../bevy_render", version = "0.15.0-dev" }
|
||||
bevy_render = { path = "../bevy_render", version = "0.15.0-dev", optional = true }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
|
||||
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev" }
|
||||
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.15.0-dev" }
|
||||
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.15.0-dev", optional = true }
|
||||
bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" }
|
||||
bevy_gizmos_macros = { path = "macros", version = "0.15.0-dev" }
|
||||
bevy_time = { path = "../bevy_time", version = "0.15.0-dev" }
|
||||
|
|
|
@ -5,7 +5,6 @@ pub use bevy_gizmos_macros::GizmoConfigGroup;
|
|||
|
||||
use bevy_ecs::{component::Component, reflect::ReflectResource, system::Resource};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath};
|
||||
use bevy_render::view::RenderLayers;
|
||||
use bevy_utils::TypeIdMap;
|
||||
use core::panic;
|
||||
use std::{
|
||||
|
@ -164,7 +163,8 @@ pub struct GizmoConfig {
|
|||
/// Describes which rendering layers gizmos will be rendered to.
|
||||
///
|
||||
/// Gizmos will only be rendered to cameras with intersecting layers.
|
||||
pub render_layers: RenderLayers,
|
||||
#[cfg(feature = "bevy_render")]
|
||||
pub render_layers: bevy_render::view::RenderLayers,
|
||||
|
||||
/// Describe how lines should join
|
||||
pub line_joints: GizmoLineJoint,
|
||||
|
@ -178,6 +178,7 @@ impl Default for GizmoConfig {
|
|||
line_perspective: false,
|
||||
line_style: GizmoLineStyle::Solid,
|
||||
depth_bias: 0.,
|
||||
#[cfg(feature = "bevy_render")]
|
||||
render_layers: Default::default(),
|
||||
|
||||
line_joints: GizmoLineJoint::None,
|
||||
|
@ -185,13 +186,15 @@ impl Default for GizmoConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Component)]
|
||||
pub(crate) struct GizmoMeshConfig {
|
||||
pub line_perspective: bool,
|
||||
pub line_style: GizmoLineStyle,
|
||||
pub render_layers: RenderLayers,
|
||||
pub render_layers: bevy_render::view::RenderLayers,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
impl From<&GizmoConfig> for GizmoMeshConfig {
|
||||
fn from(item: &GizmoConfig) -> Self {
|
||||
GizmoMeshConfig {
|
||||
|
|
|
@ -31,6 +31,7 @@ pub enum GizmoRenderSystem {
|
|||
QueueLineGizmos3d,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
pub mod aabb;
|
||||
pub mod arcs;
|
||||
pub mod arrows;
|
||||
|
@ -42,19 +43,20 @@ pub mod grid;
|
|||
pub mod primitives;
|
||||
pub mod rounded_box;
|
||||
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))]
|
||||
pub mod light;
|
||||
|
||||
#[cfg(feature = "bevy_sprite")]
|
||||
#[cfg(all(feature = "bevy_sprite", feature = "bevy_render"))]
|
||||
mod pipeline_2d;
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))]
|
||||
mod pipeline_3d;
|
||||
|
||||
/// The `bevy_gizmos` prelude.
|
||||
pub mod prelude {
|
||||
#[cfg(feature = "bevy_render")]
|
||||
pub use crate::aabb::{AabbGizmoConfigGroup, ShowAabbGizmo};
|
||||
#[doc(hidden)]
|
||||
pub use crate::{
|
||||
aabb::{AabbGizmoConfigGroup, ShowAabbGizmo},
|
||||
config::{
|
||||
DefaultGizmoConfigGroup, GizmoConfig, GizmoConfigGroup, GizmoConfigStore,
|
||||
GizmoLineJoint, GizmoLineStyle,
|
||||
|
@ -64,13 +66,12 @@ pub mod prelude {
|
|||
AppGizmoBuilder,
|
||||
};
|
||||
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))]
|
||||
pub use crate::light::{LightGizmoColor, LightGizmoConfigGroup, ShowLightGizmo};
|
||||
}
|
||||
|
||||
use aabb::AabbGizmoPlugin;
|
||||
use bevy_app::{App, FixedFirst, FixedLast, Last, Plugin, RunFixedMainLoop};
|
||||
use bevy_asset::{load_internal_asset, Asset, AssetApp, Assets, Handle};
|
||||
use bevy_asset::{Asset, AssetApp, Assets, Handle};
|
||||
use bevy_color::LinearRgba;
|
||||
use bevy_ecs::{
|
||||
component::Component,
|
||||
|
@ -83,6 +84,7 @@ use bevy_ecs::{
|
|||
};
|
||||
use bevy_math::Vec3;
|
||||
use bevy_reflect::TypePath;
|
||||
#[cfg(feature = "bevy_render")]
|
||||
use bevy_render::{
|
||||
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||
|
@ -100,14 +102,15 @@ use bevy_utils::TypeIdMap;
|
|||
use bytemuck::cast_slice;
|
||||
use config::{
|
||||
DefaultGizmoConfigGroup, GizmoConfig, GizmoConfigGroup, GizmoConfigStore, GizmoLineJoint,
|
||||
GizmoMeshConfig,
|
||||
};
|
||||
use gizmos::{GizmoStorage, Swap};
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
use light::LightGizmoPlugin;
|
||||
use std::{any::TypeId, mem};
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
const LINE_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(7414812689238026784);
|
||||
#[cfg(feature = "bevy_render")]
|
||||
const LINE_JOINT_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(1162780797909187908);
|
||||
|
||||
/// A [`Plugin`] that provides an immediate mode drawing api for visual debugging.
|
||||
|
@ -118,58 +121,60 @@ pub struct GizmoPlugin;
|
|||
|
||||
impl Plugin for GizmoPlugin {
|
||||
fn build(&self, app: &mut bevy_app::App) {
|
||||
// Gizmos cannot work without either a 3D or 2D renderer.
|
||||
#[cfg(all(not(feature = "bevy_pbr"), not(feature = "bevy_sprite")))]
|
||||
bevy_utils::tracing::error!(
|
||||
"bevy_gizmos requires either bevy_pbr or bevy_sprite. Please enable one."
|
||||
);
|
||||
|
||||
load_internal_asset!(app, LINE_SHADER_HANDLE, "lines.wgsl", Shader::from_wgsl);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
LINE_JOINT_SHADER_HANDLE,
|
||||
"line_joints.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
#[cfg(feature = "bevy_render")]
|
||||
{
|
||||
use bevy_asset::load_internal_asset;
|
||||
load_internal_asset!(app, LINE_SHADER_HANDLE, "lines.wgsl", Shader::from_wgsl);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
LINE_JOINT_SHADER_HANDLE,
|
||||
"line_joints.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
}
|
||||
|
||||
app.register_type::<GizmoConfig>()
|
||||
.register_type::<GizmoConfigStore>()
|
||||
.add_plugins(UniformComponentPlugin::<LineGizmoUniform>::default())
|
||||
.init_asset::<LineGizmo>()
|
||||
.add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default())
|
||||
.init_resource::<LineGizmoHandles>()
|
||||
// We insert the Resource GizmoConfigStore into the world implicitly here if it does not exist.
|
||||
.init_gizmo_group::<DefaultGizmoConfigGroup>()
|
||||
.add_plugins(AabbGizmoPlugin);
|
||||
.init_gizmo_group::<DefaultGizmoConfigGroup>();
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
app.add_plugins(aabb::AabbGizmoPlugin)
|
||||
.add_plugins(UniformComponentPlugin::<LineGizmoUniform>::default())
|
||||
.add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default());
|
||||
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
app.add_plugins(LightGizmoPlugin);
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
};
|
||||
#[cfg(feature = "bevy_render")]
|
||||
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app.add_systems(
|
||||
Render,
|
||||
prepare_line_gizmo_bind_group.in_set(RenderSet::PrepareBindGroups),
|
||||
);
|
||||
|
||||
render_app.add_systems(
|
||||
Render,
|
||||
prepare_line_gizmo_bind_group.in_set(RenderSet::PrepareBindGroups),
|
||||
);
|
||||
render_app.add_systems(ExtractSchedule, extract_gizmo_data);
|
||||
|
||||
render_app.add_systems(ExtractSchedule, extract_gizmo_data);
|
||||
|
||||
#[cfg(feature = "bevy_sprite")]
|
||||
if app.is_plugin_added::<bevy_sprite::SpritePlugin>() {
|
||||
app.add_plugins(pipeline_2d::LineGizmo2dPlugin);
|
||||
#[cfg(feature = "bevy_sprite")]
|
||||
if app.is_plugin_added::<bevy_sprite::SpritePlugin>() {
|
||||
app.add_plugins(pipeline_2d::LineGizmo2dPlugin);
|
||||
} else {
|
||||
bevy_utils::tracing::warn!("bevy_sprite feature is enabled but bevy_sprite::SpritePlugin was not detected. Are you sure you loaded GizmoPlugin after SpritePlugin?");
|
||||
}
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
if app.is_plugin_added::<bevy_pbr::PbrPlugin>() {
|
||||
app.add_plugins(pipeline_3d::LineGizmo3dPlugin);
|
||||
} else {
|
||||
bevy_utils::tracing::warn!("bevy_pbr feature is enabled but bevy_pbr::PbrPlugin was not detected. Are you sure you loaded GizmoPlugin after PbrPlugin?");
|
||||
}
|
||||
} else {
|
||||
bevy_utils::tracing::warn!("bevy_sprite feature is enabled but bevy_sprite::SpritePlugin was not detected. Are you sure you loaded GizmoPlugin after SpritePlugin?");
|
||||
}
|
||||
#[cfg(feature = "bevy_pbr")]
|
||||
if app.is_plugin_added::<bevy_pbr::PbrPlugin>() {
|
||||
app.add_plugins(pipeline_3d::LineGizmo3dPlugin);
|
||||
} else {
|
||||
bevy_utils::tracing::warn!("bevy_pbr feature is enabled but bevy_pbr::PbrPlugin was not detected. Are you sure you loaded GizmoPlugin after PbrPlugin?");
|
||||
bevy_utils::tracing::warn!("bevy_render feature is enabled but RenderApp was not detected. Are you sure you loaded GizmoPlugin after RenderPlugin?");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
fn finish(&self, app: &mut bevy_app::App) {
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
|
@ -361,14 +366,14 @@ fn update_gizmo_meshes<Config: GizmoConfigGroup>(
|
|||
list.positions = mem::take(&mut storage.list_positions);
|
||||
list.colors = mem::take(&mut storage.list_colors);
|
||||
} else {
|
||||
let mut list = LineGizmo {
|
||||
let list = LineGizmo {
|
||||
strip: false,
|
||||
..Default::default()
|
||||
config_ty: TypeId::of::<Config>(),
|
||||
positions: mem::take(&mut storage.list_positions),
|
||||
colors: mem::take(&mut storage.list_colors),
|
||||
joints: GizmoLineJoint::None,
|
||||
};
|
||||
|
||||
list.positions = mem::take(&mut storage.list_positions);
|
||||
list.colors = mem::take(&mut storage.list_colors);
|
||||
|
||||
*handle = Some(line_gizmos.add(list));
|
||||
}
|
||||
}
|
||||
|
@ -384,20 +389,20 @@ fn update_gizmo_meshes<Config: GizmoConfigGroup>(
|
|||
strip.colors = mem::take(&mut storage.strip_colors);
|
||||
strip.joints = config.line_joints;
|
||||
} else {
|
||||
let mut strip = LineGizmo {
|
||||
let strip = LineGizmo {
|
||||
strip: true,
|
||||
joints: config.line_joints,
|
||||
..Default::default()
|
||||
config_ty: TypeId::of::<Config>(),
|
||||
positions: mem::take(&mut storage.strip_positions),
|
||||
colors: mem::take(&mut storage.strip_colors),
|
||||
};
|
||||
|
||||
strip.positions = mem::take(&mut storage.strip_positions);
|
||||
strip.colors = mem::take(&mut storage.strip_colors);
|
||||
|
||||
*handle = Some(line_gizmos.add(strip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
fn extract_gizmo_data(
|
||||
mut commands: Commands,
|
||||
handles: Extract<Res<LineGizmoHandles>>,
|
||||
|
@ -431,11 +436,12 @@ fn extract_gizmo_data(
|
|||
_padding: Default::default(),
|
||||
},
|
||||
(*handle).clone_weak(),
|
||||
GizmoMeshConfig::from(config),
|
||||
config::GizmoMeshConfig::from(config),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Component, ShaderType, Clone, Copy)]
|
||||
struct LineGizmoUniform {
|
||||
line_width: f32,
|
||||
|
@ -447,16 +453,22 @@ struct LineGizmoUniform {
|
|||
_padding: f32,
|
||||
}
|
||||
|
||||
#[derive(Asset, Debug, Default, Clone, TypePath)]
|
||||
struct LineGizmo {
|
||||
positions: Vec<Vec3>,
|
||||
colors: Vec<LinearRgba>,
|
||||
/// A gizmo asset that represents a line.
|
||||
#[derive(Asset, Debug, Clone, TypePath)]
|
||||
pub struct LineGizmo {
|
||||
/// Positions of the gizmo's vertices
|
||||
pub positions: Vec<Vec3>,
|
||||
/// Colors of the gizmo's vertices
|
||||
pub colors: Vec<LinearRgba>,
|
||||
/// Whether this gizmo's topology is a line-strip or line-list
|
||||
strip: bool,
|
||||
pub strip: bool,
|
||||
/// Whether this gizmo should draw line joints. This is only applicable if the gizmo's topology is line-strip.
|
||||
joints: GizmoLineJoint,
|
||||
pub joints: GizmoLineJoint,
|
||||
/// The type of the gizmo's configuration group
|
||||
pub config_ty: TypeId,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Debug, Clone)]
|
||||
struct GpuLineGizmo {
|
||||
position_buffer: Buffer,
|
||||
|
@ -466,6 +478,7 @@ struct GpuLineGizmo {
|
|||
joints: GizmoLineJoint,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
impl RenderAsset for GpuLineGizmo {
|
||||
type SourceAsset = LineGizmo;
|
||||
type Param = SRes<RenderDevice>;
|
||||
|
@ -498,16 +511,19 @@ impl RenderAsset for GpuLineGizmo {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Resource)]
|
||||
struct LineGizmoUniformBindgroupLayout {
|
||||
layout: BindGroupLayout,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Resource)]
|
||||
struct LineGizmoUniformBindgroup {
|
||||
bindgroup: BindGroup,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
fn prepare_line_gizmo_bind_group(
|
||||
mut commands: Commands,
|
||||
line_gizmo_uniform_layout: Res<LineGizmoUniformBindgroupLayout>,
|
||||
|
@ -525,7 +541,9 @@ fn prepare_line_gizmo_bind_group(
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
struct SetLineGizmoBindGroup<const I: usize>;
|
||||
#[cfg(feature = "bevy_render")]
|
||||
impl<const I: usize, P: PhaseItem> RenderCommand<P> for SetLineGizmoBindGroup<I> {
|
||||
type Param = SRes<LineGizmoUniformBindgroup>;
|
||||
type ViewQuery = ();
|
||||
|
@ -551,7 +569,9 @@ impl<const I: usize, P: PhaseItem> RenderCommand<P> for SetLineGizmoBindGroup<I>
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
struct DrawLineGizmo;
|
||||
#[cfg(feature = "bevy_render")]
|
||||
impl<P: PhaseItem> RenderCommand<P> for DrawLineGizmo {
|
||||
type Param = SRes<RenderAssets<GpuLineGizmo>>;
|
||||
type ViewQuery = ();
|
||||
|
@ -597,7 +617,9 @@ impl<P: PhaseItem> RenderCommand<P> for DrawLineGizmo {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
struct DrawLineJointGizmo;
|
||||
#[cfg(feature = "bevy_render")]
|
||||
impl<P: PhaseItem> RenderCommand<P> for DrawLineJointGizmo {
|
||||
type Param = SRes<RenderAssets<GpuLineGizmo>>;
|
||||
type ViewQuery = ();
|
||||
|
@ -649,6 +671,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawLineJointGizmo {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
fn line_gizmo_vertex_buffer_layouts(strip: bool) -> Vec<VertexBufferLayout> {
|
||||
use VertexFormat::*;
|
||||
let mut position_layout = VertexBufferLayout {
|
||||
|
@ -705,6 +728,7 @@ fn line_gizmo_vertex_buffer_layouts(strip: bool) -> Vec<VertexBufferLayout> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
fn line_joint_gizmo_vertex_buffer_layouts() -> Vec<VertexBufferLayout> {
|
||||
use VertexFormat::*;
|
||||
let mut position_layout = VertexBufferLayout {
|
||||
|
|
|
@ -152,7 +152,11 @@ accesskit_unix = ["bevy_winit/accesskit_unix"]
|
|||
|
||||
bevy_text = ["dep:bevy_text", "bevy_ui?/bevy_text"]
|
||||
|
||||
bevy_render = ["dep:bevy_render", "bevy_scene?/bevy_render"]
|
||||
bevy_render = [
|
||||
"dep:bevy_render",
|
||||
"bevy_scene?/bevy_render",
|
||||
"bevy_gizmos?/bevy_render",
|
||||
]
|
||||
|
||||
# Enable assertions to check the validity of parameters passed to glam
|
||||
glam_assert = ["bevy_math/glam_assert"]
|
||||
|
|
Loading…
Reference in a new issue