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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//a Imports
use std::cell::RefCell;
use std::ops::DerefMut;
use crate::{BufferData, BufferElementType, Renderable};
//a BufferIndexAccessor
//tp BufferIndexAccessor
/// A subset of a `BufferData`, used for vertex attributes;
/// hence for use in a vertex attribute pointer.
///
/// A `BufferIndexAccessor` is used for a single attribute of a set of data, such as
/// Position or Normal.
pub struct BufferIndexAccessor<'a, R: Renderable> {
/// The `BufferData` that contains the actual index data
data: &'a BufferData<'a, R>,
/// Number of indices in the buffer
number_indices: u32,
/// The type of each element
///
/// For indices this must be UInt8, UInt16 or UInt32
ele_type: BufferElementType,
/// Offset from start of buffer to first byte of data
byte_offset: 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 `BufferIndexAccessor`s using
/// it - which then have shared references to the daata - but the
/// client is created afterwards
rc_client: RefCell<R::IndexAccessor>,
}
//ip Display for BufferIndexAccessor
impl<'a, R: Renderable> std::fmt::Debug for BufferIndexAccessor<'a, R>
where
R: Renderable,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
fmt,
"BufferIndexAccessor{{ {:?}:{:?} #{}@{}}}",
self.data,
self.ele_type,
self.number_indices,
self.byte_offset,
// self.rc_client
)
}
}
//ip AsRef<[u8]> for BufferIndexAccessor
impl<'a, R> AsRef<[u8]> for BufferIndexAccessor<'a, R>
where
R: Renderable,
{
fn as_ref(&self) -> &[u8] {
let data: &[u8] = self.data.as_ref();
let start = self.byte_offset as usize;
let byte_length = self.number_indices * self.ele_type.byte_length();
let end = (self.byte_offset + byte_length) as usize;
&data[start..end]
}
}
//ip BufferIndexAccessor
impl<'a, R: Renderable> BufferIndexAccessor<'a, R> {
//ap data
/// Get a reference to the underlying [BufferData]
pub fn data(&self) -> &BufferData<'a, R> {
self.data
}
//ap number_indices
/// Number of indices in the buffer
pub fn number_indices(&self) -> u32 {
self.number_indices
}
//ap ele_type
/// The type of each element
///
/// For indices this must be UInt8, UInt16 or UInt32
pub fn ele_type(&self) -> BufferElementType {
self.ele_type
}
//ap byte_offset
/// Offset from start of buffer to first byte of data
pub fn byte_offset(&self) -> u32 {
self.byte_offset
}
//fp new
/// Create a new index accessor of a `BufferData`
pub fn new(
data: &'a BufferData<'a, R>,
number_indices: u32,
ele_type: BufferElementType,
byte_offset: u32, // offset in bytes from start of data
) -> Self {
let rc_client = RefCell::new(R::IndexAccessor::default());
Self {
data,
number_indices,
ele_type,
byte_offset,
rc_client,
}
}
//mp create_client
/// Create the render buffer required by the BufferIndexAccessor
pub fn create_client(&self, renderable: &mut R) {
renderable.init_index_accessor_client(self.rc_client.borrow_mut().deref_mut(), self);
}
//ap borrow_client
/// Borrow the client
pub fn borrow_client(&self) -> std::cell::Ref<R::IndexAccessor> {
self.rc_client.borrow()
}
//zz All done
}
//ip Display for BufferIndexAccessor
impl<'a, R: Renderable> std::fmt::Display for BufferIndexAccessor<'a, R> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, fmt)
}
}
//ip DefaultIndentedDisplay for BufferIndexAccessor
impl<'a, R: Renderable> indent_display::DefaultIndentedDisplay for BufferIndexAccessor<'a, R> {}