feat(renderer): add dynamic mesh updates via buffer reallocation
This commit is contained in:
parent
ab01c8a033
commit
203cc2a671
|
|
@ -8,7 +8,7 @@
|
|||
mod device;
|
||||
pub mod error;
|
||||
mod instance;
|
||||
mod mesh;
|
||||
pub mod mesh;
|
||||
mod pipeline;
|
||||
mod renderer;
|
||||
mod surface;
|
||||
|
|
@ -119,6 +119,8 @@ impl Renderer {
|
|||
let (vertex_buffer, vertex_allocation, index_buffer, index_allocation) =
|
||||
create_geometry(&device, &mut allocator)?;
|
||||
|
||||
let index_count = 36;
|
||||
|
||||
let (depth_image, depth_allocation, depth_image_view) =
|
||||
create_depth_resources(&device, &mut allocator, swapchain_extent)?;
|
||||
|
||||
|
|
@ -144,6 +146,7 @@ impl Renderer {
|
|||
allocator,
|
||||
index_buffer,
|
||||
index_allocation,
|
||||
index_count,
|
||||
depth_image,
|
||||
depth_allocation,
|
||||
depth_image_view,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ use bytemuck::{Pod, Zeroable};
|
|||
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
|
||||
pub struct Vertex {
|
||||
/// 3D position of the vertex (X, Y, Z).
|
||||
/// The position coordinates of the vertex [x, y, z].
|
||||
pub position: [f32; 3],
|
||||
/// The RGB color of the vertex [r, g, b].
|
||||
pub color: [f32; 3],
|
||||
}
|
||||
|
||||
|
|
@ -19,6 +21,9 @@ impl Vertex {
|
|||
///
|
||||
/// This defines the 'stride' (distance between vertices) and specifies that
|
||||
/// data is read per-vertex rather than per-instance.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if the size of the vertex structure exceeds the maximum value of a 32-bit unsigned integer.
|
||||
#[allow(clippy::expect_used)]
|
||||
pub fn get_binding_description() -> ash::vk::VertexInputBindingDescription {
|
||||
ash::vk::VertexInputBindingDescription::default()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::error::RendererError;
|
||||
use crate::create_gpu_buffer;
|
||||
use crate::{error::RendererError, mesh::Vertex};
|
||||
use crate::sync::SyncPrimitives;
|
||||
use ash::{Device, Instance, khr, vk};
|
||||
use gpu_allocator::vulkan::{Allocation, Allocator};
|
||||
|
|
@ -58,6 +59,7 @@ pub struct Renderer {
|
|||
pub(crate) index_buffer: vk::Buffer,
|
||||
/// Memory allocation for the index buffer.
|
||||
pub(crate) index_allocation: Allocation,
|
||||
pub(crate) index_count: u32,
|
||||
/// The depth image used for depth testing.
|
||||
pub(crate) depth_image: vk::Image,
|
||||
/// Image view for the depth buffer.
|
||||
|
|
@ -276,12 +278,12 @@ impl Renderer {
|
|||
f64::from(self.swapchain_extent.width) / f64::from(self.swapchain_extent.height);
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let mut projection =
|
||||
glam::Mat4::perspective_rh(45.0_f32.to_radians(), aspect as f32, 0.1, 100.0);
|
||||
glam::Mat4::perspective_rh(45.0_f32.to_radians(), aspect as f32, 0.1, 500.0);
|
||||
projection.col_mut(1).y *= -1.0;
|
||||
|
||||
let view = glam::Mat4::look_at_rh(
|
||||
glam::vec3(2.0, 2.0, 2.0),
|
||||
glam::vec3(0.0, 0.0, 0.0),
|
||||
glam::vec3(16.0, 40.0, 60.0),
|
||||
glam::vec3(16.0, 16.0, 16.0),
|
||||
glam::vec3(0.0, 1.0, 0.0),
|
||||
);
|
||||
|
||||
|
|
@ -297,7 +299,7 @@ impl Renderer {
|
|||
mvp_bytes,
|
||||
);
|
||||
|
||||
self.device.cmd_draw_indexed(cmd, 36, 1, 0, 0, 0);
|
||||
self.device.cmd_draw_indexed(cmd, self.index_count, 1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -335,6 +337,47 @@ impl Renderer {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Replaces the currently rendering mesh with a new set of vertices and indices.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns a `RendererError` if new Vulkan buffers cannot be allocated or created.
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
pub fn update_mesh(&mut self, vertices: &[Vertex], indices: &[u32]) -> Result<(), RendererError> {
|
||||
unsafe {
|
||||
let _ = self.device.device_wait_idle();
|
||||
|
||||
let _ = self.allocator.free(std::ptr::read(&raw const self.vertex_allocation));
|
||||
self.device.destroy_buffer(self.vertex_buffer, None);
|
||||
|
||||
let _ = self.allocator.free(std::ptr::read(&raw const self.index_allocation));
|
||||
self.device.destroy_buffer(self.index_buffer, None);
|
||||
}
|
||||
|
||||
let (v_buf, v_alloc) = create_gpu_buffer(
|
||||
&self.device,
|
||||
&mut self.allocator,
|
||||
bytemuck::cast_slice(vertices),
|
||||
vk::BufferUsageFlags::VERTEX_BUFFER,
|
||||
"Chunk Vertex Buffer",
|
||||
)?;
|
||||
|
||||
let (i_buf, i_alloc) = crate::create_gpu_buffer(
|
||||
&self.device,
|
||||
&mut self.allocator,
|
||||
bytemuck::cast_slice(indices),
|
||||
vk::BufferUsageFlags::INDEX_BUFFER,
|
||||
"Chunk Index Buffer",
|
||||
)?;
|
||||
|
||||
self.vertex_buffer = v_buf;
|
||||
self.vertex_allocation = v_alloc;
|
||||
self.index_buffer = i_buf;
|
||||
self.index_allocation = i_alloc;
|
||||
self.index_count = indices.len() as u32;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Renderer {
|
||||
|
|
|
|||
Loading…
Reference in a new issue