mesh.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use crate::{
  19. error::Result,
  20. gfx::{DrawMesh, Rectangle, RenderApi, Vertex},
  21. };
  22. use miniquad::{BufferId, TextureId};
  23. pub type Color = [f32; 4];
  24. #[allow(dead_code)]
  25. pub const COLOR_RED: Color = [1., 0., 0., 1.];
  26. #[allow(dead_code)]
  27. pub const COLOR_DARKGREY: Color = [0.2, 0.2, 0.2, 1.];
  28. #[allow(dead_code)]
  29. pub const COLOR_LIGHTGREY: Color = [0.7, 0.7, 0.7, 1.];
  30. pub const COLOR_GREEN: Color = [0., 1., 0., 1.];
  31. pub const COLOR_BLUE: Color = [0., 0., 1., 1.];
  32. pub const COLOR_PINK: Color = [0.8, 0.3, 0.8, 1.];
  33. pub const COLOR_WHITE: Color = [1., 1., 1., 1.];
  34. #[allow(dead_code)]
  35. pub const COLOR_BLACK: Color = [1., 1., 1., 1.];
  36. #[allow(dead_code)]
  37. pub const COLOR_GREY: Color = [0.5, 0.5, 0.5, 1.];
  38. #[derive(Clone)]
  39. pub struct MeshInfo {
  40. pub vertex_buffer: BufferId,
  41. pub index_buffer: BufferId,
  42. pub num_elements: i32,
  43. }
  44. impl MeshInfo {
  45. /// Convenience method
  46. pub fn draw_with_texture(self, texture: TextureId) -> DrawMesh {
  47. DrawMesh {
  48. vertex_buffer: self.vertex_buffer,
  49. index_buffer: self.index_buffer,
  50. texture: Some(texture),
  51. num_elements: self.num_elements,
  52. }
  53. }
  54. /// Convenience method
  55. pub fn draw_untextured(self) -> DrawMesh {
  56. DrawMesh {
  57. vertex_buffer: self.vertex_buffer,
  58. index_buffer: self.index_buffer,
  59. texture: None,
  60. num_elements: self.num_elements,
  61. }
  62. }
  63. }
  64. pub struct MeshBuilder {
  65. pub verts: Vec<Vertex>,
  66. pub indices: Vec<u16>,
  67. clipper: Option<Rectangle>,
  68. }
  69. impl MeshBuilder {
  70. pub fn new() -> Self {
  71. Self { verts: vec![], indices: vec![], clipper: None }
  72. }
  73. pub fn with_clip(clipper: Rectangle) -> Self {
  74. Self { verts: vec![], indices: vec![], clipper: Some(clipper) }
  75. }
  76. pub fn append(&mut self, mut verts: Vec<Vertex>, indices: Vec<u16>) {
  77. let mut indices = indices.into_iter().map(|i| i + self.verts.len() as u16).collect();
  78. self.verts.append(&mut verts);
  79. self.indices.append(&mut indices);
  80. }
  81. pub fn draw_box(&mut self, obj: &Rectangle, color: Color, uv: &Rectangle) {
  82. let clipped = match &self.clipper {
  83. Some(clipper) => {
  84. let Some(clipped) = clipper.clip(&obj) else {
  85. return;
  86. };
  87. clipped
  88. }
  89. None => obj.clone(),
  90. };
  91. let (x1, y1) = clipped.top_left().unpack();
  92. let (x2, y2) = clipped.bottom_right().unpack();
  93. let (u1, v1) = uv.top_left().unpack();
  94. let (u2, v2) = uv.bottom_right().unpack();
  95. // Interpolate UV coords
  96. assert!(obj.w >= clipped.w);
  97. assert!(obj.h >= clipped.h);
  98. let i = (clipped.x - obj.x) / obj.w;
  99. let clip_u1 = u1 + i * (u2 - u1);
  100. let i = (clipped.rhs() - obj.x) / obj.w;
  101. let clip_u2 = u1 + i * (u2 - u1);
  102. let i = (clipped.y - obj.y) / obj.h;
  103. let clip_v1 = v1 + i * (v2 - v1);
  104. let i = (clipped.bhs() - obj.y) / obj.h;
  105. let clip_v2 = v1 + i * (v2 - v1);
  106. let (u1, u2) = (clip_u1, clip_u2);
  107. let (v1, v2) = (clip_v1, clip_v2);
  108. let verts = vec![
  109. // top left
  110. Vertex { pos: [x1, y1], color, uv: [u1, v1] },
  111. // top right
  112. Vertex { pos: [x2, y1], color, uv: [u2, v1] },
  113. // bottom left
  114. Vertex { pos: [x1, y2], color, uv: [u1, v2] },
  115. // bottom right
  116. Vertex { pos: [x2, y2], color, uv: [u2, v2] },
  117. ];
  118. let indices = vec![0, 2, 1, 1, 2, 3];
  119. self.append(verts, indices);
  120. }
  121. pub fn draw_filled_box(&mut self, obj: &Rectangle, color: Color) {
  122. let uv = Rectangle { x: 0., y: 0., w: 0., h: 0. };
  123. self.draw_box(obj, color, &uv);
  124. }
  125. pub fn draw_outline(&mut self, obj: &Rectangle, color: Color, thickness: f32) {
  126. let (x1, y1) = obj.top_left().unpack();
  127. let (dist_x, dist_y) = (obj.w, obj.h);
  128. let (x2, y2) = obj.bottom_right().unpack();
  129. // top
  130. self.draw_filled_box(&Rectangle::new(x1, y1, dist_x, thickness), color);
  131. // left
  132. self.draw_filled_box(&Rectangle::new(x1, y1, thickness, dist_y), color);
  133. // right
  134. self.draw_filled_box(&Rectangle::new(x2 - thickness, y1, thickness, dist_y), color);
  135. // bottom
  136. self.draw_filled_box(&Rectangle::new(x1, y2 - thickness, dist_x, thickness), color);
  137. }
  138. pub async fn alloc(self, render_api: &RenderApi) -> Result<MeshInfo> {
  139. //debug!(target: "mesh", "allocating {} verts:", self.verts.len());
  140. //for vert in &self.verts {
  141. // debug!(target: "mesh", " {:?}", vert);
  142. //}
  143. let num_elements = self.indices.len() as i32;
  144. let vertex_buffer = render_api.new_vertex_buffer(self.verts).await?;
  145. let index_buffer = render_api.new_index_buffer(self.indices).await?;
  146. Ok(MeshInfo { vertex_buffer, index_buffer, num_elements })
  147. }
  148. }