117 lines
2.9 KiB
Rust
117 lines
2.9 KiB
Rust
use std::sync::Arc;
|
|
|
|
use glam::{Mat4, Vec3};
|
|
use vulkano::{
|
|
buffer::{BufferUsage, Subbuffer},
|
|
descriptor_set::DescriptorSet,
|
|
};
|
|
|
|
use crate::{
|
|
gfx,
|
|
renderer_vk::{rect::RectPipeline, text::text_atlas::TextPipeline},
|
|
};
|
|
|
|
pub struct ModelBuffer {
|
|
idx: u32,
|
|
models: Vec<glam::Mat4>,
|
|
|
|
buffer: Subbuffer<[f32]>, //4x4 floats = 1 mat4
|
|
buffer_capacity_f32: u32,
|
|
|
|
rect_descriptor: Option<Arc<DescriptorSet>>,
|
|
}
|
|
|
|
impl ModelBuffer {
|
|
pub fn new(gfx: &Arc<gfx::WGfx>) -> anyhow::Result<Self> {
|
|
const INITIAL_CAPACITY_MAT4: u32 = 16;
|
|
const INITIAL_CAPACITY_F32: u32 = INITIAL_CAPACITY_MAT4 * (4 * 4);
|
|
|
|
let buffer = gfx.empty_buffer::<f32>(
|
|
BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST,
|
|
INITIAL_CAPACITY_F32.into(),
|
|
)?;
|
|
|
|
let mut models = Vec::<glam::Mat4>::new();
|
|
models.resize(INITIAL_CAPACITY_MAT4 as _, Default::default());
|
|
|
|
Ok(Self {
|
|
models,
|
|
idx: 0,
|
|
buffer,
|
|
buffer_capacity_f32: INITIAL_CAPACITY_F32,
|
|
rect_descriptor: None,
|
|
})
|
|
}
|
|
|
|
pub const fn begin(&mut self) {
|
|
self.idx = 0;
|
|
}
|
|
|
|
pub fn upload(&mut self, gfx: &Arc<gfx::WGfx>) -> anyhow::Result<()> {
|
|
// resize buffer if it's too small
|
|
let required_capacity_f32 = (self.models.len() * (4 * 4)) as u32;
|
|
|
|
if self.buffer_capacity_f32 < required_capacity_f32 {
|
|
self.buffer_capacity_f32 = required_capacity_f32;
|
|
self.buffer = gfx.empty_buffer::<f32>(
|
|
BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST,
|
|
required_capacity_f32.into(),
|
|
)?;
|
|
//log::info!("resized to {}", required_capacity_f32);
|
|
}
|
|
|
|
//safe
|
|
let floats = unsafe {
|
|
std::slice::from_raw_parts(
|
|
self.models.as_slice().as_ptr().cast::<f32>(),
|
|
required_capacity_f32 as usize,
|
|
)
|
|
};
|
|
|
|
self.buffer.write()?.copy_from_slice(floats);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Returns model matrix ID from the model
|
|
pub fn register(&mut self, model: &glam::Mat4) -> u32 {
|
|
/*for (idx, iter_model) in self.models.iter().enumerate() {
|
|
if iter_model == model {
|
|
return idx as u32;
|
|
}
|
|
}*/
|
|
|
|
if self.idx == self.models.len() as u32 {
|
|
self.models.resize((self.models.len() * 2).max(1), Default::default());
|
|
//log::info!("ModelBuffer: resized to {}", self.models.len());
|
|
}
|
|
|
|
// insert new
|
|
self.models[self.idx as usize] = *model;
|
|
let ret = self.idx;
|
|
self.idx += 1;
|
|
ret
|
|
}
|
|
|
|
pub fn register_pos_size(&mut self, pos: &glam::Vec2, size: &glam::Vec2, transform: &Mat4) -> u32 {
|
|
let mut model = glam::Mat4::from_translation(Vec3::new(pos.x, pos.y, 0.0));
|
|
model *= *transform;
|
|
model *= glam::Mat4::from_scale(Vec3::new(size.x, size.y, 1.0));
|
|
self.register(&model)
|
|
}
|
|
|
|
pub fn get_rect_descriptor(&mut self, pipeline: &RectPipeline) -> Arc<DescriptorSet> {
|
|
self
|
|
.rect_descriptor
|
|
.get_or_insert_with(|| pipeline.color_rect.buffer(1, self.buffer.clone()).unwrap())
|
|
.clone()
|
|
}
|
|
|
|
pub fn get_text_descriptor(&mut self, pipeline: &TextPipeline) -> Arc<DescriptorSet> {
|
|
self
|
|
.rect_descriptor
|
|
.get_or_insert_with(|| pipeline.inner.buffer(3, self.buffer.clone()).unwrap())
|
|
.clone()
|
|
}
|
|
}
|