mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
ExtractResourcePlugin (#3745)
# Objective - Add an `ExtractResourcePlugin` for convenience and consistency ## Solution - Add an `ExtractResourcePlugin` similar to `ExtractComponentPlugin` but for ECS `Resource`s. The system that is executed simply clones the main world resource into a render world resource, if and only if the main world resource was either added or changed since the last execution of the system. - Add an `ExtractResource` trait with a `fn extract_resource(res: &Self) -> Self` function. This is used by the `ExtractResourcePlugin` to extract the resource - Add a derive macro for `ExtractResource` on a `Resource` with the `Clone` trait, that simply returns `res.clone()` - Use `ExtractResourcePlugin` wherever both possible and appropriate
This commit is contained in:
parent
ba53a44956
commit
a0a3d8798b
21 changed files with 154 additions and 75 deletions
|
@ -24,6 +24,7 @@ use bevy_ecs::prelude::*;
|
|||
use bevy_render::{
|
||||
camera::{ActiveCamera, Camera2d, Camera3d, ExtractedCamera, RenderTarget},
|
||||
color::Color,
|
||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||
render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType},
|
||||
render_phase::{
|
||||
batch_phase_system, sort_phase_system, BatchedPhaseItem, CachedRenderPipelinePhaseItem,
|
||||
|
@ -33,7 +34,7 @@ use bevy_render::{
|
|||
renderer::RenderDevice,
|
||||
texture::TextureCache,
|
||||
view::{ExtractedView, Msaa, ViewDepthTexture},
|
||||
RenderApp, RenderStage, RenderWorld,
|
||||
RenderApp, RenderStage,
|
||||
};
|
||||
use bevy_utils::FloatOrd;
|
||||
|
||||
|
@ -41,7 +42,7 @@ use bevy_utils::FloatOrd;
|
|||
///
|
||||
/// This color appears as the "background" color for simple apps, when
|
||||
/// there are portions of the screen with nothing rendered.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, ExtractResource)]
|
||||
pub struct ClearColor(pub Color);
|
||||
|
||||
impl Default for ClearColor {
|
||||
|
@ -50,7 +51,7 @@ impl Default for ClearColor {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug, Default, ExtractResource)]
|
||||
pub struct RenderTargetClearColors {
|
||||
colors: HashMap<RenderTarget, Color>,
|
||||
}
|
||||
|
@ -113,7 +114,9 @@ pub enum CorePipelineRenderSystems {
|
|||
impl Plugin for CorePipelinePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<ClearColor>()
|
||||
.init_resource::<RenderTargetClearColors>();
|
||||
.init_resource::<RenderTargetClearColors>()
|
||||
.add_plugin(ExtractResourcePlugin::<ClearColor>::default())
|
||||
.add_plugin(ExtractResourcePlugin::<RenderTargetClearColors>::default());
|
||||
|
||||
let render_app = match app.get_sub_app_mut(RenderApp) {
|
||||
Ok(render_app) => render_app,
|
||||
|
@ -125,7 +128,6 @@ impl Plugin for CorePipelinePlugin {
|
|||
.init_resource::<DrawFunctions<Opaque3d>>()
|
||||
.init_resource::<DrawFunctions<AlphaMask3d>>()
|
||||
.init_resource::<DrawFunctions<Transparent3d>>()
|
||||
.add_system_to_stage(RenderStage::Extract, extract_clear_color)
|
||||
.add_system_to_stage(RenderStage::Extract, extract_core_pipeline_camera_phases)
|
||||
.add_system_to_stage(RenderStage::Prepare, prepare_core_views_system)
|
||||
.add_system_to_stage(
|
||||
|
@ -347,24 +349,6 @@ impl CachedRenderPipelinePhaseItem for Transparent3d {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn extract_clear_color(
|
||||
clear_color: Res<ClearColor>,
|
||||
clear_colors: Res<RenderTargetClearColors>,
|
||||
mut render_world: ResMut<RenderWorld>,
|
||||
) {
|
||||
// If the clear color has changed
|
||||
if clear_color.is_changed() {
|
||||
// Update the clear color resource in the render world
|
||||
render_world.insert_resource(clear_color.clone());
|
||||
}
|
||||
|
||||
// If the clear color has changed
|
||||
if clear_colors.is_changed() {
|
||||
// Update the clear color resource in the render world
|
||||
render_world.insert_resource(clear_colors.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_core_pipeline_camera_phases(
|
||||
mut commands: Commands,
|
||||
active_2d: Res<ActiveCamera<Camera2d>>,
|
||||
|
|
|
@ -39,6 +39,7 @@ use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped};
|
|||
use bevy_ecs::prelude::*;
|
||||
use bevy_reflect::TypeUuid;
|
||||
use bevy_render::{
|
||||
extract_resource::ExtractResourcePlugin,
|
||||
prelude::Color,
|
||||
render_graph::RenderGraph,
|
||||
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions},
|
||||
|
@ -76,6 +77,7 @@ impl Plugin for PbrPlugin {
|
|||
.init_resource::<GlobalVisiblePointLights>()
|
||||
.init_resource::<DirectionalLightShadowMap>()
|
||||
.init_resource::<PointLightShadowMap>()
|
||||
.add_plugin(ExtractResourcePlugin::<AmbientLight>::default())
|
||||
.add_system_to_stage(
|
||||
CoreStage::PostUpdate,
|
||||
// NOTE: Clusters need to have been added before update_clusters is run so
|
||||
|
|
|
@ -9,6 +9,7 @@ use bevy_reflect::prelude::*;
|
|||
use bevy_render::{
|
||||
camera::{Camera, CameraProjection, OrthographicProjection},
|
||||
color::Color,
|
||||
extract_resource::ExtractResource,
|
||||
prelude::Image,
|
||||
primitives::{Aabb, CubemapFrusta, Frustum, Plane, Sphere},
|
||||
render_resource::BufferBindingType,
|
||||
|
@ -170,7 +171,7 @@ impl Default for DirectionalLightShadowMap {
|
|||
}
|
||||
|
||||
/// An ambient light, which lights the entire scene equally.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug, ExtractResource)]
|
||||
pub struct AmbientLight {
|
||||
pub color: Color,
|
||||
/// A direct scale factor multiplied with `color` before being passed to the shader.
|
||||
|
|
|
@ -15,9 +15,9 @@ use bevy_ecs::{
|
|||
world::FromWorld,
|
||||
};
|
||||
use bevy_render::{
|
||||
extract_component::ExtractComponentPlugin,
|
||||
mesh::{Mesh, MeshVertexBufferLayout},
|
||||
render_asset::{RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||
render_component::ExtractComponentPlugin,
|
||||
render_phase::{
|
||||
AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase,
|
||||
SetItemPipeline, TrackedRenderPass,
|
||||
|
|
|
@ -45,11 +45,6 @@ pub enum RenderLightSystems {
|
|||
QueueShadows,
|
||||
}
|
||||
|
||||
pub struct ExtractedAmbientLight {
|
||||
color: Color,
|
||||
brightness: f32,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct ExtractedPointLight {
|
||||
color: Color,
|
||||
|
@ -63,8 +58,6 @@ pub struct ExtractedPointLight {
|
|||
shadow_normal_bias: f32,
|
||||
}
|
||||
|
||||
pub type ExtractedPointLightShadowMap = PointLightShadowMap;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct ExtractedDirectionalLight {
|
||||
color: Color,
|
||||
|
@ -76,8 +69,6 @@ pub struct ExtractedDirectionalLight {
|
|||
shadow_normal_bias: f32,
|
||||
}
|
||||
|
||||
pub type ExtractedDirectionalLightShadowMap = DirectionalLightShadowMap;
|
||||
|
||||
#[derive(Copy, Clone, ShaderType, Default, Debug)]
|
||||
pub struct GpuPointLight {
|
||||
// The lower-right 2x2 values of the projection matrix 22 23 32 33
|
||||
|
@ -408,7 +399,6 @@ pub fn extract_clusters(mut commands: Commands, views: Query<(Entity, &Clusters)
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn extract_lights(
|
||||
mut commands: Commands,
|
||||
ambient_light: Res<AmbientLight>,
|
||||
point_light_shadow_map: Res<PointLightShadowMap>,
|
||||
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
|
||||
global_point_lights: Res<GlobalVisiblePointLights>,
|
||||
|
@ -422,14 +412,14 @@ pub fn extract_lights(
|
|||
)>,
|
||||
mut previous_point_lights_len: Local<usize>,
|
||||
) {
|
||||
commands.insert_resource(ExtractedAmbientLight {
|
||||
color: ambient_light.color,
|
||||
brightness: ambient_light.brightness,
|
||||
});
|
||||
commands.insert_resource::<ExtractedPointLightShadowMap>(point_light_shadow_map.clone());
|
||||
commands.insert_resource::<ExtractedDirectionalLightShadowMap>(
|
||||
directional_light_shadow_map.clone(),
|
||||
);
|
||||
// NOTE: These shadow map resources are extracted here as they are used here too so this avoids
|
||||
// races between scheduling of ExtractResourceSystems and this system.
|
||||
if point_light_shadow_map.is_changed() {
|
||||
commands.insert_resource(point_light_shadow_map.clone());
|
||||
}
|
||||
if directional_light_shadow_map.is_changed() {
|
||||
commands.insert_resource(directional_light_shadow_map.clone());
|
||||
}
|
||||
// This is the point light shadow map texel size for one face of the cube as a distance of 1.0
|
||||
// world unit from the light.
|
||||
// point_light_texel_size = 2.0 * 1.0 * tan(PI / 4.0) / cube face width in texels
|
||||
|
@ -665,9 +655,9 @@ pub fn prepare_lights(
|
|||
(Entity, &ExtractedView, &ExtractedClusterConfig),
|
||||
With<RenderPhase<Transparent3d>>,
|
||||
>,
|
||||
ambient_light: Res<ExtractedAmbientLight>,
|
||||
point_light_shadow_map: Res<ExtractedPointLightShadowMap>,
|
||||
directional_light_shadow_map: Res<ExtractedDirectionalLightShadowMap>,
|
||||
ambient_light: Res<AmbientLight>,
|
||||
point_light_shadow_map: Res<PointLightShadowMap>,
|
||||
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
|
||||
point_lights: Query<(Entity, &ExtractedPointLight)>,
|
||||
directional_lights: Query<(Entity, &ExtractedDirectionalLight)>,
|
||||
) {
|
||||
|
|
|
@ -12,12 +12,12 @@ use bevy_ecs::{
|
|||
use bevy_math::{Mat4, Vec2};
|
||||
use bevy_reflect::TypeUuid;
|
||||
use bevy_render::{
|
||||
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||
mesh::{
|
||||
skinning::{SkinnedMesh, SkinnedMeshInverseBindposes},
|
||||
GpuBufferInfo, Mesh, MeshVertexBufferLayout,
|
||||
},
|
||||
render_asset::RenderAssets,
|
||||
render_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
|
||||
render_resource::*,
|
||||
renderer::{RenderDevice, RenderQueue},
|
||||
|
|
|
@ -7,6 +7,7 @@ use bevy_ecs::{prelude::*, reflect::ReflectComponent};
|
|||
use bevy_reflect::std_traits::ReflectDefault;
|
||||
use bevy_reflect::{Reflect, TypeUuid};
|
||||
use bevy_render::{
|
||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||
mesh::{Mesh, MeshVertexBufferLayout},
|
||||
render_asset::RenderAssets,
|
||||
render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline},
|
||||
|
@ -34,7 +35,8 @@ impl Plugin for WireframePlugin {
|
|||
Shader::from_wgsl
|
||||
);
|
||||
|
||||
app.init_resource::<WireframeConfig>();
|
||||
app.init_resource::<WireframeConfig>()
|
||||
.add_plugin(ExtractResourcePlugin::<WireframeConfig>::default());
|
||||
|
||||
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app
|
||||
|
@ -42,18 +44,11 @@ impl Plugin for WireframePlugin {
|
|||
.init_resource::<WireframePipeline>()
|
||||
.init_resource::<SpecializedMeshPipelines<WireframePipeline>>()
|
||||
.add_system_to_stage(RenderStage::Extract, extract_wireframes)
|
||||
.add_system_to_stage(RenderStage::Extract, extract_wireframe_config)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_wireframes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_wireframe_config(mut commands: Commands, wireframe_config: Res<WireframeConfig>) {
|
||||
if wireframe_config.is_added() || wireframe_config.is_changed() {
|
||||
commands.insert_resource(wireframe_config.into_inner().clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_wireframes(mut commands: Commands, query: Query<Entity, With<Wireframe>>) {
|
||||
for entity in query.iter() {
|
||||
commands.get_or_spawn(entity).insert(Wireframe);
|
||||
|
@ -65,7 +60,7 @@ fn extract_wireframes(mut commands: Commands, query: Query<Entity, With<Wirefram
|
|||
#[reflect(Component, Default)]
|
||||
pub struct Wireframe;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone, Default, ExtractResource)]
|
||||
pub struct WireframeConfig {
|
||||
/// Whether to show wireframes for all meshes. If `false`, only meshes with a [Wireframe] component will be rendered.
|
||||
pub global: bool,
|
||||
|
|
|
@ -36,6 +36,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.8.0-dev" }
|
|||
bevy_encase_derive = { path = "../bevy_encase_derive", version = "0.8.0-dev" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.8.0-dev" }
|
||||
bevy_reflect = { path = "../bevy_reflect", version = "0.8.0-dev", features = ["bevy"] }
|
||||
bevy_render_macros = { path = "macros", version = "0.8.0-dev" }
|
||||
bevy_transform = { path = "../bevy_transform", version = "0.8.0-dev" }
|
||||
bevy_window = { path = "../bevy_window", version = "0.8.0-dev" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
|
||||
|
|
19
crates/bevy_render/macros/Cargo.toml
Normal file
19
crates/bevy_render/macros/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "bevy_render_macros"
|
||||
version = "0.8.0-dev"
|
||||
edition = "2021"
|
||||
description = "Derive implementations for bevy_render"
|
||||
homepage = "https://bevyengine.org"
|
||||
repository = "https://github.com/bevyengine/bevy"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["bevy"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.8.0-dev" }
|
||||
|
||||
syn = "1.0"
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
26
crates/bevy_render/macros/src/extract_resource.rs
Normal file
26
crates/bevy_render/macros/src/extract_resource.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, parse_quote, DeriveInput, Path};
|
||||
|
||||
pub fn derive_extract_resource(input: TokenStream) -> TokenStream {
|
||||
let mut ast = parse_macro_input!(input as DeriveInput);
|
||||
let bevy_render_path: Path = crate::bevy_render_path();
|
||||
|
||||
ast.generics
|
||||
.make_where_clause()
|
||||
.predicates
|
||||
.push(parse_quote! { Self: Clone });
|
||||
|
||||
let struct_name = &ast.ident;
|
||||
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
|
||||
|
||||
TokenStream::from(quote! {
|
||||
impl #impl_generics #bevy_render_path::extract_resource::ExtractResource for #struct_name #type_generics #where_clause {
|
||||
type Source = Self;
|
||||
|
||||
fn extract_resource(source: &Self::Source) -> Self {
|
||||
source.clone()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
16
crates/bevy_render/macros/src/lib.rs
Normal file
16
crates/bevy_render/macros/src/lib.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
mod extract_resource;
|
||||
|
||||
use bevy_macro_utils::BevyManifest;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
pub(crate) fn bevy_render_path() -> syn::Path {
|
||||
BevyManifest::default()
|
||||
.maybe_get_path("bevy_render")
|
||||
// NOTE: If the derivation is within bevy_render, then we need to return 'crate'
|
||||
.unwrap_or_else(|| BevyManifest::parse_str("crate"))
|
||||
}
|
||||
|
||||
#[proc_macro_derive(ExtractResource)]
|
||||
pub fn derive_extract_resource(input: TokenStream) -> TokenStream {
|
||||
extract_resource::derive_extract_resource(input)
|
||||
}
|
46
crates/bevy_render/src/extract_resource.rs
Normal file
46
crates/bevy_render/src/extract_resource.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_ecs::system::{Commands, Res, Resource};
|
||||
pub use bevy_render_macros::ExtractResource;
|
||||
|
||||
use crate::{RenderApp, RenderStage};
|
||||
|
||||
/// Describes how a resource gets extracted for rendering.
|
||||
///
|
||||
/// Therefore the resource is transferred from the "main world" into the "render world"
|
||||
/// in the [`RenderStage::Extract`](crate::RenderStage::Extract) step.
|
||||
pub trait ExtractResource: Resource {
|
||||
type Source: Resource;
|
||||
|
||||
/// Defines how the resource is transferred into the "render world".
|
||||
fn extract_resource(source: &Self::Source) -> Self;
|
||||
}
|
||||
|
||||
/// This plugin extracts the resources into the "render world".
|
||||
///
|
||||
/// Therefore it sets up the [`RenderStage::Extract`](crate::RenderStage::Extract) step
|
||||
/// for the specified [`Resource`].
|
||||
pub struct ExtractResourcePlugin<R: ExtractResource>(PhantomData<R>);
|
||||
|
||||
impl<R: ExtractResource> Default for ExtractResourcePlugin<R> {
|
||||
fn default() -> Self {
|
||||
Self(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: ExtractResource> Plugin for ExtractResourcePlugin<R> {
|
||||
fn build(&self, app: &mut App) {
|
||||
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app.add_system_to_stage(RenderStage::Extract, extract_resource::<R>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This system extracts the resource of the corresponding [`Resource`] type
|
||||
/// by cloning it.
|
||||
pub fn extract_resource<R: ExtractResource>(mut commands: Commands, resource: Res<R::Source>) {
|
||||
if resource.is_changed() {
|
||||
commands.insert_resource(R::extract_resource(resource.into_inner()));
|
||||
}
|
||||
}
|
|
@ -2,10 +2,11 @@ extern crate core;
|
|||
|
||||
pub mod camera;
|
||||
pub mod color;
|
||||
pub mod extract_component;
|
||||
pub mod extract_resource;
|
||||
pub mod mesh;
|
||||
pub mod primitives;
|
||||
pub mod render_asset;
|
||||
pub mod render_component;
|
||||
pub mod render_graph;
|
||||
pub mod render_phase;
|
||||
pub mod render_resource;
|
||||
|
|
|
@ -10,6 +10,7 @@ pub use window::*;
|
|||
|
||||
use crate::{
|
||||
camera::ExtractedCamera,
|
||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||
prelude::Image,
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{DynamicUniformBuffer, ShaderType, Texture, TextureView},
|
||||
|
@ -27,12 +28,14 @@ pub struct ViewPlugin;
|
|||
|
||||
impl Plugin for ViewPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<Msaa>().add_plugin(VisibilityPlugin);
|
||||
app.init_resource::<Msaa>()
|
||||
// NOTE: windows.is_changed() handles cases where a window was resized
|
||||
.add_plugin(ExtractResourcePlugin::<Msaa>::default())
|
||||
.add_plugin(VisibilityPlugin);
|
||||
|
||||
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app
|
||||
.init_resource::<ViewUniforms>()
|
||||
.add_system_to_stage(RenderStage::Extract, extract_msaa)
|
||||
.add_system_to_stage(RenderStage::Prepare, prepare_view_uniforms)
|
||||
.add_system_to_stage(
|
||||
RenderStage::Prepare,
|
||||
|
@ -42,7 +45,7 @@ impl Plugin for ViewPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, ExtractResource)]
|
||||
/// Configuration resource for [Multi-Sample Anti-Aliasing](https://en.wikipedia.org/wiki/Multisample_anti-aliasing).
|
||||
///
|
||||
/// # Example
|
||||
|
@ -70,11 +73,6 @@ impl Default for Msaa {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn extract_msaa(mut commands: Commands, msaa: Res<Msaa>) {
|
||||
// NOTE: windows.is_changed() handles cases where a window was resized
|
||||
commands.insert_resource(msaa.clone());
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct ExtractedView {
|
||||
pub projection: Mat4,
|
||||
|
|
|
@ -12,9 +12,9 @@ use bevy_ecs::{
|
|||
};
|
||||
use bevy_log::error;
|
||||
use bevy_render::{
|
||||
extract_component::ExtractComponentPlugin,
|
||||
mesh::{Mesh, MeshVertexBufferLayout},
|
||||
render_asset::{RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||
render_component::ExtractComponentPlugin,
|
||||
render_phase::{
|
||||
AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase,
|
||||
SetItemPipeline, TrackedRenderPass,
|
||||
|
|
|
@ -7,9 +7,9 @@ use bevy_ecs::{
|
|||
use bevy_math::{Mat4, Vec2};
|
||||
use bevy_reflect::{Reflect, TypeUuid};
|
||||
use bevy_render::{
|
||||
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||
mesh::{GpuBufferInfo, Mesh, MeshVertexBufferLayout},
|
||||
render_asset::RenderAssets,
|
||||
render_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
|
||||
render_resource::*,
|
||||
renderer::{RenderDevice, RenderQueue},
|
||||
|
|
|
@ -7,6 +7,7 @@ use bevy::{
|
|||
core_pipeline::node::MAIN_PASS_DEPENDENCIES,
|
||||
prelude::*,
|
||||
render::{
|
||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||
render_asset::RenderAssets,
|
||||
render_graph::{self, RenderGraph},
|
||||
render_resource::*,
|
||||
|
@ -66,10 +67,12 @@ pub struct GameOfLifeComputePlugin;
|
|||
|
||||
impl Plugin for GameOfLifeComputePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
// Extract the game of life image resource from the main world into the render world
|
||||
// for operation on by the compute shader and display on the sprite.
|
||||
app.add_plugin(ExtractResourcePlugin::<GameOfLifeImage>::default());
|
||||
let render_app = app.sub_app_mut(RenderApp);
|
||||
render_app
|
||||
.init_resource::<GameOfLifePipeline>()
|
||||
.add_system_to_stage(RenderStage::Extract, extract_game_of_life_image)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_bind_group);
|
||||
|
||||
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
|
||||
|
@ -80,15 +83,11 @@ impl Plugin for GameOfLifeComputePlugin {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deref)]
|
||||
#[derive(Clone, Deref, ExtractResource)]
|
||||
struct GameOfLifeImage(Handle<Image>);
|
||||
|
||||
struct GameOfLifeImageBindGroup(BindGroup);
|
||||
|
||||
fn extract_game_of_life_image(mut commands: Commands, image: Res<GameOfLifeImage>) {
|
||||
commands.insert_resource(GameOfLifeImage(image.clone()));
|
||||
}
|
||||
|
||||
fn queue_bind_group(
|
||||
mut commands: Commands,
|
||||
pipeline: Res<GameOfLifePipeline>,
|
||||
|
|
|
@ -8,9 +8,9 @@ use bevy::{
|
|||
},
|
||||
prelude::*,
|
||||
render::{
|
||||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
mesh::MeshVertexBufferLayout,
|
||||
render_asset::RenderAssets,
|
||||
render_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline},
|
||||
render_resource::{
|
||||
PipelineCache, RenderPipelineDescriptor, SpecializedMeshPipeline,
|
||||
|
|
|
@ -7,9 +7,9 @@ use bevy::{
|
|||
pbr::{MeshPipeline, MeshPipelineKey, MeshUniform, SetMeshBindGroup, SetMeshViewBindGroup},
|
||||
prelude::*,
|
||||
render::{
|
||||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
mesh::{GpuBufferInfo, MeshVertexBufferLayout},
|
||||
render_asset::RenderAssets,
|
||||
render_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
render_phase::{
|
||||
AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase,
|
||||
SetItemPipeline, TrackedRenderPass,
|
||||
|
|
|
@ -22,6 +22,7 @@ crates=(
|
|||
bevy_transform
|
||||
bevy_window
|
||||
bevy_encase_derive
|
||||
bevy_render/macros
|
||||
bevy_render
|
||||
bevy_core_pipeline
|
||||
bevy_input
|
||||
|
|
Loading…
Reference in a new issue