Update entity model buffers when changed

This commit is contained in:
SeanOMik 2023-09-04 15:54:46 -04:00
parent f339d048b2
commit ef4426a991
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
3 changed files with 78 additions and 16 deletions

View File

@ -134,14 +134,19 @@ async fn main() {
for transform in world.query_mut::<(&mut TransformComponent,)>().iter_mut() { for transform in world.query_mut::<(&mut TransformComponent,)>().iter_mut() {
let t = &mut transform.transform; let t = &mut transform.transform;
debug!("Translation: {}", t.translation); //debug!("Translation: {}", t.translation);
/* t.translation += glam::Vec3::new(0.0, 0.001, 0.0); /* t.translation += glam::Vec3::new(0.0, 0.001, 0.0);
t.translation.x *= -1.0; */ t.translation.x *= -1.0; */
t.translation.x += dir_x; t.translation.x += dir_x;
t.translation.y += dir_y; t.translation.y += dir_y;
} }
debug!("end");
/* for mesh in world.query_mut::<(&mut MeshComponent,)>().iter_mut() {
for vertex in mesh.mesh.vertices.iter_mut() {
vertex.position[0] += 0.0001;
}
} */
Ok(()) Ok(())
}; };

View File

@ -21,12 +21,12 @@ impl RenderBuffer {
pub struct BufferStorage { pub struct BufferStorage {
buffer: wgpu::Buffer, buffer: wgpu::Buffer,
slot: u32, slot: u32,
count: Option<u32> count: usize
} }
#[allow(dead_code)] #[allow(dead_code)]
impl BufferStorage { impl BufferStorage {
pub fn new(buffer: wgpu::Buffer, slot: u32, count: Option<u32>) -> Self { pub fn new(buffer: wgpu::Buffer, slot: u32, count: usize) -> Self {
Self { Self {
buffer, buffer,
slot, slot,
@ -46,7 +46,7 @@ impl BufferStorage {
self.slot self.slot
} }
pub fn count(&self) -> Option<u32> { pub fn count(&self) -> usize {
self.count self.count
} }
} }

View File

@ -10,6 +10,7 @@ use async_std::sync::Mutex;
use async_trait::async_trait; use async_trait::async_trait;
use atomicell::{AtomicCell, RefMut}; use atomicell::{AtomicCell, RefMut};
use edict::query::EpochOf;
use edict::{EntityId, Entities}; use edict::{EntityId, Entities};
use glam::Mat4; use glam::Mat4;
use tracing::{debug, warn}; use tracing::{debug, warn};
@ -26,6 +27,7 @@ use crate::resources;
use super::camera::RenderCamera; use super::camera::RenderCamera;
use super::desc_buf_lay::DescVertexBufferLayout; use super::desc_buf_lay::DescVertexBufferLayout;
use super::texture::RenderTexture; use super::texture::RenderTexture;
use super::vertex::Vertex;
use super::{render_pipeline::FullRenderPipeline, vertex::{VERTICES}, render_buffer::BufferStorage, render_job::RenderJob, mesh::Mesh}; use super::{render_pipeline::FullRenderPipeline, vertex::{VERTICES}, render_buffer::BufferStorage, render_job::RenderJob, mesh::Mesh};
pub trait Renderer { pub trait Renderer {
@ -374,16 +376,58 @@ impl BasicRenderer {
} }
} }
fn create_model_buffers(&mut self, model_2d: &MeshComponent, transform_indices: TransformBufferIndices) -> RenderBufferStorage { fn find_next_multiple(n: u32, mul: u32) -> u32 {
let mesh = &model_2d.mesh; if n % mul == 0 {
n
} else {
n + (mul - n % mul)
}
}
// TODO: minimize how often model buffers are updated by checking if they changed
fn update_model_buffers(&mut self, entity: EntityId, model: &MeshComponent) {
if let Some(buffers) = self.buffer_storage.get_mut(&entity) {
// check if the buffer sizes dont match. If they dont, completely remake the buffers
let vertices = &model.mesh.vertices;
if buffers.buffer_vertex.count() != vertices.len() {
drop(buffers);
let (vert, idx) = self.create_vertex_index_buffers(&model.mesh);
// have to re-get buffers because of borrow checker
let buffers = self.buffer_storage.get_mut(&entity).unwrap();
buffers.buffer_indices = idx;
buffers.buffer_vertex = vert;
return;
}
// update vertices
let vertex_buffer = buffers.buffer_vertex.buffer();
let vertices = vertices.as_slice();
// align the vertices to 4 bytes (u32 is 4 bytes, which is wgpu::COPY_BUFFER_ALIGNMENT)
let (_, vertices, _) = bytemuck::pod_align_to::<Vertex, u32>(vertices);
self.queue.write_buffer(&vertex_buffer, 0, bytemuck::cast_slice(&vertices));
// update the indices if they're given
if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
let index_buffer = index_buffer.buffer();
let indices = model.mesh.indices.as_ref().unwrap().as_slice();
let (_, indices, _) = bytemuck::pod_align_to::<u16, u32>(indices);
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&indices));
}
}
}
fn create_vertex_index_buffers(&mut self, mesh: &Mesh) -> (BufferStorage, Option<BufferStorage>) {
let vertex_buffer = self.device.create_buffer_init( let vertex_buffer = self.device.create_buffer_init(
&wgpu::util::BufferInitDescriptor { &wgpu::util::BufferInitDescriptor {
label: Some("Vertex Buffer"), label: Some("Vertex Buffer"),
contents: bytemuck::cast_slice(mesh.vertices.as_slice()), contents: bytemuck::cast_slice(mesh.vertices.as_slice()),
usage: wgpu::BufferUsages::VERTEX, usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages:: COPY_DST,
} }
); );
let vertex_buffer = BufferStorage::new(vertex_buffer, 0, mesh.vertices.len());
let buffer_indices = match mesh.indices.as_ref() { let buffer_indices = match mesh.indices.as_ref() {
Some(indices) => { Some(indices) => {
@ -391,11 +435,11 @@ impl BasicRenderer {
&wgpu::util::BufferInitDescriptor { &wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"), label: Some("Index Buffer"),
contents: bytemuck::cast_slice(&indices), contents: bytemuck::cast_slice(&indices),
usage: wgpu::BufferUsages::INDEX, usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages:: COPY_DST,
} }
); );
let buffer_indices = BufferStorage::new(index_buffer, 0, Some(indices.len() as u32)); let buffer_indices = BufferStorage::new(index_buffer, 0, indices.len());
Some(buffer_indices) Some(buffer_indices)
}, },
@ -404,7 +448,15 @@ impl BasicRenderer {
} }
}; };
let texture_img = &model_2d.material.texture; ( vertex_buffer, buffer_indices )
}
fn create_model_buffers(&mut self, model: &MeshComponent, transform_indices: TransformBufferIndices) -> RenderBufferStorage {
let mesh = &model.mesh;
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
let texture_img = &model.material.texture;
let diffuse_texture = RenderTexture::from_image(&self.device, &self.queue, &texture_img.img, 0, Some("happy-tree.png")).unwrap(); let diffuse_texture = RenderTexture::from_image(&self.device, &self.queue, &texture_img.img, 0, Some("happy-tree.png")).unwrap();
let texture_bind_group_layout = let texture_bind_group_layout =
@ -450,7 +502,7 @@ impl BasicRenderer {
); );
RenderBufferStorage { RenderBufferStorage {
buffer_vertex: BufferStorage::new(vertex_buffer, 0, None), buffer_vertex: vertex_buffer,
buffer_indices, buffer_indices,
render_texture: None, render_texture: None,
texture_layout: None, texture_layout: None,
@ -498,13 +550,15 @@ impl BasicRenderer {
impl Renderer for BasicRenderer { impl Renderer for BasicRenderer {
fn prepare(&mut self, main_world: &mut edict::World) { fn prepare(&mut self, main_world: &mut edict::World) {
let last_epoch = main_world.epoch();
// render_limits.max_uniform_buffer_binding_size // render_limits.max_uniform_buffer_binding_size
for (entity, model, transform) in main_world.query::<(Entities, &MeshComponent, &TransformComponent)>().iter() { for (entity, model, model_epoch, transform) in main_world.query::<(Entities, &MeshComponent, EpochOf<MeshComponent>, &TransformComponent)>().iter() {
// Create the render job and push it to the queue // Create the render job and push it to the queue
let job = RenderJob::new(model.mesh.clone(), model.material.clone(), entity, transform.transform, None); let job = RenderJob::new(model.mesh.clone(), model.material.clone(), entity, transform.transform, None);
self.render_jobs.push_back(job); self.render_jobs.push_back(job);
if self.buffer_storage.get(&entity).is_none() { // TODO: Delete dead entites from buffer_storage // TODO: Delete dead entites from buffer_storage
if self.buffer_storage.get(&entity).is_none() {
// check if the transform buffers need to be expanded // check if the transform buffers need to be expanded
if self.transform_buffers.should_expand() { if self.transform_buffers.should_expand() {
self.expand_transform_buffers(); self.expand_transform_buffers();
@ -522,7 +576,10 @@ impl Renderer for BasicRenderer {
self.transform_buffers.update_entity(&self.queue, &self.render_limits, self.transform_buffers.update_entity(&self.queue, &self.render_limits,
entity, transform.transform.calculate_mat4()); entity, transform.transform.calculate_mat4());
// TODO: Update model buffers in storage // if the model was updated, update its buffers
if model_epoch == last_epoch {
self.update_model_buffers(entity, model);
}
} }
} }
@ -587,7 +644,7 @@ impl Renderer for BasicRenderer {
// if this mesh uses indices, use them to draw the mesh // if this mesh uses indices, use them to draw the mesh
if let Some(indices) = buffers.buffer_indices.as_ref() { if let Some(indices) = buffers.buffer_indices.as_ref() {
let indices_len = indices.count().unwrap(); // index buffers will have count, if not thats a bug let indices_len = indices.count() as u32;
render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..)); render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..));
render_pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint16); render_pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint16);