1use std::marker::PhantomData;
3
4use mod3d_base::{BufferDataAccessor, BufferElementType, BufferIndexAccessor};
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, bda: &BufferDataAccessor<G>, render_context: &mut G) {
51 bda.desc().data().create_client(render_context);
52 self.elements_per_data = bda.count();
53 self.ele_type = bda.ele_type();
54 self.byte_offset = bda.desc().byte_offset();
55 self.stride = bda.desc().stride();
56 self.gl_buffer = bda.desc().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 Self {
206 gl_buffer,
207 count,
208 ele_type,
209 }
210 }
211 pub fn gl_buffer(&self) -> &<G as Gl>::Buffer {
213 &self.gl_buffer
214 }
215
216 }
218
219impl<G> std::fmt::Display for IndexBuffer<G>
221where
222 G: Gl,
223{
224 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
225 write!(
226 f,
227 "Ind({:?}#{} {:?})",
228 self.gl_buffer, self.count, self.ele_type,
229 )
230 }
231}
232
233impl<G> indent_display::DefaultIndentedDisplay for IndexBuffer<G> where G: Gl {}
235
236#[derive(Debug)]
241pub enum BufferView<G>
242where
243 G: Gl,
244{
245 VertexBuffer(VertexBuffer<G>),
247 IndexBuffer(IndexBuffer<G>),
249}
250
251impl<G> Default for BufferView<G>
253where
254 G: Gl,
255{
256 fn default() -> Self {
257 Self::VertexBuffer(VertexBuffer::default())
258 }
259}
260
261impl<G> Clone for BufferView<G>
263where
264 G: Gl,
265{
266 fn clone(&self) -> Self {
267 use BufferView::*;
268 match self {
269 VertexBuffer(b) => Self::VertexBuffer(b.clone()),
270 IndexBuffer(b) => Self::IndexBuffer(b.clone()),
271 }
272 }
273}
274
275impl<G> BufferView<G>
277where
278 G: Gl,
279{
280 pub fn as_index_buffer(&self) -> &IndexBuffer<G> {
284 match self {
285 Self::IndexBuffer(index_buffer) => index_buffer,
286 _ => panic!("Attempt to borrow a VertexBuffer as an IndexBuffer"),
287 }
288 }
289
290 pub fn as_vertex_buffer(&self) -> &VertexBuffer<G> {
294 match self {
295 Self::VertexBuffer(vertex_buffer) => vertex_buffer,
296 _ => panic!("Attempt to borrow an IndexBuffer as an VertexBuffer"),
297 }
298 }
299
300 pub fn init_index_accessor_client(
303 &mut self,
304 buffer_view: &BufferIndexAccessor<G>,
305 renderer: &mut G,
306 ) {
307 let index_buffer = IndexBuffer::of_view(buffer_view, renderer);
308 *self = BufferView::IndexBuffer(index_buffer);
309 }
310
311 pub fn init_data_accessor_client(
314 &mut self,
315 buffer_data_accessor: &BufferDataAccessor<G>,
316 renderer: &mut G,
317 ) {
318 match self {
319 BufferView::IndexBuffer(_) => panic!("Vertex buffer is already an index buffer"),
320 BufferView::VertexBuffer(vb) => {
321 vb.of_view(buffer_data_accessor, renderer);
322 }
323 }
324 }
325}
326
327impl<G> mod3d_base::AccessorClient for BufferView<G> where G: Gl {}
329
330impl<G> std::fmt::Display for BufferView<G>
332where
333 G: Gl,
334{
335 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
336 match self {
337 Self::IndexBuffer(index_buffer) => index_buffer.fmt(f),
338 Self::VertexBuffer(vertex_buffer) => vertex_buffer.fmt(f),
339 }
340 }
341}
342
343impl<G> indent_display::DefaultIndentedDisplay for BufferView<G> where G: Gl {}
345
346#[derive(Debug)]
354pub struct UniformBuffer<G>
355where
356 G: Gl,
357{
358 gl_buffer: <G as Gl>::Buffer,
360 byte_length: usize,
362 phantom: PhantomData<G>,
363}
364
365impl<G> UniformBuffer<G>
367where
368 G: Gl,
369{
370 pub fn of_data<F: Sized>(context: &mut G, data: &[F], is_dynamic: bool) -> Result<Self, ()> {
372 G::uniform_buffer_create(context, data, is_dynamic)
373 }
374
375 pub fn new(gl_buffer: <G as Gl>::Buffer, byte_length: usize) -> Self {
377 Self {
378 gl_buffer,
379 byte_length,
380 phantom: PhantomData,
381 }
382 }
383
384 pub fn gl_buffer(&self) -> &<G as Gl>::Buffer {
388 &self.gl_buffer
389 }
390
391 pub fn byte_length(&self) -> usize {
393 self.byte_length
394 }
395
396 pub fn offset_and_length(&self, byte_offset: usize, byte_length: usize) -> (usize, usize) {
398 if byte_length == 0 {
399 (0, self.byte_length)
400 } else {
401 (byte_offset, byte_length)
402 }
403 }
404}