start making ResourceProvider::update world read-only
This commit is contained in:
		
							parent
							
								
									78d1958090
								
							
						
					
					
						commit
						08abef1c75
					
				| @ -151,6 +151,7 @@ impl AppBuilder { | ||||
|             .add_stage(stage::FIRST) | ||||
|             .add_stage(stage::EVENT_UPDATE) | ||||
|             .add_stage(stage::UPDATE) | ||||
|             .add_stage(stage::POST_UPDATE) | ||||
|             .add_stage(stage::LAST) | ||||
|     } | ||||
| 
 | ||||
| @ -162,6 +163,14 @@ impl AppBuilder { | ||||
|         self.add_system(system) | ||||
|     } | ||||
| 
 | ||||
|     pub fn build_system_on_stage<F>(&mut self, stage_name: &str, build: F) -> &mut Self | ||||
|     where | ||||
|         F: Fn(&mut Resources) -> Box<dyn Schedulable>, | ||||
|     { | ||||
|         let system = build(self.resources_mut()); | ||||
|         self.add_system_to_stage(stage_name, system) | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_system_to_stage( | ||||
|         &mut self, | ||||
|         stage_name: &str, | ||||
|  | ||||
| @ -1,4 +1,7 @@ | ||||
| use bevy_app::{Events, GetEventReader}; | ||||
| use bevy_window::WindowResized; | ||||
| use glam::Mat4; | ||||
| use legion::prelude::*; | ||||
| 
 | ||||
| #[derive(Default)] | ||||
| pub struct ActiveCamera; | ||||
| @ -116,3 +119,26 @@ impl Camera { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn camera_update_system(resources: &mut Resources) -> Box<dyn Schedulable> { | ||||
|     let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>(); | ||||
|     SystemBuilder::new("camera_update") | ||||
|         .read_resource::<Events<WindowResized>>() | ||||
|         .with_query(<Write<Camera>>::query()) | ||||
|         .build(move |_, world, window_resized_events, query| { | ||||
|             // TODO: refactor this to "window_resized_events.latest()"
 | ||||
|             let primary_window_resized_event = window_resized_events | ||||
|                 .iter(&mut window_resized_event_reader) | ||||
|                 .rev() | ||||
|                 .filter(|event| event.is_primary) | ||||
|                 .next(); | ||||
|             if let Some(primary_window_resized_event) = primary_window_resized_event { | ||||
|                 for mut camera in query.iter_mut(world) { | ||||
|                     camera.update( | ||||
|                         primary_window_resized_event.width, | ||||
|                         primary_window_resized_event.height, | ||||
|                     ); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
| } | ||||
|  | ||||
| @ -83,8 +83,6 @@ impl RenderPlugin { | ||||
|                 resources.get_event_reader::<WindowResized>(), | ||||
|             )) | ||||
|             .add_resource_provider(LightResourceProvider::new(10)) | ||||
|             // TODO: move me to ui crate
 | ||||
|             // .add_resource_provider(UiResourceProvider::new())
 | ||||
|             .add_resource_provider(MeshResourceProvider::new()) | ||||
|             .add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true)) | ||||
|             .add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true)) | ||||
| @ -98,7 +96,9 @@ impl AppPlugin for RenderPlugin { | ||||
|         let mut asset_batchers = AssetBatchers::default(); | ||||
|         asset_batchers.batch_types2::<Mesh, StandardMaterial>(); | ||||
|         app.add_system(build_entity_render_resource_assignments_system()) | ||||
|             .add_stage_after(stage::UPDATE, RENDER_STAGE) | ||||
|             .build_system_on_stage(stage::POST_UPDATE, camera::camera_update_system) | ||||
|             .add_system_to_stage(stage::POST_UPDATE, mesh::mesh_batcher_system()) | ||||
|             .add_stage_after(stage::POST_UPDATE, RENDER_STAGE) | ||||
|             .add_resource(RenderGraph::default()) | ||||
|             .add_resource(AssetStorage::<Mesh>::new()) | ||||
|             .add_resource(AssetStorage::<Texture>::new()) | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| use crate::Vertex; | ||||
| use bevy_asset::Asset; | ||||
| use crate::{render_resource::AssetBatchers, Vertex, Renderable}; | ||||
| use bevy_asset::{Handle, Asset}; | ||||
| use glam::*; | ||||
| use legion::prelude::*; | ||||
| 
 | ||||
| pub enum MeshType { | ||||
|     Cube, | ||||
| @ -118,3 +119,15 @@ pub fn create_cube() -> (Vec<Vertex>, Vec<u16>) { | ||||
| pub fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u16>) { | ||||
|     create_quad(vec2(size, size)) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pub fn mesh_batcher_system() -> Box<dyn Schedulable> { | ||||
|     SystemBuilder::new("mesh_batcher") | ||||
|         .write_resource::<AssetBatchers>() | ||||
|         .with_query(<(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(changed::<Handle<Mesh>>())) | ||||
|         .build(|_, world, asset_batchers, query| { | ||||
|             for (entity, (mesh_handle, _renderable)) in query.iter_entities(world) { | ||||
|                 asset_batchers.set_entity_handle(entity, *mesh_handle); | ||||
|             } | ||||
|         }) | ||||
| } | ||||
| @ -9,8 +9,12 @@ pub trait ResourceProvider { | ||||
|         _resources: &Resources, | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
|     // TODO: make this read-only
 | ||||
|     fn update(&mut self, _render_context: &mut dyn RenderContext, _world: &mut World, _resources: &Resources) { | ||||
|     } | ||||
| 
 | ||||
|     // TODO: remove this
 | ||||
|     fn finish_update( | ||||
|         &mut self, | ||||
|         _render_context: &mut dyn RenderContext, | ||||
| @ -18,4 +22,10 @@ pub trait ResourceProvider { | ||||
|         _resources: &Resources, | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
|     /// Runs after resources have been created on the gpu. In general systems here write gpu-related resources back to entities in this step  
 | ||||
|     fn post_update(&mut self, _render_context: &dyn RenderContext, _world: &mut World, _resources: &Resources) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -27,31 +27,11 @@ impl Camera2dResourceProvider { | ||||
|             window_resized_event_reader, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ResourceProvider for Camera2dResourceProvider { | ||||
|     fn initialize( | ||||
|     fn update_read_only( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let buffer = render_context.create_buffer(BufferInfo { | ||||
|             size: std::mem::size_of::<[[f32; 4]; 4]>(), | ||||
|             buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, | ||||
|             ..Default::default() | ||||
|         }); | ||||
| 
 | ||||
|         let mut render_resource_assignments = | ||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||
|         render_resource_assignments.set(resource_name::uniform::CAMERA2D, buffer); | ||||
|         self.camera_buffer = Some(buffer); | ||||
|     } | ||||
| 
 | ||||
|     fn update( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         world: &mut World, | ||||
|         world: &World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let window_resized_events = resources.get::<Events<WindowResized>>().unwrap(); | ||||
| @ -61,14 +41,10 @@ impl ResourceProvider for Camera2dResourceProvider { | ||||
|             .filter(|event| event.is_primary) | ||||
|             .next(); | ||||
| 
 | ||||
|         if let Some(primary_window_resized_event) = primary_window_resized_event { | ||||
|         if let Some(_) = primary_window_resized_event { | ||||
|             let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); | ||||
|             for (mut camera, _) in <(Write<Camera>, Read<ActiveCamera2d>)>::query().iter_mut(world) | ||||
|             for (camera, _) in <(Read<Camera>, Read<ActiveCamera2d>)>::query().iter(world) | ||||
|             { | ||||
|                 camera.update( | ||||
|                     primary_window_resized_event.width, | ||||
|                     primary_window_resized_event.height, | ||||
|                 ); | ||||
|                 let camera_matrix: [[f32; 4]; 4] = camera.view_matrix.to_cols_array_2d(); | ||||
| 
 | ||||
|                 if let Some(old_tmp_buffer) = self.tmp_buffer { | ||||
| @ -97,3 +73,32 @@ impl ResourceProvider for Camera2dResourceProvider { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ResourceProvider for Camera2dResourceProvider { | ||||
|     fn initialize( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let buffer = render_context.create_buffer(BufferInfo { | ||||
|             size: std::mem::size_of::<[[f32; 4]; 4]>(), | ||||
|             buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, | ||||
|             ..Default::default() | ||||
|         }); | ||||
| 
 | ||||
|         let mut render_resource_assignments = | ||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||
|         render_resource_assignments.set(resource_name::uniform::CAMERA2D, buffer); | ||||
|         self.camera_buffer = Some(buffer); | ||||
|     } | ||||
| 
 | ||||
|     fn update( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         self.update_read_only(render_context, world, resources); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -5,7 +5,8 @@ use crate::{ | ||||
|         resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments, | ||||
|         ResourceProvider, | ||||
|     }, | ||||
|     ActiveCamera, Camera, renderer_2::RenderContext, | ||||
|     renderer_2::RenderContext, | ||||
|     ActiveCamera, Camera, | ||||
| }; | ||||
| 
 | ||||
| use bevy_app::{EventReader, Events}; | ||||
| @ -27,43 +28,19 @@ impl CameraResourceProvider { | ||||
|             window_resized_event_reader, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ResourceProvider for CameraResourceProvider { | ||||
|     fn initialize( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let buffer = render_context.create_buffer(BufferInfo { | ||||
|             size: std::mem::size_of::<[[f32; 4]; 4]>(), | ||||
|             buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, | ||||
|             ..Default::default() | ||||
|         }); | ||||
| 
 | ||||
|         let mut render_resource_assignments = | ||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||
|         render_resource_assignments.set(resource_name::uniform::CAMERA, buffer); | ||||
|         self.camera_buffer = Some(buffer); | ||||
|     } | ||||
| 
 | ||||
|     fn update(&mut self, render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) { | ||||
|     pub fn update_read_only(&mut self, world: &World, resources: &Resources, render_context: &mut dyn RenderContext) { | ||||
|         let window_resized_events = resources.get::<Events<WindowResized>>().unwrap(); | ||||
|         let primary_window_resized_event = window_resized_events | ||||
|             .iter(&mut self.window_resized_event_reader) | ||||
|             .rev() | ||||
|             .filter(|event| event.is_primary) | ||||
|             .next(); | ||||
|         if let Some(primary_window_resized_event) = primary_window_resized_event { | ||||
|         if let Some(_) = primary_window_resized_event { | ||||
|             let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); | ||||
|             for (mut camera, local_to_world, _) in | ||||
|                 <(Write<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter_mut(world) | ||||
|             for (camera, local_to_world, _) in | ||||
|                 <(Read<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter(world) | ||||
|             { | ||||
|                 camera.update( | ||||
|                     primary_window_resized_event.width, | ||||
|                     primary_window_resized_event.height, | ||||
|                 ); | ||||
|                 let camera_matrix: [[f32; 4]; 4] = | ||||
|                     (camera.view_matrix * local_to_world.0).to_cols_array_2d(); | ||||
| 
 | ||||
| @ -93,3 +70,32 @@ impl ResourceProvider for CameraResourceProvider { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ResourceProvider for CameraResourceProvider { | ||||
|     fn initialize( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let buffer = render_context.create_buffer(BufferInfo { | ||||
|             size: std::mem::size_of::<[[f32; 4]; 4]>(), | ||||
|             buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, | ||||
|             ..Default::default() | ||||
|         }); | ||||
| 
 | ||||
|         let mut render_resource_assignments = | ||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||
|         render_resource_assignments.set(resource_name::uniform::CAMERA, buffer); | ||||
|         self.camera_buffer = Some(buffer); | ||||
|     } | ||||
| 
 | ||||
|     fn update( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         self.update_read_only(world, resources, render_context); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -33,30 +33,7 @@ impl LightResourceProvider { | ||||
|             tmp_count_buffer: None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ResourceProvider for LightResourceProvider { | ||||
|     fn initialize( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let light_uniform_size = | ||||
|             std::mem::size_of::<LightCount>() + self.max_lights * std::mem::size_of::<LightRaw>(); | ||||
| 
 | ||||
|         let buffer = render_context.create_buffer(BufferInfo { | ||||
|             size: light_uniform_size, | ||||
|             buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST, | ||||
|             ..Default::default() | ||||
|         }); | ||||
|         let mut render_resource_assignments = | ||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||
|         render_resource_assignments.set(resource_name::uniform::LIGHTS, buffer); | ||||
|         self.light_buffer = Some(buffer); | ||||
|     } | ||||
| 
 | ||||
|     fn update(&mut self, render_context: &mut dyn RenderContext, world: &mut World, _resources: &Resources) { | ||||
|     fn update_read_only(&mut self, render_context: &mut dyn RenderContext, world: &World) { | ||||
|         if self.lights_are_dirty { | ||||
|             let light_query = <(Read<Light>, Read<LocalToWorld>, Read<Translation>)>::query(); | ||||
|             let light_count = light_query.iter(world).count(); | ||||
| @ -123,3 +100,29 @@ impl ResourceProvider for LightResourceProvider { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ResourceProvider for LightResourceProvider { | ||||
|     fn initialize( | ||||
|         &mut self, | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let light_uniform_size = | ||||
|             std::mem::size_of::<LightCount>() + self.max_lights * std::mem::size_of::<LightRaw>(); | ||||
| 
 | ||||
|         let buffer = render_context.create_buffer(BufferInfo { | ||||
|             size: light_uniform_size, | ||||
|             buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST, | ||||
|             ..Default::default() | ||||
|         }); | ||||
|         let mut render_resource_assignments = | ||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||
|         render_resource_assignments.set(resource_name::uniform::LIGHTS, buffer); | ||||
|         self.light_buffer = Some(buffer); | ||||
|     } | ||||
| 
 | ||||
|     fn update(&mut self, render_context: &mut dyn RenderContext, world: &mut World, _resources: &Resources) { | ||||
|         self.update_read_only(render_context, world); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -40,7 +40,7 @@ impl MeshResourceProvider { | ||||
| 
 | ||||
|     fn setup_mesh_resources( | ||||
|         render_context: &mut dyn RenderContext, | ||||
|         mesh_storage: &mut AssetStorage<Mesh>, | ||||
|         mesh_storage: &AssetStorage<Mesh>, | ||||
|         handle: Handle<Mesh>, | ||||
|         render_resource_assignments: &mut RenderResourceAssignments, | ||||
|     ) { | ||||
| @ -91,10 +91,6 @@ impl ResourceProvider for MeshResourceProvider { | ||||
|     } | ||||
| 
 | ||||
|     fn update(&mut self, _render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) { | ||||
|         let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap(); | ||||
|         for (entity, (mesh_handle, _renderable)) in self.mesh_query.iter_entities_mut(world) { | ||||
|             asset_batchers.set_entity_handle(entity, *mesh_handle); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn finish_update( | ||||
| @ -103,7 +99,7 @@ impl ResourceProvider for MeshResourceProvider { | ||||
|         _world: &mut World, | ||||
|         resources: &Resources, | ||||
|     ) { | ||||
|         let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap(); | ||||
|         let mut mesh_storage = resources.get::<AssetStorage<Mesh>>().unwrap(); | ||||
|         let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap(); | ||||
| 
 | ||||
|         // this scope is necessary because the Fetch<AssetBatchers> pointer behaves weirdly
 | ||||
| @ -114,7 +110,7 @@ impl ResourceProvider for MeshResourceProvider { | ||||
|                     log::trace!("setup mesh for {:?}", batch.render_resource_assignments.id); | ||||
|                     Self::setup_mesh_resources( | ||||
|                         render_context, | ||||
|                         &mut mesh_storage, | ||||
|                         &mesh_storage, | ||||
|                         handle, | ||||
|                         &mut batch.render_resource_assignments, | ||||
|                     ); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson