Update entity model buffers when changed
This commit is contained in:
parent
f339d048b2
commit
ef4426a991
|
@ -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(())
|
||||
};
|
||||
|
|
|
@ -21,12 +21,12 @@ impl RenderBuffer {
|
|||
pub struct BufferStorage {
|
||||
buffer: wgpu::Buffer,
|
||||
slot: u32,
|
||||
count: Option<u32>
|
||||
count: usize
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
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 {
|
||||
buffer,
|
||||
slot,
|
||||
|
@ -46,7 +46,7 @@ impl BufferStorage {
|
|||
self.slot
|
||||
}
|
||||
|
||||
pub fn count(&self) -> Option<u32> {
|
||||
pub fn count(&self) -> usize {
|
||||
self.count
|
||||
}
|
||||
}
|
|
@ -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::<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(
|
||||
&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<MeshComponent>, &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);
|
||||
|
|
Loading…
Reference in New Issue