1use crate::{
27 core::{
28 algebra::{Matrix4, Vector3},
29 color::Color,
30 math::Rect,
31 sstorage::ImmutableString,
32 },
33 graphics::{
34 buffer::BufferUsage,
35 error::FrameworkError,
36 framebuffer::GpuFrameBuffer,
37 geometry_buffer::{
38 AttributeDefinition, AttributeKind, ElementsDescriptor, GpuGeometryBuffer,
39 GpuGeometryBufferDescriptor, VertexBufferData, VertexBufferDescriptor,
40 },
41 server::GraphicsServer,
42 },
43 renderer::{
44 cache::{
45 shader::{binding, property, PropertyGroup, RenderMaterial},
46 uniform::UniformBufferCache,
47 },
48 resources::RendererResources,
49 RenderPassStatistics,
50 },
51 scene::debug::Line,
52};
53use bytemuck::{Pod, Zeroable};
54
55#[repr(C)]
56#[derive(Copy, Pod, Zeroable, Clone)]
57struct Vertex {
58 position: Vector3<f32>,
59 color: u32,
60}
61
62pub struct DebugRenderer {
64 geometry: GpuGeometryBuffer,
65 vertices: Vec<Vertex>,
66 line_indices: Vec<[u32; 2]>,
67}
68
69pub fn draw_rect(rect: &Rect<f32>, lines: &mut Vec<Line>, color: Color) {
71 for (a, b) in [
72 (rect.left_top_corner(), rect.right_top_corner()),
73 (rect.right_top_corner(), rect.right_bottom_corner()),
74 (rect.right_bottom_corner(), rect.left_bottom_corner()),
75 (rect.left_bottom_corner(), rect.left_top_corner()),
76 ] {
77 lines.push(Line {
78 begin: a.to_homogeneous(),
79 end: b.to_homogeneous(),
80 color,
81 });
82 }
83}
84
85impl DebugRenderer {
86 pub(crate) fn new(server: &dyn GraphicsServer) -> Result<Self, FrameworkError> {
87 let desc = GpuGeometryBufferDescriptor {
88 name: "DebugGeometryBuffer",
89 elements: ElementsDescriptor::Lines(&[]),
90 buffers: &[VertexBufferDescriptor {
91 usage: BufferUsage::DynamicDraw,
92 attributes: &[
93 AttributeDefinition {
94 location: 0,
95 divisor: 0,
96 kind: AttributeKind::Float,
97 component_count: 3,
98 normalized: false,
99 },
100 AttributeDefinition {
101 location: 1,
102 kind: AttributeKind::UnsignedByte,
103 component_count: 4,
104 normalized: true,
105 divisor: 0,
106 },
107 ],
108 data: VertexBufferData::new::<Vertex>(None),
109 }],
110 usage: BufferUsage::DynamicDraw,
111 };
112
113 Ok(Self {
114 geometry: server.create_geometry_buffer(desc)?,
115 vertices: Default::default(),
116 line_indices: Default::default(),
117 })
118 }
119
120 pub fn set_lines(&mut self, lines: &[Line]) {
122 self.vertices.clear();
123 self.line_indices.clear();
124
125 let mut i = 0;
126 for line in lines.iter() {
127 let color = line.color.into();
128 self.vertices.push(Vertex {
129 position: line.begin,
130 color,
131 });
132 self.vertices.push(Vertex {
133 position: line.end,
134 color,
135 });
136 self.line_indices.push([i, i + 1]);
137 i += 2;
138 }
139 self.geometry.set_buffer_data_of_type(0, &self.vertices);
140 self.geometry.set_lines(&self.line_indices);
141 }
142
143 pub(crate) fn render(
144 &mut self,
145 server: &dyn GraphicsServer,
146 uniform_buffer_cache: &mut UniformBufferCache,
147 viewport: Rect<i32>,
148 framebuffer: &GpuFrameBuffer,
149 view_projection: Matrix4<f32>,
150 renderer_resources: &RendererResources,
151 ) -> Result<RenderPassStatistics, FrameworkError> {
152 let _debug_scope = server.begin_scope("DebugRendering");
153
154 let mut statistics = RenderPassStatistics::default();
155
156 let properties = PropertyGroup::from([property("worldViewProjection", &view_projection)]);
157 let material = RenderMaterial::from([binding("properties", &properties)]);
158
159 statistics += renderer_resources.shaders.debug.run_pass(
160 1,
161 &ImmutableString::new("Primary"),
162 framebuffer,
163 &self.geometry,
164 viewport,
165 &material,
166 uniform_buffer_cache,
167 Default::default(),
168 None,
169 )?;
170
171 Ok(statistics)
172 }
173}