feat(renderer): add dynamic mesh updates via buffer reallocation
This commit is contained in:
parent
ab01c8a033
commit
203cc2a671
|
|
@ -8,7 +8,7 @@
|
||||||
mod device;
|
mod device;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod instance;
|
mod instance;
|
||||||
mod mesh;
|
pub mod mesh;
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod surface;
|
mod surface;
|
||||||
|
|
@ -119,6 +119,8 @@ impl Renderer {
|
||||||
let (vertex_buffer, vertex_allocation, index_buffer, index_allocation) =
|
let (vertex_buffer, vertex_allocation, index_buffer, index_allocation) =
|
||||||
create_geometry(&device, &mut allocator)?;
|
create_geometry(&device, &mut allocator)?;
|
||||||
|
|
||||||
|
let index_count = 36;
|
||||||
|
|
||||||
let (depth_image, depth_allocation, depth_image_view) =
|
let (depth_image, depth_allocation, depth_image_view) =
|
||||||
create_depth_resources(&device, &mut allocator, swapchain_extent)?;
|
create_depth_resources(&device, &mut allocator, swapchain_extent)?;
|
||||||
|
|
||||||
|
|
@ -144,6 +146,7 @@ impl Renderer {
|
||||||
allocator,
|
allocator,
|
||||||
index_buffer,
|
index_buffer,
|
||||||
index_allocation,
|
index_allocation,
|
||||||
|
index_count,
|
||||||
depth_image,
|
depth_image,
|
||||||
depth_allocation,
|
depth_allocation,
|
||||||
depth_image_view,
|
depth_image_view,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ use bytemuck::{Pod, Zeroable};
|
||||||
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
|
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
|
||||||
pub struct Vertex {
|
pub struct Vertex {
|
||||||
/// 3D position of the vertex (X, Y, Z).
|
/// 3D position of the vertex (X, Y, Z).
|
||||||
|
/// The position coordinates of the vertex [x, y, z].
|
||||||
pub position: [f32; 3],
|
pub position: [f32; 3],
|
||||||
|
/// The RGB color of the vertex [r, g, b].
|
||||||
pub color: [f32; 3],
|
pub color: [f32; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19,6 +21,9 @@ impl Vertex {
|
||||||
///
|
///
|
||||||
/// This defines the 'stride' (distance between vertices) and specifies that
|
/// This defines the 'stride' (distance between vertices) and specifies that
|
||||||
/// data is read per-vertex rather than per-instance.
|
/// 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)]
|
#[allow(clippy::expect_used)]
|
||||||
pub fn get_binding_description() -> ash::vk::VertexInputBindingDescription {
|
pub fn get_binding_description() -> ash::vk::VertexInputBindingDescription {
|
||||||
ash::vk::VertexInputBindingDescription::default()
|
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 crate::sync::SyncPrimitives;
|
||||||
use ash::{Device, Instance, khr, vk};
|
use ash::{Device, Instance, khr, vk};
|
||||||
use gpu_allocator::vulkan::{Allocation, Allocator};
|
use gpu_allocator::vulkan::{Allocation, Allocator};
|
||||||
|
|
@ -58,6 +59,7 @@ pub struct Renderer {
|
||||||
pub(crate) index_buffer: vk::Buffer,
|
pub(crate) index_buffer: vk::Buffer,
|
||||||
/// Memory allocation for the index buffer.
|
/// Memory allocation for the index buffer.
|
||||||
pub(crate) index_allocation: Allocation,
|
pub(crate) index_allocation: Allocation,
|
||||||
|
pub(crate) index_count: u32,
|
||||||
/// The depth image used for depth testing.
|
/// The depth image used for depth testing.
|
||||||
pub(crate) depth_image: vk::Image,
|
pub(crate) depth_image: vk::Image,
|
||||||
/// Image view for the depth buffer.
|
/// Image view for the depth buffer.
|
||||||
|
|
@ -276,12 +278,12 @@ impl Renderer {
|
||||||
f64::from(self.swapchain_extent.width) / f64::from(self.swapchain_extent.height);
|
f64::from(self.swapchain_extent.width) / f64::from(self.swapchain_extent.height);
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
let mut projection =
|
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;
|
projection.col_mut(1).y *= -1.0;
|
||||||
|
|
||||||
let view = glam::Mat4::look_at_rh(
|
let view = glam::Mat4::look_at_rh(
|
||||||
glam::vec3(2.0, 2.0, 2.0),
|
glam::vec3(16.0, 40.0, 60.0),
|
||||||
glam::vec3(0.0, 0.0, 0.0),
|
glam::vec3(16.0, 16.0, 16.0),
|
||||||
glam::vec3(0.0, 1.0, 0.0),
|
glam::vec3(0.0, 1.0, 0.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -297,7 +299,7 @@ impl Renderer {
|
||||||
mvp_bytes,
|
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(())
|
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 {
|
impl Drop for Renderer {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue