mod3d_base/
buffer_data_accessor.rs

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