1use std::f32::consts::PI;
14use std::marker::PhantomData;
15
16use encase::private::WriteInto;
17use encase::ShaderType;
18
19use crate::colour::Colour;
20use crate::context::WgpuClump;
21use crate::engine_handle::Engine;
22use crate::matrix_math::normalize_points;
23use crate::render::Renderer;
24use crate::resource::ResourceId;
25use crate::shader::{Shader, UniformData, UniformError};
26use crate::texture::{Texture, UniformTexture};
27use crate::vectors::Vec2;
28use crate::vertex::{self, LineVertex, Vertex};
29
30#[derive(Debug)]
35pub struct Material<T = ()> {
36 pipeline_id: ResourceId<Shader>,
37 pub(crate) vertex_size: u64,
39 pub(crate) vertex_count: u64,
40 pub(crate) index_count: u64,
42 pub(crate) index_size: u64,
43 inner: Option<InnerBuffer>,
44 texture_id: ResourceId<Texture>,
45 _marker: PhantomData<T>,
46}
47
48impl<T> Material<T> {
49 fn from_builder(builder: MaterialBuilder<T>, engine: &mut Engine) -> Self {
51 let pipeline_id = match builder.shader_change {
52 Some(rs) => rs,
53 None => engine.defualt_pipe_id(),
54 };
55
56 let texture_id = builder
57 .texture_change
58 .unwrap_or(engine.defualt_material_bg_id());
59
60 let vertex_size = std::mem::size_of::<Vertex>() as u64;
61 let index_size = std::mem::size_of::<u16>() as u64;
62
63 Self {
64 pipeline_id,
65 vertex_count: 0,
66 vertex_size,
67 index_count: 0,
68 index_size,
69 inner: None,
70 texture_id,
71 _marker: PhantomData,
72 }
73 }
74
75 pub fn change_texture(&mut self, texture: ResourceId<Texture>) {
77 self.texture_id = texture
78 }
79
80 pub fn add_rectangle(
82 &mut self,
83 position: Vec2<f32>,
84 size: Vec2<f32>,
85 colour: Colour,
86 render: &Renderer,
87 ) {
88 let wgpu = render.wgpu;
89 let verts = vertex::from_pixels(position, size, colour.as_raw());
90
91 self.push_rectangle(wgpu, verts);
92 }
93
94 pub fn add_screenspace_rectangle(
96 &mut self,
97 position: Vec2<f32>,
98 size: Vec2<f32>,
99 colour: Colour,
100 render: &Renderer,
101 ) {
102 let wgpu = render.wgpu;
103 let screen_size = render.size;
104
105 let verts = vertex::new(position, size, colour.as_raw(), screen_size);
106 self.push_rectangle(wgpu, verts);
107 }
108
109 pub fn add_rectangle_with_uv(
112 &mut self,
113 position: Vec2<f32>,
114 size: Vec2<f32>,
115 uv_position: Vec2<f32>,
116 uv_size: Vec2<f32>,
117 colour: Colour,
118 render: &Renderer,
119 ) {
120 let wgpu = render.wgpu;
121
122 let texture_size = render
123 .resources
124 .get_texture(&self.texture_id)
125 .map(|t| t.size)
126 .unwrap_or(Vec2 { x: 1.0, y: 1.0 });
127 let uv_size = normalize_points(uv_size, texture_size);
130 let uv_position = normalize_points(uv_position, texture_size);
131
132 let verts =
133 vertex::from_pixels_with_uv(position, size, colour.as_raw(), uv_position, uv_size);
134
135 self.push_rectangle(wgpu, verts);
136 }
137
138 pub fn add_rectangle_with_rotation(
140 &mut self,
141 position: Vec2<f32>,
142 size: Vec2<f32>,
143 colour: Colour,
144 rotation: f32,
145 render: &Renderer,
146 ) {
147 let wgpu = render.wgpu;
148
149 let verts = vertex::from_pixels_with_rotation(position, size, colour.as_raw(), rotation);
150
151 self.push_rectangle(wgpu, verts);
152 }
153
154 #[allow(clippy::too_many_arguments)]
155 pub fn add_rectangle_ex(
157 &mut self,
158 position: Vec2<f32>,
159 size: Vec2<f32>,
160 colour: Colour,
161 rotation: f32,
162 uv_position: Vec2<f32>,
163 uv_size: Vec2<f32>,
164 render: &Renderer,
165 ) {
166 let wgpu = render.wgpu;
167
168 let texture_size = render.resources.get_texture(&self.texture_id).unwrap().size;
169
170 let uv_size = normalize_points(uv_size, texture_size);
171 let uv_position = normalize_points(uv_position, texture_size);
172
173 let verts = vertex::from_pixels_ex(
174 position,
175 size,
176 colour.as_raw(),
177 rotation,
178 uv_position,
179 uv_size,
180 );
181
182 self.push_rectangle(wgpu, verts);
183 }
184
185 #[allow(clippy::too_many_arguments)]
186 pub fn add_screenspace_rectangle_ex(
188 &mut self,
189 position: Vec2<f32>,
190 size: Vec2<f32>,
191 colour: Colour,
192 rotation: f32,
193 uv_position: Vec2<f32>,
194 uv_size: Vec2<f32>,
195 render: &Renderer,
196 ) {
197 let wgpu = render.wgpu;
198
199 let verts = vertex::new_ex(
200 position,
201 size,
202 colour.as_raw(),
203 rotation,
204 uv_position,
205 uv_size,
206 );
207
208 self.push_rectangle(wgpu, verts);
209 }
210
211 pub fn add_custom(
214 &mut self,
215 points: [Vec2<f32>; 4],
216 uv_points: [Vec2<f32>; 4],
217 rotation: f32,
218 colour: Colour,
219 render: &Renderer,
220 ) {
221 let wgpu = render.wgpu;
222 let texture_size = render.resources.get_texture(&self.texture_id).unwrap().size;
223 let uv_points = [
224 normalize_points(uv_points[0], texture_size),
225 normalize_points(uv_points[1], texture_size),
226 normalize_points(uv_points[2], texture_size),
227 normalize_points(uv_points[3], texture_size),
228 ];
229
230 let verts = vertex::from_pixels_custom(points, uv_points, rotation, colour.as_raw());
231
232 self.push_rectangle(wgpu, verts);
233 }
234
235 pub fn add_triangle(
237 &mut self,
238 p1: Vec2<f32>,
239 p2: Vec2<f32>,
240 p3: Vec2<f32>,
241 colour: Colour,
242 render: &Renderer,
243 ) {
244 let wgpu = render.wgpu;
245
246 let colour = colour.as_raw();
247 let tex_coords = [0.0, 0.0];
248
249 let verts = [
250 Vertex::from_2d([p1.x, p1.y], tex_coords, colour),
251 Vertex::from_2d([p2.x, p2.y], tex_coords, colour),
252 Vertex::from_2d([p3.x, p3.y], tex_coords, colour),
253 ];
254
255 self.push_triangle(wgpu, verts);
256 }
257
258 pub fn add_triangle_with_coloured_verticies(
261 &mut self,
262 points: [Vec2<f32>; 3],
263 colours: [Colour; 3],
264 render: &Renderer,
265 ) {
266 let wgpu = render.wgpu;
267
268 let tex_coords = [0.0, 0.0];
269 let verts = [
270 Vertex::from_2d([points[0].x, points[0].y], tex_coords, colours[0].as_raw()),
271 Vertex::from_2d([points[1].x, points[1].y], tex_coords, colours[1].as_raw()),
272 Vertex::from_2d([points[2].x, points[2].y], tex_coords, colours[2].as_raw()),
273 ];
274
275 self.push_triangle(wgpu, verts);
276 }
277
278 pub fn add_regular_n_gon(
281 &mut self,
282 number_of_sides: usize,
283 radius: f32,
284 center: Vec2<f32>,
285 colour: Colour,
286 render: &Renderer,
287 ) {
288 if number_of_sides < 4 {
289 return;
290 }
291
292 if self.inner.is_none() {
293 let (vert, ind) = Self::create_buffers(
294 &render.wgpu.device,
295 self.vertex_size,
296 50,
297 self.index_size,
298 50,
299 );
300
301 self.inner = Some(InnerBuffer {
302 vertex_buffer: vert,
303 index_buffer: ind,
304 });
305 }
306
307 let wgpu = render.wgpu;
308
309 let vertices = (0..number_of_sides)
310 .map(|num| Vec2 {
311 x: radius * (2.0 * PI * num as f32 / number_of_sides as f32).cos() + center.x,
312 y: radius * (2.0 * PI * num as f32 / number_of_sides as f32).sin() + center.y,
313 })
314 .map(|point| Vertex::from_2d([point.x, point.y], [0.0, 0.0], colour.as_raw()))
315 .collect::<Vec<Vertex>>();
316
317 let number_of_vertices = self.get_vertex_number() as u16;
318 let number_of_triangles = (number_of_sides - 2) as u16;
319
320 let mut indicies = (1..number_of_triangles + 1)
321 .flat_map(|i| {
322 [
323 number_of_vertices,
324 i + number_of_vertices,
325 i + 1 + number_of_vertices,
326 ]
327 })
328 .collect::<Vec<u16>>();
329
330 let num_indicies = indicies.len();
332 let triangles_to_add = if num_indicies < 12 {
333 (12 % num_indicies) / 3
334 } else {
335 (num_indicies % 12) / 3
336 };
337
338 for _ in 0..triangles_to_add {
339 indicies.extend_from_slice(&[
340 indicies[num_indicies - 3],
341 indicies[num_indicies - 2],
342 indicies[num_indicies - 1],
343 ]);
344 }
345
346 let buffers = self.inner.as_mut().unwrap();
347
348 let max_verts = buffers.vertex_buffer.size();
349 if self.vertex_count + (vertices.len() as u64 * self.vertex_size) > max_verts {
350 grow_buffer(
351 &mut buffers.vertex_buffer,
352 wgpu,
353 self.vertex_count + (vertices.len() as u64 * self.vertex_size),
354 wgpu::BufferUsages::VERTEX,
355 );
356 }
357
358 let max_indicies = buffers.index_buffer.size();
359 if self.index_count + (indicies.len() as u64 * self.index_size) > max_indicies {
360 grow_buffer(
361 &mut buffers.index_buffer,
362 wgpu,
363 self.index_count + (indicies.len() as u64 * self.index_size),
364 wgpu::BufferUsages::INDEX,
365 );
366 }
367
368 wgpu.queue.write_buffer(
369 &buffers.vertex_buffer,
370 self.vertex_count,
371 bytemuck::cast_slice(&vertices),
372 );
373 wgpu.queue.write_buffer(
374 &buffers.index_buffer,
375 self.index_count,
376 bytemuck::cast_slice(&indicies),
377 );
378
379 self.vertex_count += vertices.len() as u64 * self.vertex_size;
380 self.index_count += indicies.len() as u64 * self.index_size;
381 }
382
383 pub fn resize_uniform_texture(
387 &mut self,
388 texture: &mut UniformTexture,
389 size: Vec2<u32>,
390 engine: &mut Engine,
391 ) -> Result<(), UniformError> {
392 let context = match &engine.context {
393 Some(c) => c,
394 None => return Ok(()),
395 };
399
400 let texture_format = context.get_texture_format();
401
402 let options = match engine.resource_manager.get_mut_shader(&self.pipeline_id) {
403 Some(shader) => shader,
404 None => Err(UniformError::NotLoadedYet)?,
405 };
406
407 texture.resize(size, &context.wgpu, texture_format);
408
409 options.update_uniform_texture(texture, &context.wgpu, texture_format)?;
410
411 Ok(())
412 }
413
414 pub fn update_uniform_texture(
415 &mut self,
416 texture: &mut UniformTexture,
417 engine: &mut Engine,
418 ) -> Result<(), UniformError> {
419 let context = match &engine.context {
420 Some(c) => c,
421 None => return Ok(()),
422 };
426
427 let texture_format = context.get_texture_format();
428
429 let options = match engine.resource_manager.get_mut_shader(&self.pipeline_id) {
430 Some(shader) => shader,
431 None => Err(UniformError::NotLoadedYet)?,
432 };
433
434 options.update_uniform_texture(texture, &context.wgpu, texture_format)?;
435
436 Ok(())
437 }
438
439 pub fn get_vertex_number(&self) -> u64 {
441 self.vertex_count / self.vertex_size
442 }
443
444 pub fn get_index_number(&self) -> u64 {
446 self.index_count / self.index_size
447 }
448
449 pub fn get_texture_size(&self, engine: &Engine) -> Option<Vec2<f32>> {
452 engine
453 .resource_manager
454 .get_texture(&self.texture_id)
455 .map(|t| t.size)
456 }
457
458 fn push_rectangle(&mut self, wgpu: &WgpuClump, verts: [Vertex; 4]) {
459 if self.inner.is_none() {
460 let (vert, ind) =
461 Self::create_buffers(&wgpu.device, self.vertex_size, 50, self.index_size, 50);
462 self.inner = Some(InnerBuffer {
463 vertex_buffer: vert,
464 index_buffer: ind,
465 });
466 }
467
468 let num_verts = self.get_vertex_number() as u16;
469 let buffers = self.inner.as_mut().unwrap();
470
471 let max_verts = buffers.vertex_buffer.size();
472 if self.vertex_count + (4 * self.vertex_size) > max_verts {
473 grow_buffer(
474 &mut buffers.vertex_buffer,
475 wgpu,
476 1,
477 wgpu::BufferUsages::VERTEX,
478 );
479 }
480
481 let indicies = [
482 num_verts,
483 1 + num_verts,
484 2 + num_verts,
485 3 + num_verts,
486 num_verts,
487 2 + num_verts,
488 ];
489
490 let max_indicies = buffers.index_buffer.size();
491 if self.index_count + (6 * self.index_size) > max_indicies {
492 grow_buffer(
493 &mut buffers.index_buffer,
494 wgpu,
495 1,
496 wgpu::BufferUsages::INDEX,
497 );
498 }
499
500 wgpu.queue.write_buffer(
501 &buffers.vertex_buffer,
502 self.vertex_count,
503 bytemuck::cast_slice(&verts),
504 );
505 wgpu.queue.write_buffer(
506 &buffers.index_buffer,
507 self.index_count,
508 bytemuck::cast_slice(&indicies),
509 );
510
511 self.vertex_count += 4 * self.vertex_size;
512 self.index_count += 6 * self.index_size;
513 }
514
515 fn push_triangle(&mut self, wgpu: &WgpuClump, verts: [Vertex; 3]) {
516 if self.inner.is_none() {
517 let (vert, ind) =
518 Self::create_buffers(&wgpu.device, self.vertex_size, 50, self.index_size, 50);
519 self.inner = Some(InnerBuffer {
520 vertex_buffer: vert,
521 index_buffer: ind,
522 });
523 }
524
525 let num_verts = self.get_vertex_number() as u16;
526 let buffers = self.inner.as_mut().unwrap();
527
528 let max_verts = buffers.vertex_buffer.size();
529 if self.vertex_count + (3 * self.vertex_size) > max_verts {
530 grow_buffer(
531 &mut buffers.vertex_buffer,
532 wgpu,
533 1,
534 wgpu::BufferUsages::VERTEX,
535 );
536 }
537
538 let indicies = [
541 num_verts,
542 1 + num_verts,
543 2 + num_verts,
544 num_verts,
545 1 + num_verts,
546 2 + num_verts,
547 ];
548
549 let max_indicies = buffers.index_buffer.size();
550 if self.index_count + (6 * self.index_size) > max_indicies {
551 grow_buffer(
552 &mut buffers.index_buffer,
553 wgpu,
554 1,
555 wgpu::BufferUsages::INDEX,
556 );
557 }
558
559 wgpu.queue.write_buffer(
560 &buffers.vertex_buffer,
561 self.vertex_count,
562 bytemuck::cast_slice(&verts),
563 );
564 wgpu.queue.write_buffer(
565 &buffers.index_buffer,
566 self.index_count,
567 bytemuck::cast_slice(&indicies),
568 );
569
570 self.vertex_count += 3 * self.vertex_size;
571 self.index_count += 6 * self.index_size;
572 }
573
574 pub fn draw<'others>(&'others mut self, information: &mut Renderer<'_, 'others>) {
577 if self.vertex_count == 0 {
578 return;
579 }
580
581 let Some(shader) = information.resources.get_pipeline(&self.pipeline_id) else {
583 return;
584 };
585
586 let Some(texture) = information
587 .resources
588 .get_texture(&self.texture_id)
589 .map(|t| &t.bind_group)
590 else {
591 return;
592 };
593 let buffers = self.inner.as_ref().unwrap();
596
597 shader.set_active(information);
598
599 information.pass.set_bind_group(0, texture, &[]);
600
601 information
602 .pass
603 .set_vertex_buffer(0, buffers.vertex_buffer.slice(0..self.vertex_count));
604 information.pass.set_index_buffer(
605 buffers.index_buffer.slice(0..self.index_count),
606 wgpu::IndexFormat::Uint16,
607 );
608
609 information
610 .pass
611 .draw_indexed(0..self.get_index_number() as u32, 0, 0..1);
612
613 self.vertex_count = 0;
614 self.index_count = 0;
615 }
616
617 pub(crate) fn create_buffers(
618 device: &wgpu::Device,
619 vertex_size: u64,
620 vert_count: u64,
621 index_size: u64,
622 index_count: u64,
623 ) -> (wgpu::Buffer, wgpu::Buffer) {
624 let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
625 label: Some("Vertex_Buffer"),
626 size: vertex_size * vert_count,
627 usage: wgpu::BufferUsages::VERTEX
628 | wgpu::BufferUsages::COPY_DST
629 | wgpu::BufferUsages::COPY_SRC,
630 mapped_at_creation: false,
631 });
632
633 let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
635 label: Some("Index_Buffer"),
636 size: index_size * index_count,
637 usage: wgpu::BufferUsages::INDEX
638 | wgpu::BufferUsages::COPY_DST
639 | wgpu::BufferUsages::COPY_SRC,
640 mapped_at_creation: false,
641 });
642
643 (vertex_buffer, index_buffer)
644 }
645}
646
647impl<T: ShaderType + WriteInto> Material<T> {
648 pub fn update_uniform_data(&self, data: &T, engine: &Engine) -> Result<(), UniformError> {
652 let options = match engine.resource_manager.get_pipeline(&self.pipeline_id) {
653 Some(shader) => shader,
654 None => return Err(UniformError::NotLoadedYet),
655 };
656
657 options.update_uniform_data(data, engine)?;
658
659 Ok(())
660 }
661}
662
663pub struct MaterialBuilder<T> {
665 texture_change: Option<ResourceId<Texture>>,
668 shader_change: Option<ResourceId<Shader>>,
669 _marker: PhantomData<T>,
670}
671
672impl<T> MaterialBuilder<T> {
673 pub fn new() -> Self {
676 Self {
677 texture_change: None,
678 shader_change: None,
679 _marker: PhantomData,
680 }
681 }
682
683 pub fn add_texture(self, texture: ResourceId<Texture>) -> Self {
685 Self {
686 texture_change: Some(texture),
687 shader_change: self.shader_change,
688 _marker: PhantomData,
689 }
690 }
691
692 pub fn set_shader(self, shader: ResourceId<Shader>) -> Self {
694 Self {
695 texture_change: self.texture_change,
696 shader_change: Some(shader),
697 _marker: PhantomData,
698 }
699 }
700
701 pub fn add_uniform_data<H: ShaderType + WriteInto>(
703 self,
704 _data: &UniformData<H>,
705 ) -> MaterialBuilder<H> {
706 MaterialBuilder {
707 texture_change: self.texture_change,
708 shader_change: self.shader_change,
709 _marker: PhantomData,
710 }
711 }
712
713 pub fn build(self, engine_handle: &mut Engine) -> Material<T> {
715 Material::from_builder(self, engine_handle)
716 }
717}
718
719impl<T> Default for MaterialBuilder<T> {
720 fn default() -> Self {
721 Self::new()
722 }
723}
724
725pub struct LineMaterial {
729 pipe_id: ResourceId<Shader>,
730 vertex_buffer: Option<wgpu::Buffer>,
731 vertex_count: u64,
732 vertex_size: u64,
733}
734
735impl LineMaterial {
736 pub fn new(engine: &Engine) -> Self {
738 let vertex_size = std::mem::size_of::<LineVertex>() as u64;
739
740 Self {
741 pipe_id: engine.line_pipe_id(),
742 vertex_buffer: None,
743 vertex_count: 0,
744 vertex_size,
745 }
746 }
747
748 pub fn add_line(
750 &mut self,
751 start: Vec2<f32>,
752 end: Vec2<f32>,
753 colour: Colour,
754 renderer: &Renderer,
755 ) {
756 let wgpu = renderer.wgpu;
757 if self.vertex_buffer.is_none() {
758 self.vertex_buffer = Some(wgpu.device.create_buffer(&wgpu::BufferDescriptor {
759 label: Some("Line material vertex buffer"),
760 usage: wgpu::BufferUsages::VERTEX
761 | wgpu::BufferUsages::COPY_DST
762 | wgpu::BufferUsages::COPY_SRC,
763 size: self.vertex_size * 100,
764 mapped_at_creation: false,
765 }));
766 }
767
768 let verts = [
769 LineVertex::new(start.to_raw(), colour.as_raw()),
770 LineVertex::new(end.to_raw(), colour.as_raw()),
771 ];
772
773 let vertex_buffer = self.vertex_buffer.as_mut().unwrap();
774
775 let max_verts = vertex_buffer.size();
776 let vert_size = std::mem::size_of::<LineVertex>() as u64;
777 if self.vertex_count + (2 * vert_size) > max_verts {
778 grow_buffer(vertex_buffer, wgpu, 1, wgpu::BufferUsages::VERTEX);
779 }
780
781 wgpu.queue.write_buffer(
782 vertex_buffer,
783 self.vertex_count,
784 bytemuck::cast_slice(&verts),
785 );
786
787 self.vertex_count += 2 * self.vertex_size;
788 }
789
790 pub fn add_screenspace_line(
791 &mut self,
792 start: Vec2<f32>,
793 end: Vec2<f32>,
794 colour: Colour,
795 renderer: &Renderer,
796 ) {
797 let wgpu = renderer.wgpu;
798 let size = renderer.size;
799
800 if self.vertex_buffer.is_none() {
801 self.vertex_buffer = Some(wgpu.device.create_buffer(&wgpu::BufferDescriptor {
802 label: Some("Line material vertex buffer"),
803 usage: wgpu::BufferUsages::VERTEX
804 | wgpu::BufferUsages::COPY_DST
805 | wgpu::BufferUsages::COPY_SRC,
806 size: self.vertex_size * 100,
807 mapped_at_creation: false,
808 }));
809 }
810
811 let verts = [
812 LineVertex::new(start.to_raw(), colour.as_raw()).screenspace_to_pixels(size),
813 LineVertex::new(end.to_raw(), colour.as_raw()).screenspace_to_pixels(size),
814 ];
815
816 let vertex_buffer = self.vertex_buffer.as_mut().unwrap();
817
818 let max_verts = vertex_buffer.size();
819 let vert_size = std::mem::size_of::<LineVertex>() as u64;
820 if self.vertex_count + (2 * vert_size) > max_verts {
821 grow_buffer(vertex_buffer, wgpu, 1, wgpu::BufferUsages::VERTEX);
822 }
823
824 wgpu.queue.write_buffer(
825 vertex_buffer,
826 self.vertex_count,
827 bytemuck::cast_slice(&verts),
828 );
829
830 self.vertex_count += 2 * self.vertex_size;
831 }
832
833 pub fn draw<'others>(&'others mut self, information: &mut Renderer<'_, 'others>) {
835 if self.vertex_count == 0 {
836 return;
837 }
838
839 let Some(pipeline) = information
840 .resources
841 .get_pipeline(&self.pipe_id)
842 .map(|p| &p.pipeline)
843 else {
844 return;
845 };
846
847 let buffer = self.vertex_buffer.as_ref().unwrap();
848
849 information.pass.set_pipeline(pipeline);
850 information
851 .pass
852 .set_bind_group(0, information.camera_bindgroup, &[]);
853 information
854 .pass
855 .set_vertex_buffer(0, buffer.slice(0..self.vertex_count));
856
857 information
858 .pass
859 .draw(0..self.get_vertex_count() as u32, 0..1);
860
861 self.vertex_count = 0;
862 }
863
864 pub fn get_vertex_count(&self) -> u64 {
865 self.vertex_count / self.vertex_size
866 }
867}
868
869pub(crate) fn grow_buffer(
870 buffer: &mut wgpu::Buffer,
871 wgpu: &WgpuClump,
872 size_needed: u64,
873 vert_or_index: wgpu::BufferUsages,
874) {
875 let mut encoder = wgpu
876 .device
877 .create_command_encoder(&wgpu::CommandEncoderDescriptor {
878 label: Some("Material Buffer Grower"),
879 });
880
881 let size_needed = size_needed + (4 - (size_needed % wgpu::COPY_BUFFER_ALIGNMENT));
882
883 let new_size = std::cmp::max(buffer.size() * 2, size_needed);
884 let new_buffer = wgpu.device.create_buffer(&wgpu::BufferDescriptor {
885 label: Some("Vertex_Buffer"),
886 size: new_size,
887 usage: vert_or_index | wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::COPY_SRC,
888 mapped_at_creation: false,
889 });
890
891 encoder.copy_buffer_to_buffer(buffer, 0, &new_buffer, 0, buffer.size());
892
893 wgpu.queue.submit(std::iter::once(encoder.finish()));
894
895 *buffer = new_buffer;
896}
897
898#[derive(Debug)]
899struct InnerBuffer {
900 vertex_buffer: wgpu::Buffer,
901 index_buffer: wgpu::Buffer,
902}