Skip to content

Commit

Permalink
Refactor and upgrade to Bevy 0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
Weasy666 committed Sep 4, 2022
1 parent 8c6049f commit 83d0453
Show file tree
Hide file tree
Showing 24 changed files with 275 additions and 190 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ default = ["2d", "3d"]
3d = ["bevy/bevy_pbr"]

[dependencies]
bevy = { version = "0.7", default-features = false, features = ["bevy_core_pipeline", "bevy_render"] }
bevy = { version = "0.8", default-features = false, features = ["bevy_asset", "bevy_core_pipeline", "bevy_render"] }
copyless = "0.1"

lyon_geom = "0.17"
Expand All @@ -32,7 +32,7 @@ anyhow = "1.0"
thiserror = "1.0"

[dev-dependencies]
bevy = { version = "0.7", default-features = true }
bevy = { version = "0.8", default-features = true }

#### 2D examples ####
[[example]]
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/complex_one_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("asteroid_field.svg");
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());
let mut transform = Transform::from_xyz(0.0, 0.0, 0.0);
transform.scale = Vec3::new(2.0, 2.0, 1.0);
commands.spawn_bundle(Svg2dBundle {
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/twinkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("twinkle.svg");
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());
let mut transform = Transform::from_xyz(0.0, 0.0, 0.0);
transform.scale = Vec3::new(0.75, 0.75, 1.0);
commands.spawn_bundle(Svg2dBundle {
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/two_colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("neutron_star.svg");
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn_bundle(Svg2dBundle {
svg,
origin: Origin::Center,
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/two_colors_visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("neutron_star.svg");
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn_bundle(Svg2dBundle {
svg,
origin: Origin::Center,
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/complex_one_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("asteroid_field.svg");
commands.spawn_bundle(PerspectiveCameraBundle::new_3d());
commands.spawn_bundle(Camera3dBundle::default());
commands.spawn_bundle(Svg3dBundle {
svg,
origin: Origin::Center,
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/twinkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("twinkle.svg");
commands.spawn_bundle(PerspectiveCameraBundle {
commands.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(5.0, 8.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/two_colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("neutron_star.svg");
commands.spawn_bundle(PerspectiveCameraBundle {
commands.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(5.0, 8.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});
Expand Down
2 changes: 1 addition & 1 deletion examples/3d/two_colors_visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let svg = asset_server.load("neutron_star.svg");
commands.spawn_bundle(PerspectiveCameraBundle::new_3d());
commands.spawn_bundle(Camera3dBundle::default());
commands.spawn_bundle(Svg3dBundle {
svg,
origin: Origin::Center,
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@
clippy::cargo
)]

mod bundle;
mod loader;
mod plugin;
mod render;
mod svg;


/// Import this module as `use bevy_svg::prelude::*` to get convenient imports.
pub mod prelude {
pub use crate::{plugin::SvgPlugin, svg::{Svg, Origin}};
#[cfg(feature = "2d")]
pub use crate::bundle::Svg2dBundle;
pub use crate::render::Svg2dBundle;
#[cfg(feature = "3d")]
pub use crate::bundle::Svg3dBundle;
pub use crate::render::Svg3dBundle;
pub use lyon_tessellation::{
FillOptions, FillRule, LineCap, LineJoin, Orientation, StrokeOptions,
};
Expand Down
75 changes: 8 additions & 67 deletions src/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1,74 +1,15 @@
use bevy::{
app::{App, Plugin},
asset::{Assets, HandleUntyped},
reflect::TypeUuid,
render::{
render_phase::AddRenderCommand,
render_resource::{Shader, SpecializedRenderPipelines},
RenderApp, RenderStage,
},
};
#[cfg(feature = "2d")]
use bevy::core_pipeline::Transparent2d;
#[cfg(feature = "3d")]
use bevy::core_pipeline::Transparent3d;
use lyon_tessellation::{FillTessellator, StrokeTessellator};

#[cfg(feature = "2d")]
mod pipeline_2d;
#[cfg(feature = "3d")]
mod pipeline_3d;
mod plugin;
pub(crate) mod tessellation;
mod vertex_buffer;

#[cfg(feature = "2d")]
mod svg2d;
#[cfg(feature = "3d")]
mod svg3d;

/// Plugin that renders [`Svg`](crate::svg::Svg)s in 2D
pub struct SvgPlugin;

/// Handle to the custom shader with a unique random ID
#[cfg(feature = "2d")]
pub const SVG_2D_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8514826620251853414);
pub use svg2d::Svg2dBundle;
#[cfg(feature = "3d")]
pub const SVG_3D_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8514826640451853414);
pub use svg3d::Svg3dBundle;

impl Plugin for SvgPlugin {
fn build(&self, app: &mut App) {
let fill_tess = FillTessellator::new();
let stroke_tess = StrokeTessellator::new();
// Load SVG shader
let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
#[cfg(feature = "2d")]
shaders.set_untracked(
SVG_2D_SHADER_HANDLE,
Shader::from_wgsl(include_str!("svg_2d.wgsl")),
);
#[cfg(feature = "3d")]
shaders.set_untracked(
SVG_3D_SHADER_HANDLE,
Shader::from_wgsl(include_str!("svg_3d.wgsl")),
);
app
.insert_resource(fill_tess)
.insert_resource(stroke_tess);
// Register our custom draw function and pipeline, and add our render systems
let render_app = app.get_sub_app_mut(RenderApp).unwrap();
#[cfg(feature = "2d")]
render_app
.add_render_command::<Transparent2d, pipeline_2d::DrawSvg2d>()
.init_resource::<pipeline_2d::Svg2dPipeline>()
.init_resource::<SpecializedRenderPipelines<pipeline_2d::Svg2dPipeline>>()
.init_resource::<pipeline_2d::ExtractedSvgs2d>()
.add_system_to_stage(RenderStage::Extract, pipeline_2d::extract_svg_2d)
.add_system_to_stage(RenderStage::Prepare, pipeline_2d::prepare_svg_2d)
.add_system_to_stage(RenderStage::Queue, pipeline_2d::queue_svg_2d);
#[cfg(feature = "3d")]
render_app
.add_render_command::<Transparent3d, pipeline_3d::DrawSvg3d>()
.init_resource::<pipeline_3d::Svg3dPipeline>()
.init_resource::<SpecializedRenderPipelines<pipeline_3d::Svg3dPipeline>>()
.init_resource::<pipeline_3d::ExtractedSvgs3d>()
.add_system_to_stage(RenderStage::Extract, pipeline_3d::extract_svg_3d)
.add_system_to_stage(RenderStage::Prepare, pipeline_3d::prepare_svg_3d)
.add_system_to_stage(RenderStage::Queue, pipeline_3d::queue_svg_3d);
}
}
pub use plugin::SvgPlugin;
45 changes: 45 additions & 0 deletions src/render/plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use bevy::{
app::{App, Plugin},
asset::Assets,
render::RenderApp,
render::render_resource::Shader,
};
use lyon_tessellation::{FillTessellator, StrokeTessellator};

#[cfg(feature = "2d")]
use crate::render::svg2d;
#[cfg(feature = "3d")]
use crate::render::svg3d;


/// Plugin that renders [`Svg`](crate::svg::Svg)s in 2D
pub struct SvgPlugin;

impl Plugin for SvgPlugin {
fn build(&self, app: &mut App) {
// Load SVG shader
let mut shaders = app.world.resource_mut::<Assets<Shader>>();
#[cfg(feature = "2d")]
shaders.set_untracked(
svg2d::SVG_2D_SHADER_HANDLE,
Shader::from_wgsl(include_str!("svg2d/svg_2d.wgsl")),
);
#[cfg(feature = "3d")]
shaders.set_untracked(
svg3d::SVG_3D_SHADER_HANDLE,
Shader::from_wgsl(include_str!("svg3d/svg_3d.wgsl")),
);
let fill_tess = FillTessellator::new();
let stroke_tess = StrokeTessellator::new();
app
.insert_resource(fill_tess)
.insert_resource(stroke_tess);
// Register our custom draw function and pipeline, and add our render systems
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
#[cfg(feature = "2d")]
render_app.add_plugin(svg2d::RenderPlugin);
#[cfg(feature = "3d")]
render_app.add_plugin(svg3d::RenderPlugin);
}
}
}
41 changes: 41 additions & 0 deletions src/render/svg2d/bundle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//! Bevy [`Bundle`] representing an SVG entity.
use bevy::{
asset::Handle,
ecs::bundle::Bundle,
render::view::{ComputedVisibility, Visibility},
sprite::Mesh2dHandle,
transform::components::{GlobalTransform, Transform},
};

use crate::svg::{Origin, Svg};


/// A Bevy [`Bundle`] representing an SVG entity.
#[allow(missing_docs)]
#[derive(Bundle)]
pub struct Svg2dBundle {
pub svg: Handle<Svg>,
pub mesh_2d: Mesh2dHandle,
/// [`Origin`] of the coordinate system and as such the origin for the Bevy position.
pub origin: Origin,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub visibility: Visibility,
pub computed_visibility: ComputedVisibility,
}

impl Default for Svg2dBundle {
/// Creates a default [`Svg2dBundle`].
fn default() -> Self {
Self {
svg: Default::default(),
mesh_2d: Default::default(),
origin: Default::default(),
transform: Transform::default(),
global_transform: GlobalTransform::default(),
visibility: Visibility::default(),
computed_visibility: ComputedVisibility::default(),
}
}
}
15 changes: 15 additions & 0 deletions src/render/svg2d/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use bevy::{
asset::HandleUntyped,
reflect::TypeUuid,
render::render_resource::Shader,
};

mod bundle;
mod pipeline_2d;
mod plugin;

/// Handle to the custom shader with a unique random ID
pub const SVG_2D_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8514826620251853414);

pub use bundle::Svg2dBundle;
pub use plugin::RenderPlugin;
33 changes: 16 additions & 17 deletions src/render/pipeline_2d.rs → src/render/svg2d/pipeline_2d.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use bevy::{
asset::{Assets, Handle},
core::FloatOrd,
core_pipeline::Transparent2d,
core_pipeline::core_2d::Transparent2d,
ecs::{entity::Entity, world::{FromWorld, World}, system::{Query, Res, ResMut}},
log::debug,
math::{Vec3, Vec3Swizzles},
render::{
mesh::Mesh,
Extract, mesh::Mesh,
render_asset::RenderAssets,
render_phase::{DrawFunctions, RenderPhase, SetItemPipeline},
render_resource::{
Expand All @@ -16,17 +15,18 @@ use bevy::{
VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
},
texture::BevyDefault,
view::{ComputedVisibility, Msaa}, RenderWorld,
view::{ComputedVisibility, Msaa},
},
sprite::{
DrawMesh2d, Mesh2dHandle, Mesh2dPipeline, Mesh2dPipelineKey,
SetMesh2dBindGroup, SetMesh2dViewBindGroup, Mesh2dUniform,
},
transform::components::GlobalTransform,
transform::components::Transform,
utils::FloatOrd,
};
use copyless::VecHelper;

use crate::{render::SVG_2D_SHADER_HANDLE, svg::{Origin, Svg}};
use crate::{render::svg2d::SVG_2D_SHADER_HANDLE, svg::{Origin, Svg}};


#[derive(Default)]
Expand All @@ -44,28 +44,27 @@ pub struct ExtractedSvg2d {

/// Extract [`Svg`]s with a [`Mesh2dHandle`] component into [`RenderWorld`].
pub fn extract_svg_2d(
mut render_world: ResMut<RenderWorld>,
svgs: Res<Assets<Svg>>,
query: Query<(Entity, &ComputedVisibility, &Handle<Svg>, &Mesh2dHandle, &Origin, &GlobalTransform)>,
mut extracted_svgs: ResMut<ExtractedSvgs2d>,
svgs: Extract<Res<Assets<Svg>>>,
query: Extract<Query<(Entity, &ComputedVisibility, &Handle<Svg>, &Mesh2dHandle, &Origin, &Transform)>>,
) {
debug!("Extracting `Svg`s from `World`.");
let mut extracted_svgs = render_world.get_resource_mut::<ExtractedSvgs2d>().unwrap();
extracted_svgs.svgs.clear();
for (entity, computed_visibility, svg_handle, mesh2d_handle, origin, global_transform) in query.iter() {
if !computed_visibility.is_visible {
for (entity, computed_visibility, svg_handle, mesh2d_handle, origin, transform) in query.iter() {
if !computed_visibility.is_visible() {
continue;
}

if let Some(svg) = svgs.get(svg_handle) {
let mut transform = global_transform.clone();
let mut transform = transform.clone();
let scaled_size = svg.size * transform.scale.xy();
transform.translation += origin.compute_translation(scaled_size);

extracted_svgs.svgs.alloc().init(ExtractedSvg2d {
entity,
mesh2d_handle: mesh2d_handle.clone(),
origin_offset: origin.compute_translation(scaled_size),
z: global_transform.translation.z,
z: transform.translation.z,
});
}
}
Expand Down Expand Up @@ -173,7 +172,7 @@ impl SpecializedRenderPipeline for Svg2dPipeline {
// Position
VertexFormat::Float32x3,
// Color
VertexFormat::Uint32,
VertexFormat::Float32x4,
];

RenderPipelineDescriptor {
Expand All @@ -190,11 +189,11 @@ impl SpecializedRenderPipeline for Svg2dPipeline {
shader: SVG_2D_SHADER_HANDLE.typed::<Shader>(),
shader_defs: Vec::new(),
entry_point: "fragment".into(),
targets: vec![ColorTargetState {
targets: vec![Some(ColorTargetState {
format: TextureFormat::bevy_default(),
blend: Some(BlendState::ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
}],
})],
}),
// Use the two standard uniforms for 2d meshes
layout: Some(vec![
Expand Down
Loading

0 comments on commit 83d0453

Please sign in to comment.