use super::*;
use std::os::raw::c_void;
#[derive(Default)]
pub struct StructuredBuffer<T>
where T: Default + Clone {
phantom: std::marker::PhantomData<T>,
id : GLuint,
buffer_size : usize,
elements : usize,
}
impl<T: Default + Clone> StructuredBuffer<T> {
pub fn new(size : usize) -> Self
{
let mut id = 0;
let buffer_size = std::mem::size_of::<T>() * size;
let mut empty_data = Vec::new();
empty_data.resize(size, T::default());
unsafe{
gl::GenBuffers(1,&mut id);
gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, id);
gl::BufferData(gl::SHADER_STORAGE_BUFFER, buffer_size as isize, empty_data.as_ptr() as *const c_void, gl::DYNAMIC_COPY);
gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, 0);
}
StructuredBuffer{
phantom: std::marker::PhantomData,
id,
buffer_size,
elements: size
}
}
pub fn from(data : Vec<T>) -> Self {
let mut id = 0;
let buffer_size = std::mem::size_of::<T>() * data.len();
unsafe{
gl::GenBuffers(1,&mut id);
gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, id);
gl::BufferData(gl::SHADER_STORAGE_BUFFER, buffer_size as isize, data.as_ptr() as *const c_void, gl::DYNAMIC_COPY);
gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, 0);
}
StructuredBuffer{
phantom: std::marker::PhantomData,
id,
buffer_size,
elements: data.len()
}
}
pub fn map_data(&mut self, data : &Vec<T>){
unsafe{
gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, self.id);
let d : *mut T = gl::MapBuffer(gl::SHADER_STORAGE_BUFFER, gl::WRITE_ONLY) as *mut T;
std::ptr::copy(data.as_ptr() as *const T, d, self.elements);
gl::UnmapBuffer(gl::SHADER_STORAGE_BUFFER);
gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, 0);
}
}
pub fn get_id(&self) -> GLuint{
self.id
}
pub fn get_size(&self) -> usize {
self.buffer_size
}
}
impl<T: Default + Clone> Drop for StructuredBuffer<T>{
fn drop(&mut self){
unsafe{
gl::DeleteBuffers(1, &self.id);
}
}
}