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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//a Imports
use std::cell::RefCell;
use crate::{BufferData, Renderable, VertexDesc};
//a BufferDescriptor
//tp BufferDescriptor
/// A descriptor of a subset of a `BufferData`, used for vertex attributes;
/// hence for use in a vertex attribute pointer.
///
/// A [BufferDescriptor] allows portion of a [BufferData] to contain
/// an array of structs with multiple fields for, e.g., Vertex, Normal
/// and Color.
///
/// A [BufferDescriptor] is used within a [crate::BufferDataAccessor]
/// to describe *just* an individual field element.
pub struct BufferDescriptor<'a, R: Renderable> {
/// The `BufferData` that contains the actual vertex attribute data
data: &'a BufferData<'a, R>,
/// Byte offset to first data inside 'data'
byte_offset: u32,
/// Byte length of the data used by the descriptor
byte_length: u32,
// Indexed by instance - if true, instance 'n' vertex 'v' use the
// data from index 'n'; if false then instance 'n' vertex 'v' use
// the data from index 'v'.
//
// index_by_instance: bool,
/// Stride of data in the buffer
///
/// This is always at least the maximum of the elements[].byte_offset() + byte_length()
stride: u32,
/// Description of the layout of the elements of the actual portion of buffer data
///
/// This could become a reference to a struct that is borrowed here, with its own client ref
elements: Vec<VertexDesc>,
/// The client bound to data\[byte_offset\] .. + byte_length
///
/// This must be held as a [RefCell] as the [BufferDescriptor] is
/// created early in the process, prior to any `BufferDataAccessor`s using
/// it - which then have shared references to the descriptor - but the
/// client is created afterwards
rc_client: RefCell<R::Descriptor>,
}
//ip Display for BufferDescriptor
impl<'a, R: Renderable> std::fmt::Debug for BufferDescriptor<'a, R>
where
R: Renderable,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
fmt,
"BufferDescriptor{{ {:?} @{}+*{}}}",
self.data,
self.byte_offset,
self.stride,
// self.ele_type,
// self.elements_per_data,
// self.rc_client
)
}
}
//ip AsRef<[u8]> for BufferDescriptor
impl<'a, R> AsRef<[u8]> for BufferDescriptor<'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 end = (self.byte_offset + self.byte_length) as usize;
&data[start..end]
}
}
//ip BufferDescriptor
impl<'a, R: Renderable> BufferDescriptor<'a, R> {
//ap data
/// Get a reference to the underlying [BufferData]
pub fn data(&self) -> &BufferData<'a, R> {
self.data
}
//ap byte_offset
/// Get the byte offset within the underlying [BufferData] for
/// this descriptor
pub fn byte_offset(&self) -> u32 {
self.byte_offset
}
//ap byte_length
/// Get the byte length within the underlying [BufferData] for
/// this descriptor
pub fn byte_length(&self) -> u32 {
self.byte_length
}
//ap stride
/// Get the byte stride between different indices for the instances for
/// this descriptor
pub fn stride(&self) -> u32 {
self.stride
}
//ap element
/// Get a reference to the n'th element
pub fn element(&self, n: usize) -> &VertexDesc {
&self.elements[n]
}
//ap elements
/// Get a reference to the elements
pub fn elements(&self) -> &[VertexDesc] {
&self.elements
}
//fp new
/// Create a new view of a `BufferData`
pub fn new(
data: &'a BufferData<'a, R>,
byte_offset: u32,
byte_length: u32,
mut stride: u32,
elements: Vec<VertexDesc>,
) -> Self {
assert!(
byte_offset + byte_length <= data.byte_length(),
"Buffer data is not large enough for data {byte_offset} + #{byte_length} [ got {}]",
data.byte_length()
);
let rc_client = RefCell::new(R::Descriptor::default());
for e in elements.iter() {
stride = stride.max(e.byte_offset() as u32 + e.byte_length());
}
Self {
data,
byte_offset,
byte_length,
stride,
elements,
rc_client,
}
}
//mp add_vertex_desc
/// Add a [VertexDesc] to the fields that this [BufferDescriptor] describes.
pub fn add_vertex_desc(&mut self, vertex_desc: VertexDesc) -> u8 {
let n = self.elements.len() as u8;
self.stride = self
.stride
.max(vertex_desc.byte_offset() as u32 + vertex_desc.byte_length());
self.elements.push(vertex_desc);
n
}
//mp create_client
/// Create the render buffer required by the BufferDescriptor
pub fn create_client(&self, renderable: &mut R) {
use std::ops::DerefMut;
renderable.init_buffer_desc_client(self.rc_client.borrow_mut().deref_mut(), self);
}
//ap borrow_client
/// Borrow the client
pub fn borrow_client(&self) -> std::cell::Ref<R::Descriptor> {
self.rc_client.borrow()
}
//zz All done
}
//ip Display for BufferDescriptor
impl<'a, R: Renderable> std::fmt::Display for BufferDescriptor<'a, R> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, f)
}
}
//ip DefaultIndentedDisplay for BufferDescriptor
impl<'a, R: Renderable> indent_display::DefaultIndentedDisplay for BufferDescriptor<'a, R> {}