mod3d_base/
buffer_index_accessor.rs

1//a Imports
2use std::cell::RefCell;
3use std::ops::DerefMut;
4
5use crate::{BufferData, BufferElementType, Renderable};
6
7//a BufferIndexAccessor
8//tp BufferIndexAccessor
9/// A subset of a `BufferData`, used for vertex attributes;
10/// hence for use in a vertex attribute pointer.
11///
12/// A `BufferIndexAccessor` is used for a single attribute of a set of data, such as
13/// Position or Normal.
14pub struct BufferIndexAccessor<'a, R: Renderable> {
15    /// The `BufferData` that contains the actual index data
16    data: &'a BufferData<'a, R>,
17
18    /// Number of indices in the buffer
19    number_indices: u32,
20
21    /// The type of each element
22    ///
23    /// For indices this must be UInt8, UInt16 or UInt32
24    ele_type: BufferElementType,
25
26    /// Offset from start of buffer to first byte of data
27    byte_offset: u32,
28
29    /// The client bound to data\[byte_offset\] .. + byte_length
30    ///
31    /// This must be held as a [RefCell] as the [BufferData] is
32    /// created early in the process, prior to any `BufferIndexAccessor`s using
33    /// it - which then have shared references to the daata - but the
34    /// client is created afterwards
35    rc_client: RefCell<R::IndexAccessor>,
36}
37
38//ip Display for BufferIndexAccessor
39impl<'a, R: Renderable> std::fmt::Debug for BufferIndexAccessor<'a, R>
40where
41    R: Renderable,
42{
43    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
44        write!(
45            fmt,
46            "BufferIndexAccessor{{ {:?}:{:?} #{}@{}}}",
47            self.data,
48            self.ele_type,
49            self.number_indices,
50            self.byte_offset,
51            //  self.rc_client
52        )
53    }
54}
55
56//ip AsRef<[u8]> for BufferIndexAccessor
57impl<'a, R> AsRef<[u8]> for BufferIndexAccessor<'a, R>
58where
59    R: Renderable,
60{
61    fn as_ref(&self) -> &[u8] {
62        let data: &[u8] = self.data.as_ref();
63        let start = self.byte_offset as usize;
64        let byte_length = self.number_indices * self.ele_type.byte_length();
65        let end = (self.byte_offset + byte_length) as usize;
66        &data[start..end]
67    }
68}
69
70//ip BufferIndexAccessor
71impl<'a, R: Renderable> BufferIndexAccessor<'a, R> {
72    //ap data
73    /// Get a reference to the underlying [BufferData]
74    pub fn data(&self) -> &BufferData<'a, R> {
75        self.data
76    }
77
78    //ap number_indices
79    /// Number of indices in the buffer
80    pub fn number_indices(&self) -> u32 {
81        self.number_indices
82    }
83
84    //ap ele_type
85    /// The type of each element
86    ///
87    /// For indices this must be UInt8, UInt16 or UInt32
88    pub fn ele_type(&self) -> BufferElementType {
89        self.ele_type
90    }
91
92    //ap byte_offset
93    /// Offset from start of buffer to first byte of data
94    pub fn byte_offset(&self) -> u32 {
95        self.byte_offset
96    }
97
98    //fp new
99    /// Create a new index accessor of a `BufferData`
100    pub fn new(
101        data: &'a BufferData<'a, R>,
102        number_indices: u32,
103        ele_type: BufferElementType,
104        byte_offset: u32, // offset in bytes from start of data
105    ) -> Self {
106        let rc_client = RefCell::new(R::IndexAccessor::default());
107        Self {
108            data,
109            number_indices,
110            ele_type,
111            byte_offset,
112            rc_client,
113        }
114    }
115
116    //mp create_client
117    /// Create the render buffer required by the BufferIndexAccessor
118    pub fn create_client(&self, renderable: &mut R) {
119        renderable.init_index_accessor_client(self.rc_client.borrow_mut().deref_mut(), self);
120    }
121
122    //ap borrow_client
123    /// Borrow the client
124    pub fn borrow_client(&self) -> std::cell::Ref<R::IndexAccessor> {
125        self.rc_client.borrow()
126    }
127
128    //zz All done
129}
130
131//ip Display for BufferIndexAccessor
132impl<'a, R: Renderable> std::fmt::Display for BufferIndexAccessor<'a, R> {
133    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
134        std::fmt::Debug::fmt(self, fmt)
135    }
136}
137
138//ip DefaultIndentedDisplay for BufferIndexAccessor
139impl<'a, R: Renderable> indent_display::DefaultIndentedDisplay for BufferIndexAccessor<'a, R> {}