1use std::marker::PhantomData;
3
4use mod3d_base::{BufferDataAccessor, BufferElementType, BufferIndexAccessor, VertexAttr};
5
6use crate::{Gl, GlProgram};
7
8#[derive(Debug)]
20pub struct VertexBuffer<G>
21where
22 G: Gl,
23{
24 gl_buffer: <G as Gl>::Buffer,
26 pub elements_per_data: u32,
28 pub ele_type: BufferElementType,
30 pub byte_offset: u32,
32 pub stride: u32,
34}
35
36impl<G> VertexBuffer<G>
38where
39 G: Gl,
40{
41 pub fn gl_buffer(&self) -> &<G as Gl>::Buffer {
45 &self.gl_buffer
46 }
47
48 fn of_view(&mut self, view: &BufferDataAccessor<G>, render_context: &mut G) {
51 view.data.create_client(render_context);
52 self.elements_per_data = view.elements_per_data;
53 self.ele_type = view.ele_type;
54 self.byte_offset = view.byte_offset;
55 self.stride = view.stride;
56 self.gl_buffer = view.data.borrow_client().clone();
57 }
58
59 pub fn bind_to_vao_attr(
62 &self,
63 context: &mut G,
64 attr_id: &<<G as Gl>::Program as GlProgram>::GlAttrId,
65 ) {
66 context.buffer_bind_to_vao_attr(
67 &self.gl_buffer,
68 attr_id,
69 self.elements_per_data,
70 self.ele_type,
71 self.byte_offset,
72 self.stride,
73 );
74 }
75
76 }
78
79impl<G> Default for VertexBuffer<G>
81where
82 G: Gl,
83{
84 fn default() -> Self {
85 let gl_buffer = <G as Gl>::Buffer::default();
86 let elements_per_data = 0;
87 let ele_type = BufferElementType::float32();
88 let byte_offset = 0;
89 let stride = 0;
90 Self {
91 gl_buffer,
92 elements_per_data,
93 ele_type,
94 byte_offset,
95 stride,
96 }
97 }
98}
99
100impl<G> Clone for VertexBuffer<G>
102where
103 G: Gl,
104{
105 fn clone(&self) -> Self {
106 let gl_buffer = self.gl_buffer.clone();
107 let elements_per_data = self.elements_per_data;
108 let ele_type = self.ele_type;
109 let byte_offset = self.byte_offset;
110 let stride = self.stride;
111 Self {
112 gl_buffer,
113 elements_per_data,
114 ele_type,
115 byte_offset,
116 stride,
117 }
118 }
119}
120
121impl<G> std::fmt::Display for VertexBuffer<G>
123where
124 G: Gl,
125{
126 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
127 write!(
128 f,
129 "Vert({:?}+{}:#{} {:?} @{})",
130 self.gl_buffer, self.byte_offset, self.elements_per_data, self.ele_type, self.stride
131 )
132 }
133}
134
135impl<G> indent_display::DefaultIndentedDisplay for VertexBuffer<G> where G: Gl {}
137
138#[derive(Debug)]
146pub struct IndexBuffer<G>
147where
148 G: Gl,
149{
150 gl_buffer: <G as Gl>::Buffer,
152 pub count: u32,
154 pub ele_type: BufferElementType,
156}
157
158impl<G> Default for IndexBuffer<G>
160where
161 G: Gl,
162{
163 fn default() -> Self {
164 let gl_buffer = <G as Gl>::Buffer::default();
165 let count = 0;
166 let ele_type = BufferElementType::UInt8;
167 Self {
168 gl_buffer,
169 count,
170 ele_type,
171 }
172 }
173}
174
175impl<G> Clone for IndexBuffer<G>
177where
178 G: Gl,
179{
180 fn clone(&self) -> Self {
181 let gl_buffer = self.gl_buffer.clone();
182 let count = self.count;
183 let ele_type = self.ele_type;
184 Self {
185 gl_buffer,
186 count,
187 ele_type,
188 }
189 }
190}
191
192impl<G> IndexBuffer<G>
194where
195 G: Gl,
196{
197 fn of_view(view: &BufferIndexAccessor<G>, render_context: &mut G) -> Self {
200 let mut gl_buffer = <G as Gl>::Buffer::default();
201 render_context.init_buffer_of_indices(&mut gl_buffer, view);
202 let count = view.number_indices;
203 let ele_type = view.ele_type;
204 println!(
205 "Create indices buffer {} of view {:?}#{}",
206 gl_buffer, ele_type, count
207 );
208 Self {
209 gl_buffer,
210 count,
211 ele_type,
212 }
213 }
214 pub fn gl_buffer(&self) -> &<G as Gl>::Buffer {
216 &self.gl_buffer
217 }
218
219 }
221
222impl<G> std::fmt::Display for IndexBuffer<G>
224where
225 G: Gl,
226{
227 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
228 write!(
229 f,
230 "Ind({:?}#{} {:?})",
231 self.gl_buffer, self.count, self.ele_type,
232 )
233 }
234}
235
236impl<G> indent_display::DefaultIndentedDisplay for IndexBuffer<G> where G: Gl {}
238
239#[derive(Debug)]
244pub enum BufferView<G>
245where
246 G: Gl,
247{
248 VertexBuffer(VertexBuffer<G>),
250 IndexBuffer(IndexBuffer<G>),
252}
253
254impl<G> Default for BufferView<G>
256where
257 G: Gl,
258{
259 fn default() -> Self {
260 Self::VertexBuffer(VertexBuffer::default())
261 }
262}
263
264impl<G> Clone for BufferView<G>
266where
267 G: Gl,
268{
269 fn clone(&self) -> Self {
270 use BufferView::*;
271 match self {
272 VertexBuffer(b) => Self::VertexBuffer(b.clone()),
273 IndexBuffer(b) => Self::IndexBuffer(b.clone()),
274 }
275 }
276}
277
278impl<G> BufferView<G>
280where
281 G: Gl,
282{
283 pub fn as_index_buffer(&self) -> &IndexBuffer<G> {
287 match self {
288 Self::IndexBuffer(index_buffer) => index_buffer,
289 _ => panic!("Attempt to borrow a VertexBuffer as an IndexBuffer"),
290 }
291 }
292
293 pub fn as_vertex_buffer(&self) -> &VertexBuffer<G> {
297 match self {
298 Self::VertexBuffer(vertex_buffer) => vertex_buffer,
299 _ => panic!("Attempt to borrow an IndexBuffer as an VertexBuffer"),
300 }
301 }
302
303 pub fn init_index_accessor_client(
306 &mut self,
307 buffer_view: &BufferIndexAccessor<G>,
308 renderer: &mut G,
309 ) {
310 let index_buffer = IndexBuffer::of_view(buffer_view, renderer);
311 *self = BufferView::IndexBuffer(index_buffer);
312 }
313
314 pub fn init_buffer_view_client(
317 &mut self,
318 buffer_view: &BufferDataAccessor<G>,
319 attr: VertexAttr,
320 renderer: &mut G,
321 ) {
322 match self {
323 BufferView::IndexBuffer(_) => panic!("Vertex buffer is already an index buffer"),
324 BufferView::VertexBuffer(vb) => {
325 vb.of_view(buffer_view, renderer);
326 }
327 }
328 }
329}
330
331impl<G> mod3d_base::AccessorClient for BufferView<G> where G: Gl {}
333
334impl<G> std::fmt::Display for BufferView<G>
336where
337 G: Gl,
338{
339 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
340 match self {
341 Self::IndexBuffer(index_buffer) => index_buffer.fmt(f),
342 Self::VertexBuffer(vertex_buffer) => vertex_buffer.fmt(f),
343 }
344 }
345}
346
347impl<G> indent_display::DefaultIndentedDisplay for BufferView<G> where G: Gl {}
349
350#[derive(Debug)]
358pub struct UniformBuffer<G>
359where
360 G: Gl,
361{
362 gl_buffer: <G as Gl>::Buffer,
364 byte_length: usize,
366 phantom: PhantomData<G>,
367}
368
369impl<G> UniformBuffer<G>
371where
372 G: Gl,
373{
374 pub fn of_data<F: Sized>(context: &mut G, data: &[F], is_dynamic: bool) -> Result<Self, ()> {
376 G::uniform_buffer_create(context, data, is_dynamic)
377 }
378
379 pub fn new(gl_buffer: <G as Gl>::Buffer, byte_length: usize) -> Self {
381 Self {
382 gl_buffer,
383 byte_length,
384 phantom: PhantomData,
385 }
386 }
387
388 pub fn gl_buffer(&self) -> &<G as Gl>::Buffer {
392 &self.gl_buffer
393 }
394
395 pub fn byte_length(&self) -> usize {
397 self.byte_length
398 }
399
400 pub fn offset_and_length(&self, byte_offset: usize, byte_length: usize) -> (usize, usize) {
402 if byte_length == 0 {
403 (0, self.byte_length)
404 } else {
405 (byte_offset, byte_length)
406 }
407 }
408}