1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
//a Imports
use std::cell::RefCell;
use crate::{BufferData, BufferElementType, Renderable, VertexAttr};
//a BufferAccessor
//tp BufferAccessor
/// A subset of a `BufferData`, used for vertex attributes;
/// hence for use in a vertex attribute pointer.
///
/// A `BufferAccessor` is used for a single attribute of a set of data, such as
/// Position or Normal.
pub struct BufferAccessor<'a, R: Renderable + ?Sized> {
/// The `BufferData` that contains the actual vertex attribute data
pub data: &'a BufferData<'a, R>,
/// For attributes: number of elements per vertex (1 to 4, or 4, 9 or 16)
/// For indices: number of indices in the buffer
pub elements_per_data: u32,
/// The type of each element
///
/// For indices this must be Int8, Int16 or Int32
pub ele_type: BufferElementType,
/// Offset from start of buffer to first byte of data
pub byte_offset: u32,
/// Stride of data in the buffer - 0 for count*sizeof(ele_type)
/// Unused for indices
pub stride: u32,
/// The client bound to data\[byte_offset\] .. + byte_length
///
/// This must be held as a [RefCell] as the [BufferData] is
/// created early in the process, prior to any `BufferAccessor`s using
/// it - which then have shared references to the daata - but the
/// client is created afterwards
rc_client: RefCell<R::Accessor>,
}
//ip Display for Object
impl<'a, R: Renderable> std::fmt::Debug for BufferAccessor<'a, R>
where
R: Renderable,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
fmt,
"BufferAccessor{{ {:?}:{:?} #{}@{}+*{}}}",
self.data,
self.ele_type,
self.elements_per_data,
self.byte_offset,
self.stride,
// self.rc_client
)
}
}
//ip BufferAccessor
impl<'a, R: Renderable> BufferAccessor<'a, R> {
//fp new
/// Create a new view of a `BufferData`
pub fn new(
data: &'a BufferData<'a, R>,
count: u32, // count is number of ele_type in an attribute
ele_type: BufferElementType,
byte_offset: u32, // offset in bytes from start of data
stride: u32, /* stride between elements
* (0->count*sizeof(ele_type)) */
) -> Self {
let rc_client = RefCell::new(R::Accessor::default());
Self {
data,
elements_per_data: count,
ele_type,
byte_offset,
stride,
rc_client,
}
}
//mp create_client
/// Create the render buffer required by the BufferAccessor
pub fn create_client(&self, attr: VertexAttr, renderable: &mut R) {
use std::ops::DerefMut;
renderable.init_buffer_view_client(self.rc_client.borrow_mut().deref_mut(), self, attr);
}
//ap borrow_client
/// Borrow the client
pub fn borrow_client(&self) -> std::cell::Ref<R::Accessor> {
self.rc_client.borrow()
}
//zz All done
}
//ip Display for BufferAccessor
impl<'a, R: Renderable> std::fmt::Display for BufferAccessor<'a, R> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(
f,
"BufferAccessor[{:?}#{}]\n {}+{}+n*{}\n",
self.ele_type, self.elements_per_data, self.data, self.byte_offset, self.stride
)
}
}
//ip DefaultIndentedDisplay for BufferAccessor
impl<'a, R: Renderable> indent_display::DefaultIndentedDisplay for BufferAccessor<'a, R> {}