mirror of
https://github.com/bevyengine/bevy
synced 2024-11-26 06:30:19 +00:00
start making ResourceProvider::update world read-only
This commit is contained in:
parent
78d1958090
commit
08abef1c75
9 changed files with 162 additions and 94 deletions
|
@ -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;
|
||||
|
@ -115,4 +118,27 @@ 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 a new issue