camera: always update camera uniform buffers

This commit is contained in:
Carter Anderson 2020-05-30 12:43:27 -07:00
parent 6e76296ce0
commit e59385472c

View file

@ -7,9 +7,7 @@ use crate::{
Camera, Camera,
}; };
use bevy_app::Events;
use bevy_transform::prelude::*; use bevy_transform::prelude::*;
use bevy_window::WindowResized;
use legion::prelude::*; use legion::prelude::*;
use std::borrow::Cow; use std::borrow::Cow;
use zerocopy::AsBytes; use zerocopy::AsBytes;
@ -47,15 +45,13 @@ impl Node for CameraNode {
impl SystemNode for CameraNode { impl SystemNode for CameraNode {
fn get_system(&self) -> Box<dyn Schedulable> { fn get_system(&self) -> Box<dyn Schedulable> {
let mut camera_buffer = None; let mut camera_buffer = None;
let mut window_resized_event_reader = None;
let mut command_queue = self.command_queue.clone(); let mut command_queue = self.command_queue.clone();
let uniform_name = self.uniform_name.clone(); let uniform_name = self.uniform_name.clone();
(move |world: &mut SubWorld, (move |world: &mut SubWorld,
render_resources: Res<RenderResources>, render_resources: Res<RenderResources>,
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel // PERF: this write on RenderResourceAssignments will prevent this system from running in parallel
// with other systems that do the same // with other systems that do the same
mut render_resource_assignments: ResMut<RenderResourceAssignments>, mut render_resource_assignments: ResMut<RenderResourceAssignments>,
window_resized_events: Res<Events<WindowResized>>,
query: &mut Query<(Read<Camera>, Read<LocalToWorld>)>| { query: &mut Query<(Read<Camera>, Read<LocalToWorld>)>| {
let render_resources = &render_resources.context; let render_resources = &render_resources.context;
if camera_buffer.is_none() { if camera_buffer.is_none() {
@ -75,42 +71,33 @@ impl SystemNode for CameraNode {
); );
camera_buffer = Some(buffer); camera_buffer = Some(buffer);
} }
if window_resized_event_reader.is_none() { let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
window_resized_event_reader = Some(window_resized_events.get_reader()); if let Some((camera, local_to_world)) = query
} .iter(world)
let primary_window_resized_event = window_resized_event_reader .find(|(camera, _)| camera.name.as_ref().map(|n| n.as_str()) == Some(&uniform_name))
.as_mut() {
.unwrap() let camera_matrix: [[f32; 4]; 4] =
.find_latest(&window_resized_events, |event| event.is_primary); (camera.view_matrix * local_to_world.0).to_cols_array_2d();
if let Some(_) = primary_window_resized_event {
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
if let Some((camera, local_to_world)) = query
.iter(world)
.find(|(camera, _)| camera.name.as_ref().map(|n| n.as_str()) == Some(&uniform_name))
{
let camera_matrix: [[f32; 4]; 4] =
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
let tmp_buffer = render_resources.create_buffer_mapped( let tmp_buffer = render_resources.create_buffer_mapped(
BufferInfo { BufferInfo {
size: matrix_size, size: matrix_size,
buffer_usage: BufferUsage::COPY_SRC, buffer_usage: BufferUsage::COPY_SRC,
..Default::default() ..Default::default()
}, },
&mut |data, _renderer| { &mut |data, _renderer| {
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes()); data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
}, },
); );
command_queue.copy_buffer_to_buffer( command_queue.copy_buffer_to_buffer(
tmp_buffer, tmp_buffer,
0, 0,
camera_buffer.unwrap(), camera_buffer.unwrap(),
0, 0,
matrix_size as u64, matrix_size as u64,
); );
command_queue.free_buffer(tmp_buffer); command_queue.free_buffer(tmp_buffer);
}
} }
}) })
.system() .system()