mesh.rs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2025 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::gfx::{
  19. DebugTag, DrawMesh, ManagedBufferPtr, ManagedTexturePtr, Point, Rectangle, RenderApi, Vertex,
  20. };
  21. pub type Color = [f32; 4];
  22. #[allow(dead_code)]
  23. pub const COLOR_RED: Color = [1., 0., 0., 1.];
  24. #[allow(dead_code)]
  25. pub const COLOR_DARKGREY: Color = [0.2, 0.2, 0.2, 1.];
  26. #[allow(dead_code)]
  27. pub const COLOR_LIGHTGREY: Color = [0.7, 0.7, 0.7, 1.];
  28. #[allow(dead_code)]
  29. pub const COLOR_GREEN: Color = [0., 1., 0., 1.];
  30. pub const COLOR_BLUE: Color = [0., 0., 1., 1.];
  31. pub const COLOR_PINK: Color = [0.8, 0.3, 0.8, 1.];
  32. pub const COLOR_CYAN: Color = [0., 1., 1., 1.];
  33. #[allow(dead_code)]
  34. pub const COLOR_PURPLE: Color = [1., 0., 1., 1.];
  35. pub const COLOR_WHITE: Color = [1., 1., 1., 1.];
  36. #[allow(dead_code)]
  37. pub const COLOR_BLACK: Color = [1., 1., 1., 1.];
  38. #[allow(dead_code)]
  39. pub const COLOR_GREY: Color = [0.5, 0.5, 0.5, 1.];
  40. #[derive(Clone)]
  41. pub struct MeshInfo {
  42. pub vertex_buffer: ManagedBufferPtr,
  43. pub index_buffer: ManagedBufferPtr,
  44. pub num_elements: i32,
  45. }
  46. impl MeshInfo {
  47. /// Convenience method for textured mesh
  48. pub fn draw_with_textures(self, textures: Vec<ManagedTexturePtr>) -> DrawMesh {
  49. DrawMesh {
  50. vertex_buffer: self.vertex_buffer,
  51. index_buffer: self.index_buffer,
  52. textures: Some(textures),
  53. num_elements: self.num_elements,
  54. }
  55. }
  56. /// Convenience method
  57. pub fn draw_untextured(self) -> DrawMesh {
  58. DrawMesh {
  59. vertex_buffer: self.vertex_buffer,
  60. index_buffer: self.index_buffer,
  61. textures: None,
  62. num_elements: self.num_elements,
  63. }
  64. }
  65. }
  66. pub struct MeshBuilder {
  67. pub verts: Vec<Vertex>,
  68. pub indices: Vec<u16>,
  69. tag: DebugTag,
  70. }
  71. impl MeshBuilder {
  72. pub fn new(tag: DebugTag) -> Self {
  73. Self { verts: vec![], indices: vec![], tag }
  74. }
  75. pub fn append(&mut self, mut verts: Vec<Vertex>, indices: Vec<u16>) {
  76. let mut indices = indices.into_iter().map(|i| i + self.verts.len() as u16).collect();
  77. self.verts.append(&mut verts);
  78. self.indices.append(&mut indices);
  79. }
  80. pub fn draw_box(&mut self, obj: &Rectangle, color: Color, uv: &Rectangle) {
  81. let (x1, y1) = obj.pos().unpack();
  82. let (x2, y2) = obj.corner().unpack();
  83. let (u1, v1) = uv.pos().unpack();
  84. let (u2, v2) = uv.corner().unpack();
  85. let verts = vec![
  86. // top left
  87. Vertex { pos: [x1, y1], color, uv: [u1, v1] },
  88. // top right
  89. Vertex { pos: [x2, y1], color, uv: [u2, v1] },
  90. // bottom left
  91. Vertex { pos: [x1, y2], color, uv: [u1, v2] },
  92. // bottom right
  93. Vertex { pos: [x2, y2], color, uv: [u2, v2] },
  94. ];
  95. let indices = vec![0, 2, 1, 1, 2, 3];
  96. self.append(verts, indices);
  97. }
  98. pub fn draw_filled_box(&mut self, obj: &Rectangle, color: Color) {
  99. let uv = Rectangle::zero();
  100. self.draw_box(obj, color, &uv);
  101. }
  102. pub fn draw_box_shadow(&mut self, obj: &Rectangle, color: Color, spread: f32) {
  103. let (x1, y1) = obj.pos().unpack();
  104. let (x2, y2) = obj.corner().unpack();
  105. let uv = Rectangle::zero();
  106. let (u1, v1) = uv.pos().unpack();
  107. let (u2, v2) = uv.corner().unpack();
  108. let color2 = [color[0], color[1], color[2], 0.];
  109. // left
  110. self.append(
  111. vec![
  112. Vertex { pos: [x1, y1], color, uv: [u1, v1] },
  113. Vertex { pos: [x1 - spread, y1 - spread], color: color2, uv: [u2, v1] },
  114. Vertex { pos: [x1, y2], color, uv: [u1, v2] },
  115. Vertex { pos: [x1 - spread, y2 + spread], color: color2, uv: [u2, v2] },
  116. ],
  117. vec![0, 2, 1, 1, 2, 3],
  118. );
  119. // top
  120. self.append(
  121. vec![
  122. Vertex { pos: [x1, y1], color, uv: [u1, v1] },
  123. Vertex { pos: [x1 - spread, y1 - spread], color: color2, uv: [u2, v1] },
  124. Vertex { pos: [x2, y1], color, uv: [u1, v2] },
  125. Vertex { pos: [x2 + spread, y1 - spread], color: color2, uv: [u2, v2] },
  126. ],
  127. vec![0, 2, 1, 1, 2, 3],
  128. );
  129. // right
  130. self.append(
  131. vec![
  132. Vertex { pos: [x2, y1], color, uv: [u1, v1] },
  133. Vertex { pos: [x2 + spread, y1 - spread], color: color2, uv: [u2, v1] },
  134. Vertex { pos: [x2, y2], color, uv: [u1, v2] },
  135. Vertex { pos: [x2 + spread, y2 + spread], color: color2, uv: [u2, v2] },
  136. ],
  137. vec![0, 2, 1, 1, 2, 3],
  138. );
  139. // bottom
  140. self.append(
  141. vec![
  142. Vertex { pos: [x1, y2], color, uv: [u1, v1] },
  143. Vertex { pos: [x1 - spread, y2 + spread], color: color2, uv: [u2, v1] },
  144. Vertex { pos: [x2, y2], color, uv: [u1, v2] },
  145. Vertex { pos: [x2 + spread, y2 + spread], color: color2, uv: [u2, v2] },
  146. ],
  147. vec![0, 2, 1, 1, 2, 3],
  148. );
  149. }
  150. pub fn draw_outline(&mut self, obj: &Rectangle, color: Color, thickness: f32) {
  151. let (x1, y1) = obj.pos().unpack();
  152. let (dist_x, dist_y) = (obj.w, obj.h);
  153. let (x2, y2) = obj.corner().unpack();
  154. // top
  155. self.draw_filled_box(&Rectangle::new(x1, y1, dist_x, thickness), color);
  156. // left
  157. self.draw_filled_box(&Rectangle::new(x1, y1, thickness, dist_y), color);
  158. // right
  159. self.draw_filled_box(&Rectangle::new(x2 - thickness, y1, thickness, dist_y), color);
  160. // bottom
  161. self.draw_filled_box(&Rectangle::new(x1, y2 - thickness, dist_x, thickness), color);
  162. }
  163. pub fn draw_line(&mut self, start: Point, end: Point, color: Color, thickness: f32) {
  164. let mut dir = end - start;
  165. dir.normalize();
  166. let left = dir.perp_left() * (thickness / 2.);
  167. let right = dir.perp_right() * (thickness / 2.);
  168. let p1 = start + left;
  169. let p2 = end + left;
  170. let p3 = start + right;
  171. let p4 = end + right;
  172. let uv = [0., 0.];
  173. let verts = vec![
  174. // top left
  175. Vertex { pos: [p1.x, p1.y], color, uv },
  176. // top right
  177. Vertex { pos: [p2.x, p2.y], color, uv },
  178. // bottom left
  179. Vertex { pos: [p3.x, p3.y], color, uv },
  180. // bottom right
  181. Vertex { pos: [p4.x, p4.y], color, uv },
  182. ];
  183. let indices = vec![0, 2, 1, 1, 2, 3];
  184. self.append(verts, indices);
  185. }
  186. pub fn alloc(self, render_api: &RenderApi) -> MeshInfo {
  187. //debug!(target: "mesh", "allocating {} verts:", self.verts.len());
  188. //for vert in &self.verts {
  189. // debug!(target: "mesh", " {:?}", vert);
  190. //}
  191. let num_elements = self.indices.len() as i32;
  192. let vertex_buffer = render_api.new_vertex_buffer(self.verts, self.tag);
  193. let index_buffer = render_api.new_index_buffer(self.indices, self.tag);
  194. MeshInfo { vertex_buffer, index_buffer, num_elements }
  195. }
  196. }