1use crate::header::{
8 glm, pixel_to_cartesian, uniform_type, Instance, InstanceRaw, Object, ObjectSettings, Pipeline,
9 PipelineData, Renderer, RotateAxis, TextureData, Textures, Vertex,
10};
11use crate::uniform_type::{Array4, Matrix};
12use crate::utils::default_resources::{DEFAULT_MATRIX_4, DEFAULT_SHADER, DEFAULT_TEXTURE};
13use crate::{ObjectStorage, RotateAmount, StringBuffer, UnsignedIntType, Vector3};
14
15impl Renderer {
16 pub fn build_object(
27 &mut self,
28 name: impl StringBuffer,
29 vertices: Vec<Vertex>,
30 indices: Vec<UnsignedIntType>,
31 settings: ObjectSettings,
32 ) -> Result<Object, crate::error::Error> {
33 let vertex_buffer = self.build_vertex_buffer(&vertices, &indices);
34
35 let uniform = self.build_uniform_buffer(&vec![
36 self.build_uniform_buffer_part("Transformation Matrix", DEFAULT_MATRIX_4),
37 self.build_uniform_buffer_part(
38 "Color",
39 crate::uniform_type::Array4 {
40 data: crate::utils::default_resources::DEFAULT_COLOR,
41 },
42 ),
43 ]);
44
45 let shader_source =
46 ShaderBuilder::new(DEFAULT_SHADER.to_string(), settings.camera_effect.clone());
47
48 let shader = self.build_shader(
49 name.as_str(),
50 shader_source.shader.clone(),
51 Some(&uniform.1),
52 settings.shader_settings,
53 );
54
55 let texture = self.build_texture(
56 "Default Texture",
57 TextureData::Bytes(DEFAULT_TEXTURE.to_vec()),
58 crate::header::TextureMode::Clamp,
59 )?;
61
62 let instance = Instance::new([0f32, 0f32, 0f32], [0f32, 0f32, 0f32], [1f32, 1f32, 1f32]);
63
64 let instance_buffer = self.build_instance(vec![instance.to_raw()]);
65
66 Ok(Object {
67 name: name.as_arc(),
68 vertices,
69 indices,
70 pipeline: Pipeline {
71 vertex_buffer: PipelineData::Data(vertex_buffer),
72 shader: PipelineData::Data(shader),
73 texture: PipelineData::Data(texture),
74 uniform: PipelineData::Data(Some(uniform.0)),
75 },
76 instances: vec![instance],
77 instance_buffer,
78 uniform_layout: uniform.1,
79 size: Vector3::new(1f32, 1f32, 1f32),
80 position: Vector3::default(),
81 rotation: Vector3::new(0f32, 0f32, 0f32),
82 changed: false,
83 position_matrix: DEFAULT_MATRIX_4.to_im(),
84 scale_matrix: DEFAULT_MATRIX_4.to_im(),
85 rotation_matrix: DEFAULT_MATRIX_4.to_im(),
86 inverse_transformation_matrix: Matrix::from_im(nalgebra_glm::transpose(
87 &nalgebra_glm::inverse(&DEFAULT_MATRIX_4.to_im()),
88 )),
89 color: crate::uniform_type::Array4 {
90 data: crate::utils::default_resources::DEFAULT_COLOR,
91 },
92 shader_builder: shader_source,
93 shader_settings: settings.shader_settings,
94 camera_effect: settings.camera_effect,
95 uniform_buffers: vec![
96 self.build_uniform_buffer_part("Transformation Matrix", DEFAULT_MATRIX_4),
97 self.build_uniform_buffer_part(
98 "Color",
99 crate::uniform_type::Array4 {
100 data: crate::utils::default_resources::DEFAULT_COLOR,
101 },
102 ),
103 ],
104 is_visible: true,
105 render_order: 0,
106 })
107 }
108}
109
110impl ObjectStorage {
111 pub fn new_object(
113 &mut self,
114 name: impl StringBuffer,
115 vertices: Vec<Vertex>,
116 indices: Vec<UnsignedIntType>,
117 settings: ObjectSettings,
118 renderer: &mut Renderer,
119 ) {
120 match renderer.build_object(name.clone(), vertices, indices, settings) {
121 Ok(object) => self.add_object(name.clone(), object),
122 Err(e) => {
123 eprintln!("Could not create a new Object: {e:#?}");
124 }
125 }
126 }
127
128 pub fn add_object(&mut self, key: impl StringBuffer, object: Object) {
130 fn add_object_inner(object_storage: &mut ObjectStorage, key: String, object: Object) {
131 object_storage.insert(key, object);
132 }
133 add_object_inner(self, key.as_string(), object);
134 }
135
136 pub fn update_object<T: Fn(&mut Object)>(&mut self, key: impl StringBuffer, callback: T) {
138 fn update_object_inner<T: Fn(&mut Object)>(
139 object_storage: &mut ObjectStorage,
140 key: String,
141 callback: T,
142 ) {
143 let object = object_storage.get_mut(&key);
144 if let Some(object) = object {
145 callback(object);
146 }
147 }
148 update_object_inner(self, key.as_string(), callback);
149 }
150}
151
152impl Object {
153 pub fn set_name(&mut self, name: impl StringBuffer) -> &mut Self {
155 self.name = name.as_arc();
156
157 self
158 }
159
160 pub fn set_scale(&mut self, scale: impl Into<Vector3>) -> &mut Self {
162 let scale = scale.into();
163 self.size *= scale;
164
165 let transformation_matrix = self.scale_matrix;
166 let result = nalgebra_glm::scale(&transformation_matrix, &scale.into());
167 self.scale_matrix = result;
168 self.inverse_matrices();
169
170 self.changed = true;
171 self
172 }
173
174 pub fn resize(
176 &mut self,
177 width: f32,
178 height: f32,
179 depth: f32,
180 window_size: winit::dpi::PhysicalSize<u32>,
181 ) -> &mut Self {
182 let difference_in_width = if self.size.x != 0.0 && width != 0.0 {
183 let a = pixel_to_cartesian(width, window_size.width);
184 let b = pixel_to_cartesian(self.size.x, window_size.width);
185 if a != 0f32 && b != 0f32 {
186 a / b
187 } else {
188 b
189 }
190 } else {
191 0.0
192 };
193
194 let difference_in_height = if self.size.y != 0.0 && height != 0.0 {
195 let a = pixel_to_cartesian(height, window_size.height);
196 let b = pixel_to_cartesian(self.size.y, window_size.height);
197 if a != 0f32 && b != 0f32 {
198 a / b
199 } else {
200 b
201 }
202 } else {
203 0.0
204 };
205 let difference_in_depth = if self.size.z != 0.0 && depth != 0.0 {
206 let a = pixel_to_cartesian(depth, window_size.width);
207 let b = pixel_to_cartesian(self.size.z, window_size.width);
208 if a != 0f32 && b != 0f32 {
209 a / b
210 } else {
211 b
212 }
213 } else {
214 0.0
215 };
216
217 self.set_scale(Vector3::new(
218 difference_in_width,
219 difference_in_height,
220 difference_in_depth,
221 ));
222 self
223 }
224
225 #[deprecated]
229 pub fn set_rotatation(&mut self, angle: f32, axis: RotateAxis) -> &mut Self {
230 let mut rotation_matrix = self.rotation_matrix;
231 let axis = match axis {
232 RotateAxis::X => {
233 self.rotation.x += angle;
234 Vector3::x_axis()
235 }
236 RotateAxis::Y => {
237 self.rotation.y += angle;
238 Vector3::y_axis()
239 }
240 RotateAxis::Z => {
241 self.rotation.z += angle;
242 Vector3::z_axis()
243 }
244 };
245
246 rotation_matrix = nalgebra_glm::rotate(&rotation_matrix, angle.to_radians(), &axis.into());
247 self.rotation_matrix = rotation_matrix;
248 self.inverse_matrices();
249
250 self.changed = true;
251 self
252 }
253
254 pub fn set_rotation(&mut self, amount: RotateAmount, axis: RotateAxis) -> &mut Self {
256 let mut rotation_matrix = self.rotation_matrix;
257
258 let amount_radians = match amount {
259 RotateAmount::Radians(amount) => amount,
260 RotateAmount::Degrees(amount) => amount.to_radians(),
261 };
262 let axis = match axis {
263 RotateAxis::X => {
264 self.rotation.x = amount_radians;
265 Vector3::x_axis()
266 }
267 RotateAxis::Y => {
268 self.rotation.y = amount_radians;
269 Vector3::y_axis()
270 }
271 RotateAxis::Z => {
272 self.rotation.z = amount_radians;
273 Vector3::z_axis()
274 }
275 };
276
277 rotation_matrix = nalgebra_glm::rotate(&rotation_matrix, amount_radians, &axis.into());
278 self.rotation_matrix = rotation_matrix;
279 self.inverse_matrices();
280
281 self.changed = true;
282 self
283 }
284
285 pub fn rotate(&mut self, amount: RotateAmount, axis: RotateAxis) -> &mut Self {
287 let mut rotation_matrix = self.rotation_matrix;
288
289 let amount_radians = match amount {
290 RotateAmount::Radians(amount) => amount,
291 RotateAmount::Degrees(amount) => amount.to_radians(),
292 };
293 let axis = match axis {
294 RotateAxis::X => {
295 self.rotation.x += amount_radians;
296 Vector3::x_axis()
297 }
298 RotateAxis::Y => {
299 self.rotation.y += amount_radians;
300 Vector3::y_axis()
301 }
302 RotateAxis::Z => {
303 self.rotation.z += amount_radians;
304 Vector3::z_axis()
305 }
306 };
307
308 rotation_matrix = nalgebra_glm::rotate(&rotation_matrix, amount_radians, &axis.into());
309 self.rotation_matrix = rotation_matrix;
310 self.inverse_matrices();
311
312 self.changed = true;
313 self
314 }
315
316 pub fn set_translation(&mut self, new_pos: impl Into<Vector3>) -> &mut Self {
318 self.position -= new_pos.into();
319
320 let mut position_matrix = self.position_matrix;
321 position_matrix = nalgebra_glm::translate(&position_matrix, &self.position.into());
322 self.position_matrix = position_matrix;
323
324 self.inverse_matrices();
325 self.changed = true;
326 self
327 }
328
329 pub fn set_position(&mut self, new_pos: impl Into<Vector3>) -> &mut Self {
331 let new_pos = new_pos.into();
332 self.set_translation((self.position - new_pos) * -1f32);
333
334 self.position.x = new_pos.x;
335 self.position.y = new_pos.y;
336 self.position.z = new_pos.z;
337 self
338 }
339
340 pub fn set_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) -> &mut Self {
342 self.color = Array4 {
343 data: [red, green, blue, alpha],
344 };
345 self.changed = true;
346 self
347 }
348
349 pub fn set_render_order(&mut self, render_order: usize) -> &mut Self {
353 self.render_order = render_order;
354
355 self
356 }
357
358 pub fn set_texture(&mut self, texture: Textures) -> &mut Self {
360 self.pipeline.texture = PipelineData::Data(texture);
361 self.changed = true;
362
363 self
364 }
365
366 pub fn flag_as_changed(&mut self, is_changed: bool) {
370 self.changed = is_changed;
371 }
372
373 pub fn set_visibility(&mut self, is_visible: bool) {
375 self.is_visible = is_visible;
376 }
377
378 pub fn inverse_matrices(&mut self) {
380 self.inverse_transformation_matrix =
381 Matrix::from_im(nalgebra_glm::transpose(&nalgebra_glm::inverse(
382 &(self.position_matrix * self.rotation_matrix * self.scale_matrix),
383 )));
384 }
385
386 pub fn update(&mut self, renderer: &mut Renderer) {
388 self.update_vertex_buffer(renderer);
389 self.update_uniform_buffer(renderer);
390 self.update_shader(renderer);
391 self.update_instance_buffer(renderer);
392 self.changed = false;
393 }
394
395 pub fn update_and_return(
397 &mut self,
398 renderer: &mut Renderer,
399 ) -> (crate::VertexBuffers, crate::UniformBuffers, crate::Shaders) {
400 let vertex_buffer = self.update_vertex_buffer_and_return(renderer);
401 let uniform_buffer = self.update_uniform_buffer_and_return(renderer);
402 let shader = self.update_shader_and_return(renderer);
403 self.changed = false;
404 (vertex_buffer, uniform_buffer, shader)
405 }
406
407 pub fn update_vertex_buffer(&mut self, renderer: &mut Renderer) {
409 let updated_buffer = renderer.build_vertex_buffer(&self.vertices, &self.indices);
410 self.pipeline.vertex_buffer = PipelineData::Data(updated_buffer);
411 }
412
413 pub fn update_vertex_buffer_and_return(
415 &mut self,
416 renderer: &mut Renderer,
417 ) -> crate::VertexBuffers {
418 let updated_buffer = renderer.build_vertex_buffer(&self.vertices, &self.indices);
419 let updated_buffer_2 = renderer.build_vertex_buffer(&self.vertices, &self.indices);
420 self.pipeline.vertex_buffer = PipelineData::Data(updated_buffer);
421
422 updated_buffer_2
423 }
424
425 pub fn update_shader(&mut self, renderer: &mut Renderer) {
427 let updated_shader = renderer.build_shader(
428 self.name.as_ref(),
429 self.shader_builder.shader.clone(),
430 Some(&self.uniform_layout),
431 self.shader_settings,
432 );
433 self.pipeline.shader = PipelineData::Data(updated_shader);
434 }
435
436 pub fn update_shader_and_return(&mut self, renderer: &mut Renderer) -> crate::Shaders {
438 let updated_shader = renderer.build_shader(
439 self.name.as_ref(),
440 self.shader_builder.shader.clone(),
441 Some(&self.uniform_layout),
442 self.shader_settings,
443 );
444 let updated_shader2 = renderer.build_shader(
445 self.name.as_ref(),
446 self.shader_builder.shader.clone(),
447 Some(&self.uniform_layout),
448 self.shader_settings,
449 );
450 self.pipeline.shader = PipelineData::Data(updated_shader);
451
452 updated_shader2
453 }
454
455 pub fn update_uniform_buffer(&mut self, renderer: &mut Renderer) {
457 self.uniform_buffers[0] = renderer.build_uniform_buffer_part(
458 "Transformation Matrix",
459 uniform_type::Matrix::from_im(
460 self.position_matrix * self.rotation_matrix * self.scale_matrix,
461 ),
462 );
463 self.uniform_buffers[1] = renderer.build_uniform_buffer_part("Color", self.color);
464
465 let updated_buffer = renderer.build_uniform_buffer(&self.uniform_buffers);
466
467 self.pipeline.uniform = PipelineData::Data(Some(updated_buffer.0));
468 self.uniform_layout = updated_buffer.1;
469 }
470
471 pub fn update_uniform_buffer_and_return(
473 &mut self,
474 renderer: &mut Renderer,
475 ) -> crate::UniformBuffers {
476 self.uniform_buffers[0] = renderer.build_uniform_buffer_part(
477 "Transformation Matrix",
478 uniform_type::Matrix::from_im(
479 self.position_matrix * self.rotation_matrix * self.scale_matrix,
480 ),
481 );
482 self.uniform_buffers[1] = renderer.build_uniform_buffer_part("Color", self.color);
483
484 let updated_buffer = renderer.build_uniform_buffer(&self.uniform_buffers);
485 let updated_buffer2 = renderer.build_uniform_buffer(&self.uniform_buffers);
486
487 self.pipeline.uniform = PipelineData::Data(Some(updated_buffer.0));
488 self.uniform_layout = updated_buffer.1;
489
490 updated_buffer2.0
491 }
492
493 pub fn update_instance_buffer(&mut self, renderer: &mut Renderer) {
495 let instance_data = self
496 .instances
497 .iter()
498 .map(Instance::to_raw)
499 .collect::<Vec<_>>();
500 let instance_buffer = renderer.build_instance(instance_data);
501 self.instance_buffer = instance_buffer;
502 }
503
504 pub fn update_instance_buffer_and_return(&mut self, renderer: &mut Renderer) -> wgpu::Buffer {
506 let instance_data = self
507 .instances
508 .iter()
509 .map(Instance::to_raw)
510 .collect::<Vec<_>>();
511 let instance_buffer = renderer.build_instance(instance_data.clone());
512 let instance_buffer2 = renderer.build_instance(instance_data);
513
514 self.instance_buffer = instance_buffer;
515 instance_buffer2
516 }
517
518 pub fn reference_vertices(&mut self, object_id: impl StringBuffer) -> &mut Self {
521 self.pipeline.vertex_buffer = PipelineData::Copy(object_id.as_string());
522 self
523 }
524
525 pub fn reference_shader(&mut self, object_id: impl StringBuffer) -> &mut Self {
527 self.pipeline.shader = PipelineData::Copy(object_id.as_string());
528 self
529 }
530
531 pub fn reference_texture(&mut self, object_id: impl StringBuffer) -> &mut Self {
533 self.pipeline.texture = PipelineData::Copy(object_id.as_string());
534 self
535 }
536
537 pub fn reference_uniform_buffer(&mut self, object_id: impl StringBuffer) -> &mut Self {
539 self.pipeline.uniform = PipelineData::Copy(object_id.as_string());
540 self
541 }
542
543 pub fn add_instance(&mut self, instance: Instance) -> &mut Self {
546 self.instances.push(instance);
547 self.changed = true;
548 self
549 }
550}
551
552pub type ShaderConfigs = Vec<(String, Box<dyn Fn(Option<std::sync::Arc<str>>) -> String>)>;
554
555pub struct ShaderBuilder {
557 pub shader: String,
559 pub camera_effect: Option<std::sync::Arc<str>>,
561 pub configs: ShaderConfigs,
563}
564
565impl ShaderBuilder {
566 pub fn new(shader_source: String, camera_effect: Option<std::sync::Arc<str>>) -> Self {
568 let mut shader_builder = Self {
569 shader: shader_source,
570 camera_effect,
571 configs: vec![
572 (
573 "//@CAMERA_STRUCT".to_string(),
574 Box::new(|camera_effect| {
575 if camera_effect.is_some() {
576 r#"struct CameraUniforms {
577 camera_matrix: mat4x4<f32>,
578 };
579 @group(1) @binding(0)
580 var<uniform> camera_uniform: CameraUniforms;"#
581 .to_string()
582 } else {
583 "".to_string()
584 }
585 }),
586 ),
587 (
588 "//@CAMERA_VERTEX".to_string(),
589 Box::new(|camera_effect| {
590 if camera_effect.is_some() {
591 r#"out.position = camera_uniform.camera_matrix * model_matrix * (transform_uniform.transform_matrix * vec4<f32>(input.position, 1.0));"#
592 .to_string()
593 } else {
594 r#"out.position = model_matrix * (transform_uniform.transform_matrix * vec4<f32>(input.position, 1.0));"#.to_string()
595 }
596 }),
597 ),
598 ],
599 };
600 shader_builder.build();
601
602 shader_builder
603 }
604
605 pub fn set_shader(&mut self, new_shader: String) {
607 self.shader = new_shader;
608 self.build();
609 }
610
611 pub fn build(&mut self) {
613 for i in &self.configs {
614 self.shader = self.shader.replace(&i.0, &i.1(self.camera_effect.clone()));
615 }
616 }
617}
618
619impl Instance {
620 pub fn new(
622 position: impl Into<Vector3>,
623 rotation: impl Into<Vector3>,
624 scale: impl Into<Vector3>,
625 ) -> Self {
626 Self {
627 position: position.into(),
628 rotation: rotation.into(),
629 scale: scale.into(),
630 }
631 }
632
633 pub fn to_raw(&self) -> InstanceRaw {
635 let position_matrix = glm::translate(&DEFAULT_MATRIX_4.to_im(), &self.position.into());
636 let rotation_matrix =
637 nalgebra_glm::rotate(&DEFAULT_MATRIX_4.to_im(), 0f32, &self.rotation.into());
638 let scale_matrix = glm::scale(&DEFAULT_MATRIX_4.to_im(), &self.scale.into());
639 InstanceRaw {
640 model: Matrix::from_im(position_matrix * rotation_matrix * scale_matrix),
641 }
642 }
643
644 pub fn set_position(&mut self, position: impl Into<Vector3>) {
646 self.position = position.into();
647 }
648
649 pub fn set_rotation(&mut self, rotation: impl Into<Vector3>) {
651 self.rotation = rotation.into();
652 }
653
654 pub fn set_scale(&mut self, scale: impl Into<Vector3>) {
656 self.scale = scale.into();
657 }
658}
659
660impl Default for Instance {
661 fn default() -> Self {
662 Self {
663 position: Vector3::default(),
664 rotation: Vector3::default(),
665 scale: Vector3::new(1.0, 1.0, 1.0),
666 }
667 }
668}
669
670impl InstanceRaw {
671 pub fn desc() -> wgpu::VertexBufferLayout<'static> {
673 use std::mem;
674 wgpu::VertexBufferLayout {
675 array_stride: mem::size_of::<InstanceRaw>() as wgpu::BufferAddress,
676 step_mode: wgpu::VertexStepMode::Instance,
680 attributes: &[
681 wgpu::VertexAttribute {
684 offset: 0,
685 shader_location: 3,
686 format: wgpu::VertexFormat::Float32x4,
687 },
688 wgpu::VertexAttribute {
689 offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
690 shader_location: 4,
691 format: wgpu::VertexFormat::Float32x4,
692 },
693 wgpu::VertexAttribute {
694 offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
695 shader_location: 5,
696 format: wgpu::VertexFormat::Float32x4,
697 },
698 wgpu::VertexAttribute {
699 offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
700 shader_location: 6,
701 format: wgpu::VertexFormat::Float32x4,
702 },
703 ],
704 }
705 }
706}