diff --git a/src/main.rs b/src/main.rs index 04ec870..f070be5 100755 --- a/src/main.rs +++ b/src/main.rs @@ -134,14 +134,19 @@ async fn main() { for transform in world.query_mut::<(&mut TransformComponent,)>().iter_mut() { 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.x *= -1.0; */ t.translation.x += dir_x; 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(()) }; diff --git a/src/render/render_buffer.rs b/src/render/render_buffer.rs index e86a036..016568a 100755 --- a/src/render/render_buffer.rs +++ b/src/render/render_buffer.rs @@ -21,12 +21,12 @@ impl RenderBuffer { pub struct BufferStorage { buffer: wgpu::Buffer, slot: u32, - count: Option + count: usize } #[allow(dead_code)] impl BufferStorage { - pub fn new(buffer: wgpu::Buffer, slot: u32, count: Option) -> Self { + pub fn new(buffer: wgpu::Buffer, slot: u32, count: usize) -> Self { Self { buffer, slot, @@ -46,7 +46,7 @@ impl BufferStorage { self.slot } - pub fn count(&self) -> Option { + pub fn count(&self) -> usize { self.count } } \ No newline at end of file diff --git a/src/render/renderer.rs b/src/render/renderer.rs index 5994977..f5d1157 100755 --- a/src/render/renderer.rs +++ b/src/render/renderer.rs @@ -10,6 +10,7 @@ use async_std::sync::Mutex; use async_trait::async_trait; use atomicell::{AtomicCell, RefMut}; +use edict::query::EpochOf; use edict::{EntityId, Entities}; use glam::Mat4; use tracing::{debug, warn}; @@ -26,6 +27,7 @@ use crate::resources; use super::camera::RenderCamera; use super::desc_buf_lay::DescVertexBufferLayout; use super::texture::RenderTexture; +use super::vertex::Vertex; use super::{render_pipeline::FullRenderPipeline, vertex::{VERTICES}, render_buffer::BufferStorage, render_job::RenderJob, mesh::Mesh}; pub trait Renderer { @@ -374,16 +376,58 @@ impl BasicRenderer { } } - fn create_model_buffers(&mut self, model_2d: &MeshComponent, transform_indices: TransformBufferIndices) -> RenderBufferStorage { - let mesh = &model_2d.mesh; + fn find_next_multiple(n: u32, mul: u32) -> u32 { + 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::(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::(indices); + + self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&indices)); + } + } + } + + fn create_vertex_index_buffers(&mut self, mesh: &Mesh) -> (BufferStorage, Option) { let vertex_buffer = self.device.create_buffer_init( &wgpu::util::BufferInitDescriptor { label: Some("Vertex Buffer"), 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() { Some(indices) => { @@ -391,11 +435,11 @@ impl BasicRenderer { &wgpu::util::BufferInitDescriptor { label: Some("Index Buffer"), 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) }, @@ -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 texture_bind_group_layout = @@ -450,7 +502,7 @@ impl BasicRenderer { ); RenderBufferStorage { - buffer_vertex: BufferStorage::new(vertex_buffer, 0, None), + buffer_vertex: vertex_buffer, buffer_indices, render_texture: None, texture_layout: None, @@ -498,13 +550,15 @@ impl BasicRenderer { impl Renderer for BasicRenderer { fn prepare(&mut self, main_world: &mut edict::World) { + let last_epoch = main_world.epoch(); // 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, &TransformComponent)>().iter() { // Create the render job and push it to the queue let job = RenderJob::new(model.mesh.clone(), model.material.clone(), entity, transform.transform, None); 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 if self.transform_buffers.should_expand() { self.expand_transform_buffers(); @@ -522,7 +576,10 @@ impl Renderer for BasicRenderer { self.transform_buffers.update_entity(&self.queue, &self.render_limits, 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 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_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint16);