diff --git a/Cargo.toml b/Cargo.toml index e8fa50b..3617d88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ authors = [ [dependencies] bitflags = "2.3" -bevy = { version = "0.11.0", default-features = false, features = [ +bevy = { version = "0.12", default-features = false, features = [ "bevy_core_pipeline", "bevy_render", "bevy_asset", @@ -26,13 +26,13 @@ bevy = { version = "0.11.0", default-features = false, features = [ [dependencies.naga] features = ["glsl-in", "spv-out", "wgsl-out"] -version = "0.12" +version = "0.13" [dev-dependencies] lazy_static = "1.4.0" rand = "0.8.4" -ringbuffer = "0.14" -bevy = { version = "0.11.0", default-features = false, features = [ +ringbuffer = "0.15" +bevy = { version = "0.12", default-features = false, features = [ "bevy_winit", "bevy_pbr", "x11", diff --git a/examples/nbody.rs b/examples/nbody.rs index 590f748..8d1d89d 100644 --- a/examples/nbody.rs +++ b/examples/nbody.rs @@ -9,7 +9,7 @@ use bevy_polyline::prelude::*; use lazy_static::*; use rand::{prelude::*, Rng}; -use ringbuffer::{ConstGenericRingBuffer, RingBufferExt, RingBufferWrite}; +use ringbuffer::{ConstGenericRingBuffer, RingBuffer}; const NUM_BODIES: usize = 512; const TRAIL_LENGTH: usize = 1024; @@ -208,7 +208,7 @@ fn update_trails( query.for_each_mut(|(body, mut trail, polyline)| { if let Some(position) = trail.0.back() { let last_vec = *position - body.position; - let last_last_vec = if let Some(position) = trail.0.get(-2) { + let last_last_vec = if let Some(position) = trail.0.get_signed(-2) { *position - body.position } else { last_vec @@ -221,7 +221,7 @@ fn update_trails( } else { // If the last point didn't actually add much of a curve, just overwrite it. if polylines.get_mut(polyline).unwrap().vertices.len() > 1 { - *trail.0.get_mut(-1).unwrap() = body.position; + *trail.0.get_mut_signed(-1).unwrap() = body.position; *polylines .get_mut(polyline) .unwrap() diff --git a/src/lib.rs b/src/lib.rs index c79b66e..16619fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![allow(clippy::type_complexity)] #![allow(clippy::too_many_arguments)] -use bevy::{prelude::*, reflect::TypeUuid}; +use bevy::{asset::embedded_asset, prelude::*}; use material::PolylineMaterialPlugin; use polyline::{PolylineBasePlugin, PolylineRenderPlugin}; @@ -13,19 +13,15 @@ pub mod prelude { pub use crate::polyline::{Polyline, PolylineBundle}; pub use crate::PolylinePlugin; } - -pub const SHADER_HANDLE: HandleUntyped = - HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 12823766040132746065); - pub struct PolylinePlugin; impl Plugin for PolylinePlugin { fn build(&self, app: &mut bevy::prelude::App) { - let mut shaders = app.world.get_resource_mut::>().unwrap(); - shaders.set_untracked( - SHADER_HANDLE, - Shader::from_wgsl(include_str!("shaders/polyline.wgsl"), file!()), - ); + #[cfg(target_family = "windows")] + embedded_asset!(app, "src\\", "shaders\\polyline.wgsl"); + #[cfg(not(target_family = "windows"))] + embedded_asset!(app, "src/", "shaders/polyline.wgsl"); + app.add_plugins(( PolylineBasePlugin, PolylineRenderPlugin, diff --git a/src/material.rs b/src/material.rs index ed9eab2..eb9c613 100644 --- a/src/material.rs +++ b/src/material.rs @@ -1,10 +1,8 @@ -use crate::{ - polyline::{ - DrawPolyline, PolylinePipeline, PolylinePipelineKey, PolylineUniform, - PolylineViewBindGroup, SetPolylineBindGroup, - }, - SHADER_HANDLE, +use crate::polyline::{ + DrawPolyline, PolylinePipeline, PolylinePipelineKey, PolylineUniform, PolylineViewBindGroup, + SetPolylineBindGroup, }; + use bevy::{ core_pipeline::core_3d::{AlphaMask3d, Opaque3d, Transparent3d}, ecs::{ @@ -28,7 +26,7 @@ use bevy::{ }; use std::fmt::Debug; -#[derive(Component, Debug, PartialEq, Clone, Copy, TypeUuid, TypePath)] +#[derive(Asset, Debug, PartialEq, Clone, Copy, TypeUuid, TypePath)] #[uuid = "69b87497-2ba0-4c38-ba82-f54bf1ffe873"] pub struct PolylineMaterial { /// Width of the line. @@ -73,14 +71,6 @@ impl Default for PolylineMaterial { } impl PolylineMaterial { - fn fragment_shader() -> Handle { - SHADER_HANDLE.typed() - } - - fn vertex_shader() -> Handle { - SHADER_HANDLE.typed() - } - pub fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayout { render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[BindGroupLayoutEntry { @@ -152,14 +142,14 @@ impl RenderAsset for PolylineMaterial { let mut buffer = UniformBuffer::from(value); buffer.write_buffer(device, queue); - let bind_group = device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { + let bind_group = device.create_bind_group( + Some("polyline_material_bind_group"), + &polyline_pipeline.material_layout, + &[BindGroupEntry { binding: 0, resource: buffer.binding().unwrap(), }], - label: Some("polyline_material_bind_group"), - layout: &polyline_pipeline.material_layout, - }); + ); let alpha_mode = if material.color.a() < 1.0 { AlphaMode::Blend @@ -182,7 +172,7 @@ pub struct PolylineMaterialPlugin; impl Plugin for PolylineMaterialPlugin { fn build(&self, app: &mut App) { - app.add_asset::() + app.init_asset::() .add_plugins(ExtractComponentPlugin::>::default()) .add_plugins(RenderAssetPlugin::::default()); } @@ -204,8 +194,6 @@ impl Plugin for PolylineMaterialPlugin { pub struct PolylineMaterialPipeline { pub polyline_pipeline: PolylinePipeline, pub material_layout: BindGroupLayout, - pub vertex_shader: Handle, - pub fragment_shader: Handle, } impl FromWorld for PolylineMaterialPipeline { @@ -216,8 +204,6 @@ impl FromWorld for PolylineMaterialPipeline { PolylineMaterialPipeline { polyline_pipeline: world.get_resource::().unwrap().to_owned(), material_layout, - vertex_shader: PolylineMaterial::vertex_shader(), - fragment_shader: PolylineMaterial::fragment_shader(), } } } @@ -358,6 +344,8 @@ pub fn queue_material_polylines( // -z in front of the camera, values in view space decrease away from the // camera. Flipping the sign of mesh_z results in the correct front-to-back ordering distance: -polyline_z, + batch_range: 0..1, + dynamic_offset: None, }); } AlphaMode::Mask(_) => { @@ -370,6 +358,8 @@ pub fn queue_material_polylines( // -z in front of the camera, values in view space decrease away from the // camera. Flipping the sign of mesh_z results in the correct front-to-back ordering distance: -polyline_z, + batch_range: 0..1, + dynamic_offset: None, }); } AlphaMode::Blend @@ -385,6 +375,8 @@ pub fn queue_material_polylines( // -z in front of the camera, the largest distance is -far with values increasing toward the // camera. As such we can just use mesh_z as the distance distance: polyline_z, + batch_range: 0..1, + dynamic_offset: None, }); } } diff --git a/src/polyline.rs b/src/polyline.rs index add93fe..5d886ef 100644 --- a/src/polyline.rs +++ b/src/polyline.rs @@ -1,4 +1,4 @@ -use crate::{material::PolylineMaterial, SHADER_HANDLE}; +use crate::material::PolylineMaterial; use bevy::{ core::cast_slice, ecs::{ @@ -26,7 +26,7 @@ pub struct PolylineBasePlugin; impl Plugin for PolylineBasePlugin { fn build(&self, app: &mut App) { - app.add_asset::() + app.init_asset::() .add_plugins(RenderAssetPlugin::::default()); } } @@ -44,8 +44,8 @@ impl Plugin for PolylineRenderPlugin { .add_systems( Render, ( - queue_polyline_bind_group.in_set(RenderSet::Queue), - queue_polyline_view_bind_groups.in_set(RenderSet::Queue), + prepare_polyline_bind_group.in_set(RenderSet::PrepareBindGroups), + prepare_polyline_view_bind_groups.in_set(RenderSet::PrepareBindGroups), ), ); } @@ -60,10 +60,11 @@ pub struct PolylineBundle { /// User indication of whether an entity is visible pub visibility: Visibility, /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering - pub computed_visibility: ComputedVisibility, + pub inherited_visibility: InheritedVisibility, + pub view_visibility: ViewVisibility, } -#[derive(Debug, Default, Component, Clone, TypeUuid, TypePath)] +#[derive(Debug, Default, Asset, Clone, TypeUuid, TypePath)] #[uuid = "c76af88a-8afe-405c-9a64-0a7d845d2546"] pub struct Polyline { pub vertices: Vec, @@ -120,15 +121,16 @@ pub fn extract_polylines( query: Extract< Query<( Entity, - &ComputedVisibility, + &InheritedVisibility, + &ViewVisibility, &GlobalTransform, &Handle, )>, >, ) { let mut values = Vec::with_capacity(*previous_len); - for (entity, computed_visibility, transform, handle) in query.iter() { - if !computed_visibility.is_visible() { + for (entity, inherited_visibility, view_visibility, transform, handle) in query.iter() { + if !inherited_visibility.get() || !view_visibility.get() { continue; } let transform = transform.compute_matrix(); @@ -151,6 +153,7 @@ pub fn extract_polylines( pub struct PolylinePipeline { pub view_layout: BindGroupLayout, pub polyline_layout: BindGroupLayout, + pub shader: Handle, } impl FromWorld for PolylinePipeline { @@ -186,9 +189,12 @@ impl FromWorld for PolylinePipeline { }], label: Some("polyline_layout"), }); + + let assets = world.resource_mut::(); PolylinePipeline { view_layout, polyline_layout, + shader: assets.load("embedded://bevy_polyline/shaders/polyline.wgsl"), } } } @@ -241,7 +247,7 @@ impl SpecializedRenderPipeline for PolylinePipeline { RenderPipelineDescriptor { vertex: VertexState { - shader: SHADER_HANDLE.typed::(), + shader: self.shader.clone(), entry_point: "vertex".into(), shader_defs: shader_defs.clone(), buffers: vec![VertexBufferLayout { @@ -251,7 +257,7 @@ impl SpecializedRenderPipeline for PolylinePipeline { }], }, fragment: Some(FragmentState { - shader: SHADER_HANDLE.typed::(), + shader: self.shader.clone(), shader_defs, entry_point: "fragment".into(), targets: vec![Some(ColorTargetState { @@ -339,7 +345,7 @@ pub struct PolylineBindGroup { pub value: BindGroup, } -pub fn queue_polyline_bind_group( +pub fn prepare_polyline_bind_group( mut commands: Commands, polyline_pipeline: Res, render_device: Res, @@ -347,14 +353,14 @@ pub fn queue_polyline_bind_group( ) { if let Some(binding) = polyline_uniforms.uniforms().binding() { commands.insert_resource(PolylineBindGroup { - value: render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { + value: render_device.create_bind_group( + Some("polyline_bind_group"), + &polyline_pipeline.polyline_layout, + &[BindGroupEntry { binding: 0, resource: binding, }], - label: Some("polyline_bind_group"), - layout: &polyline_pipeline.polyline_layout, - }), + ), }); } } @@ -365,7 +371,7 @@ pub struct PolylineViewBindGroup { } #[allow(clippy::too_many_arguments)] -pub fn queue_polyline_view_bind_groups( +pub fn prepare_polyline_view_bind_groups( mut commands: Commands, render_device: Res, polyline_pipeline: Res, @@ -374,14 +380,14 @@ pub fn queue_polyline_view_bind_groups( ) { if let Some(view_binding) = view_uniforms.uniforms.binding() { for entity in views.iter() { - let view_bind_group = render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { + let view_bind_group = render_device.create_bind_group( + Some("polyline_view_bind_group"), + &polyline_pipeline.view_layout, + &[BindGroupEntry { binding: 0, resource: view_binding.clone(), }], - label: Some("polyline_view_bind_group"), - layout: &polyline_pipeline.view_layout, - }); + ); commands.entity(entity).insert(PolylineViewBindGroup { value: view_bind_group, diff --git a/src/shaders/polyline.wgsl b/src/shaders/polyline.wgsl index b75a16b..2ebde5a 100644 --- a/src/shaders/polyline.wgsl +++ b/src/shaders/polyline.wgsl @@ -1,4 +1,4 @@ -#import bevy_render::view View +#import bevy_render::view::View @group(0) @binding(0) var view: View;