use crate::core::{Buffer, Device};
use ash::vk;
use std::sync::Arc;
pub struct Mesh {
device: Arc<Device>,
vertex_buffer: Buffer,
index_buffer: Option<Buffer>,
vertex_count: u32,
index_count: Option<u32>,
index_type: vk::IndexType,
binding: u32,
}
impl Mesh {
pub fn new(device: Arc<Device>, vertex_buffer: Buffer, vertex_count: u32, binding: u32) -> Self {
Self {
device,
vertex_buffer,
index_buffer: None,
vertex_count,
index_count: None,
index_type: vk::IndexType::UINT16, binding,
}
}
pub fn new_indexed(
device: Arc<Device>,
vertex_buffer: Buffer,
vertex_count: u32,
index_buffer: Buffer,
index_count: u32,
index_type: vk::IndexType,
binding: u32,
) -> Self {
Self {
device,
vertex_buffer,
index_buffer: Some(index_buffer),
vertex_count,
index_count: Some(index_count),
index_type,
binding,
}
}
#[inline]
pub fn vertex_buffer(&self) -> &Buffer {
&self.vertex_buffer
}
#[inline]
pub fn index_buffer(&self) -> Option<&Buffer> {
self.index_buffer.as_ref()
}
#[inline]
pub fn vertex_count(&self) -> u32 {
self.vertex_count
}
#[inline]
pub fn index_count(&self) -> Option<u32> {
self.index_count
}
#[inline]
pub fn is_indexed(&self) -> bool {
self.index_buffer.is_some()
}
#[inline]
pub fn index_type(&self) -> vk::IndexType {
self.index_type
}
#[inline]
pub fn binding(&self) -> u32 {
self.binding
}
#[inline]
pub(crate) fn bind(&self, device: &ash::Device, command_buffer: vk::CommandBuffer) {
unsafe {
device.cmd_bind_vertex_buffers(
command_buffer,
self.binding,
&[self.vertex_buffer.handle()],
&[0],
);
if let Some(ref index_buffer) = self.index_buffer {
device.cmd_bind_index_buffer(
command_buffer,
index_buffer.handle(),
0,
self.index_type,
);
}
}
}
#[inline]
pub(crate) fn draw(&self, device: &ash::Device, command_buffer: vk::CommandBuffer) {
unsafe {
if let Some(index_count) = self.index_count {
device.cmd_draw_indexed(
command_buffer,
index_count,
1, 0, 0, 0, );
} else {
device.cmd_draw(
command_buffer,
self.vertex_count,
1, 0, 0, );
}
}
}
}
impl Drop for Mesh {
fn drop(&mut self) {
if let Some(ref mut index_buffer) = self.index_buffer {
index_buffer.destroy(&self.device);
}
self.vertex_buffer.destroy(&self.device);
}
}