Implement a Render Graph #16

Merged
SeanOMik merged 20 commits from feature/render-graph into main 2024-06-15 22:54:47 +00:00
1 changed files with 21 additions and 29 deletions
Showing only changes of commit 41d77c5687 - Show all commits

View File

@ -28,13 +28,9 @@ struct MeshBufferStorage {
buffer_vertex: BufferStorage, buffer_vertex: BufferStorage,
buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>, buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>,
//#[allow(dead_code)] // maybe this should just be a Uuid and the material can be retrieved though
//render_texture: Option<RenderTexture>, // MeshPass's `material_buffers` field?
material: Option<Rc<Material>>, material: Option<Rc<Material>>,
// The index of the transform for this entity.
// The tuple is structured like this: (transform index, index of transform inside the buffer)
//transform_index: TransformBufferIndices,
} }
#[derive(Clone, Debug, Component)] #[derive(Clone, Debug, Component)]
@ -180,16 +176,8 @@ impl MeshPass {
} }
/// Processes the mesh for the renderer, storing and creating buffers as needed. Returns true if a new mesh was processed. /// Processes the mesh for the renderer, storing and creating buffers as needed. Returns true if a new mesh was processed.
#[instrument(skip(self, device, queue, transform, mesh, entity))] #[instrument(skip(self, device, queue, mesh, entity))]
fn process_mesh(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, entity: Entity, transform: Transform, mesh: &Mesh, mesh_uuid: Uuid) -> bool { fn process_mesh(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, entity: Entity, mesh: &Mesh, mesh_uuid: Uuid) -> bool {
let _ = transform;
/* if self.transform_buffers.should_expand() {
self.transform_buffers.expand_buffers(&self.device);
}
self.transform_buffers.update_or_insert(&self.queue, &self.render_limits,
entity, || ( transform.calculate_mat4(), glam::Mat3::from_quat(transform.rotation) )); */
#[allow(clippy::map_entry)] #[allow(clippy::map_entry)]
if !self.mesh_buffers.contains_key(&mesh_uuid) { if !self.mesh_buffers.contains_key(&mesh_uuid) {
// create the mesh's buffers // create the mesh's buffers
@ -343,6 +331,9 @@ impl RenderGraphPass for MeshPass {
{ {
alive_entities.insert(entity); alive_entities.insert(entity);
// Interpolate the transform for this entity using a component.
// If the entity does not have the component then it will be queued to be added
// to it after all the entities are prepared for rendering.
let interp_transform = match interp_tran { let interp_transform = match interp_tran {
Some(mut interp_transform) => { Some(mut interp_transform) => {
// found in https://youtu.be/YJB1QnEmlTs?t=472 // found in https://youtu.be/YJB1QnEmlTs?t=472
@ -362,22 +353,28 @@ impl RenderGraphPass for MeshPass {
} }
}; };
{
// expand the transform buffers if they need to be.
// this is done in its own scope to avoid multiple mutable references to self at
// once; aka, make the borrow checker happy
let transforms = self.transforms.as_mut().unwrap();
if transforms.needs_expand() {
debug!("Expanding transform buffers");
transforms.expand_buffers(device);
}
}
if let Some((mesh_han, mesh_epoch)) = mesh_pair { if let Some((mesh_han, mesh_epoch)) = mesh_pair {
if let Some(mesh) = mesh_han.data_ref() { if let Some(mesh) = mesh_han.data_ref() {
// if process mesh did not just create a new mesh, and the epoch // if process mesh did not just create a new mesh, and the epoch
// shows that the scene has changed, verify that the mesh buffers // shows that the scene has changed, verify that the mesh buffers
// dont need to be resent to the gpu. // dont need to be resent to the gpu.
if !self.process_mesh(device, queue, entity, interp_transform, &*mesh, mesh_han.uuid()) if !self.process_mesh(device, queue, entity, &*mesh, mesh_han.uuid())
&& mesh_epoch == last_epoch { && mesh_epoch == last_epoch {
self.check_mesh_buffers(device, queue, &mesh_han); self.check_mesh_buffers(device, queue, &mesh_han);
} }
let transforms = self.transforms.as_mut().unwrap(); let transforms = self.transforms.as_mut().unwrap();
if transforms.needs_expand() {
debug!("Expanding transform buffers");
transforms.expand_buffers(device);
}
let group = TransformGroup::EntityRes(entity, mesh_han.uuid()); let group = TransformGroup::EntityRes(entity, mesh_han.uuid());
let transform_id = transforms.update_or_push(device, queue, &render_limits, let transform_id = transforms.update_or_push(device, queue, &render_limits,
group, interp_transform.calculate_mat4(), glam::Mat3::from_quat(interp_transform.rotation)); group, interp_transform.calculate_mat4(), glam::Mat3::from_quat(interp_transform.rotation));
@ -404,17 +401,12 @@ impl RenderGraphPass for MeshPass {
// if process mesh did not just create a new mesh, and the epoch // if process mesh did not just create a new mesh, and the epoch
// shows that the scene has changed, verify that the mesh buffers // shows that the scene has changed, verify that the mesh buffers
// dont need to be resent to the gpu. // dont need to be resent to the gpu.
if !self.process_mesh(device, queue, entity, mesh_interpo, &*mesh, mesh_han.uuid()) if !self.process_mesh(device, queue, entity, &*mesh, mesh_han.uuid())
&& scene_epoch == last_epoch { && scene_epoch == last_epoch {
self.check_mesh_buffers(device, queue, &mesh_han); self.check_mesh_buffers(device, queue, &mesh_han);
} }
let transforms = self.transforms.as_mut().unwrap(); let transforms = self.transforms.as_mut().unwrap();
if transforms.needs_expand() {
debug!("Expanding transform buffers");
transforms.expand_buffers(device);
}
let scene_mesh_group = TransformGroup::Res(scene_han.uuid(), mesh_han.uuid()); let scene_mesh_group = TransformGroup::Res(scene_han.uuid(), mesh_han.uuid());
let group = TransformGroup::OwnedGroup(entity, scene_mesh_group.into()); let group = TransformGroup::OwnedGroup(entity, scene_mesh_group.into());
let transform_id = transforms.update_or_push(device, queue, &render_limits, let transform_id = transforms.update_or_push(device, queue, &render_limits,