use bytes::Bytes;
use std::{
clone::Clone,
fmt,
sync::{Arc, RwLock},
};
use super::{BufferUpdateHint, Usage, VertexAttribute, VertexFormat};
#[derive(Debug, Clone)]
pub enum BufferFlags {
None = 0,
BufferObject = 1 << 0, Mapped = 1 << 1,
MappedFallback = 1 << 2,
}
impl Default for BufferFlags {
fn default() -> Self {
Self::None
}
}
#[derive(Debug, Clone)]
pub enum BufferUsageHint {
Texture,
AttributeBuffer,
IndexBuffer,
}
impl Default for BufferUsageHint {
fn default() -> Self {
Self::Texture
}
}
#[derive(Debug, Clone)]
pub enum BufferBindTarget {
PixelPack,
PixelUnpack,
AttributeBuffer,
IndexBuffer,
Count,
}
impl Default for BufferBindTarget {
fn default() -> Self {
Self::PixelPack
}
}
#[derive(Default, Debug, Clone)]
pub struct Buffer {
last_target: BufferBindTarget,
flags: BufferFlags,
handle: u32,
size: u32,
usage_hint: BufferUsageHint,
update_hint: BufferUpdateHint,
data: Bytes,
immutable_ref: i32,
store_created: bool,
}
#[derive(Default, Clone, Debug)]
pub struct VertexStructure {
pub instanced: bool,
pub elements: Vec<(String, VertexFormat)>,
}
impl VertexStructure {
pub fn new() -> Self {
Default::default()
}
pub fn byte_size(&self) -> usize {
unimplemented!()
}
pub fn add<T: Into<String>>(&mut self, name: T, format: VertexFormat) {
self.elements.push((name.into(), format))
}
}
#[derive(Debug, Default, Clone)]
#[repr(C)]
pub struct VertexBuffer<T>
where
T: Default + Clone + fmt::Debug,
{
handle: Option<u32>,
size: usize,
vertices: Arc<RwLock<Option<Vec<T>>>>,
atttribute_layout: VertexStructure,
usage: Usage,
}
impl<T> VertexBuffer<T>
where
T: Default + Clone + fmt::Debug,
{
pub fn new(size: usize, atttribute_layout: VertexStructure, usage: Usage) -> Self {
let mut vertices = Vec::with_capacity(size);
vertices.resize(size, T::default());
Self {
handle: None,
size,
atttribute_layout,
usage,
vertices: Arc::new(RwLock::new(Some(vertices))),
}
}
pub fn lock(&self, closure: impl Fn(&mut [T])) {
match self.vertices.write() {
Ok(ref mut vertices) => match vertices.as_mut() {
Some(data) => {
closure(data.as_mut_slice());
}
None => {
log::warn!("VertexBuffer is empty");
}
},
Err(e) => panic!("RwLock poisoned"),
}
}
}
impl<T> Drop for VertexBuffer<T>
where
T: Default + Clone + fmt::Debug,
{
fn drop(&mut self) {
match self.handle {
Some(handle) => {
println!("Should free GPU buffer {}", handle);
}
None => {}
}
}
}