sge_debug_visualisations/
grid.rs1use glium::{IndexBuffer, ProgramCreationError, VertexBuffer, implement_vertex};
2use sge_api::shapes_2d::draw_line_world;
3use sge_camera::{get_camera_2d, get_camera_2d_mut};
4use sge_color::Color;
5use sge_error_union::ErrorUnion;
6use sge_math::transform::Transform3D;
7use sge_programs::{ProgramRef, load_program_sync};
8use sge_rendering::{
9 materials::Material,
10 object_3d::{Mesh, Object3D, Object3DRef},
11};
12use sge_types::MaterialVertex3D;
13use sge_vectors::Vec2;
14use sge_window::get_display;
15
16implement_vertex!(GridVertex, position);
17#[derive(Copy, Clone, Debug)]
18pub struct GridVertex {
19 pub position: [f32; 3],
20}
21
22#[derive(ErrorUnion, Debug)]
23pub enum GridCreationError {
24 VertexBuffer(glium::vertex::BufferCreationError),
25 IndexBuffer(glium::index::BufferCreationError),
26 Program(glium::program::ProgramCreationError),
27}
28
29pub fn create_infinite_grid() -> Result<Object3DRef, GridCreationError> {
30 let display = get_display();
31
32 let size = 1000.0;
33 let vertices = vec![
34 MaterialVertex3D {
35 position: [-size, 0.0, -size],
36 normal: [0.0, 1.0, 0.0],
37 tex_coords: [0.0, 0.0],
38 },
39 MaterialVertex3D {
40 position: [size, 0.0, -size],
41 normal: [0.0, 1.0, 0.0],
42 tex_coords: [1.0, 0.0],
43 },
44 MaterialVertex3D {
45 position: [size, 0.0, size],
46 normal: [0.0, 1.0, 0.0],
47 tex_coords: [1.0, 1.0],
48 },
49 MaterialVertex3D {
50 position: [-size, 0.0, size],
51 normal: [0.0, 1.0, 0.0],
52 tex_coords: [0.0, 1.0],
53 },
54 ];
55
56 let indices = vec![0, 1, 2, 0, 2, 3];
57
58 let vertex_buffer = VertexBuffer::new(display, &vertices)?;
59 let index_buffer = IndexBuffer::new(
60 display,
61 glium::index::PrimitiveType::TrianglesList,
62 &indices,
63 )?;
64
65 let program = load_grid_program()?;
66
67 let draw_params = glium::DrawParameters {
68 blend: glium::Blend::alpha_blending(),
69 depth: glium::Depth {
70 test: glium::DepthTest::IfLess,
71 write: false,
72 ..Default::default()
73 },
74 ..Default::default()
75 };
76
77 let material = Material::new(program)
78 .with_float("grid_scale", 1.0)
79 .with_float("grid_size", 10.0)
80 .with_color("grid_color_thin", Color::NEUTRAL_500.with_alpha(0.4))
81 .with_color("grid_color_thick", Color::NEUTRAL_500.with_alpha(0.8))
82 .with_color("x_axis_color", Color::RED_200)
83 .with_color("z_axis_color", Color::BLUE_200)
84 .with_float("axis_width", 0.02)
85 .with_draw_param_overrides(draw_params)
86 .create();
87
88 let object = Object3D {
89 mesh: Mesh {
90 vertices: vertex_buffer,
91 indices: index_buffer,
92 }
93 .create(),
94 material,
95 transform: Transform3D::IDENTITY,
96 flip_normals: false,
97 };
98
99 Ok(object.create())
100}
101
102fn load_grid_program() -> Result<ProgramRef, ProgramCreationError> {
103 let vertex_shader = include_str!("../assets/vertex.glsl");
104 let fragment_shader = include_str!("../assets/fragment.glsl");
105
106 load_program_sync(vertex_shader, fragment_shader)
107}
108
109pub fn draw_2d_grid_world(color: Color) {
110 let (min, max) = get_camera_2d_mut().visible_bounds();
111 let size = max - min;
112
113 let rough_spacing = size.x.min(size.y) / 5.0;
114 let log = rough_spacing.log10();
115 let large_scale = 10_f32.powi(log.ceil() as i32);
116 let small_scale = 10_f32.powi(log.floor() as i32);
117
118 let t = ((1.0 - log.fract().rem_euclid(1.0)) * 2.0).clamp(0.0, 1.0);
119
120 let small_alpha = t;
121 let large_alpha = 1.0;
122
123 draw_grid(min, max, large_scale, large_alpha, 2.0, color);
124 draw_grid(min, max, small_scale, small_alpha, 1.0, color);
125}
126
127fn draw_grid(min: Vec2, max: Vec2, scale: f32, alpha: f32, thickness_mult: f32, color: Color) {
128 let size = max - min;
129 let width = (size.x / scale).ceil() as usize + 1;
130 let height = (size.y / scale).ceil() as usize + 1;
131 let tl = (min / scale).floor() * scale;
132
133 let faded = Color::from_rgba(color.r, color.g, color.b, color.a * alpha);
134 let thickness = thickness_mult / get_camera_2d().scale();
135
136 for x in 0..width {
137 let x = x as f32 * scale + tl.x;
138 draw_line_world(Vec2::new(x, min.y), Vec2::new(x, max.y), thickness, faded);
139 }
140 for y in 0..height {
141 let y = y as f32 * scale + tl.y;
142 draw_line_world(Vec2::new(min.x, y), Vec2::new(max.x, y), thickness, faded);
143 }
144}