use std::marker::PhantomData;
use crate::core::*;
pub trait ElementBufferDataType: data_type::DataType {
fn as_u32(&self) -> u32;
}
impl ElementBufferDataType for u8 {
fn as_u32(&self) -> u32 {
*self as u32
}
}
impl ElementBufferDataType for u16 {
fn as_u32(&self) -> u32 {
*self as u32
}
}
impl ElementBufferDataType for u32 {
fn as_u32(&self) -> u32 {
*self
}
}
pub struct ElementBuffer<T: ElementBufferDataType> {
context: Context,
id: crate::context::Buffer,
count: u32,
_d: PhantomData<T>,
}
impl<T: ElementBufferDataType> ElementBuffer<T> {
pub fn new(context: &Context) -> Self {
let id = unsafe { context.create_buffer().expect("Failed creating buffer") };
Self {
context: context.clone(),
id,
count: 0,
_d: PhantomData,
}
}
pub fn new_with_data(context: &Context, data: &[T]) -> Self {
let mut buffer = Self::new(context);
if !data.is_empty() {
buffer.fill(data);
}
buffer
}
pub fn fill(&mut self, indices: &[T]) {
self.bind();
unsafe {
self.context.buffer_data_u8_slice(
crate::context::ELEMENT_ARRAY_BUFFER,
to_byte_slice(indices),
crate::context::STATIC_DRAW,
);
self.context
.bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None);
}
self.count = indices.len() as u32;
}
pub fn fill_subset(&mut self, offset: u32, indices: &[T]) {
self.bind();
unsafe {
self.context.buffer_sub_data_u8_slice(
crate::context::ELEMENT_ARRAY_BUFFER,
offset as i32,
to_byte_slice(indices),
);
self.context
.bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None);
}
self.count = (offset + indices.len() as u32).max(self.count);
}
pub fn count(&self) -> u32 {
self.count
}
pub fn triangle_count(&self) -> u32 {
self.count / 3
}
pub(crate) fn bind(&self) {
unsafe {
self.context
.bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, Some(self.id));
}
}
}
impl<T: ElementBufferDataType> Drop for ElementBuffer<T> {
fn drop(&mut self) {
unsafe {
self.context.delete_buffer(self.id);
}
}
}