gridsim_ui/
lib.rs

1use glium::{implement_vertex, uniform};
2
3mod run;
4
5pub use run::Loop;
6
7use rayon::prelude::*;
8
9#[derive(Copy, Clone, Debug)]
10struct SquareVert {
11    color: [f32; 3],
12    position: [f32; 2],
13}
14
15implement_vertex!(SquareVert, color, position);
16
17/// Stores information to render
18pub struct Renderer {
19    square: glium::Program,
20}
21
22impl Renderer {
23    pub fn new<D: glium::backend::Facade>(display: &D) -> Renderer {
24        Renderer {
25            square: glium::Program::from_source(
26                display,
27                include_str!("square.vert"),
28                include_str!("square.frag"),
29                Some(include_str!("square.geom")),
30            )
31            .unwrap(),
32        }
33    }
34
35    /// Takes a glium Facade, a drawing Surface, a Grid, a transform, and a cell to color map.
36    ///
37    /// Renders the cells in a space from <-1, -1> to <1, 1> which is transformed with the transform matrix.
38    pub fn render<
39        'a,
40        D: glium::backend::Facade,
41        Su: glium::Surface,
42        S: gridsim::Sim<'a>,
43        Color: Fn(&S::Cell) -> [f32; 3] + Sync,
44        Filter: Fn(&S::Cell) -> bool + Sync,
45    >(
46        &self,
47        display: &D,
48        surface: &mut Su,
49        grid: &gridsim::SquareGrid<'a, S>,
50        draw_params: glium::DrawParameters,
51        cell_color: Color,
52        filter: Filter,
53    ) -> Result<(), glium::DrawError>
54    where
55        S::Cell: Sync,
56    {
57        let width = grid.get_width();
58        let height = grid.get_height();
59        let verts: Vec<_> = grid
60            .get_cells()
61            .par_iter()
62            .enumerate()
63            .filter(|(_, cell)| filter(&cell))
64            .map(|(ix, cell)| SquareVert {
65                color: cell_color(cell),
66                position: [
67                    2.0 * (ix % width) as f32 / width as f32 - 1.0,
68                    2.0 * (ix / width) as f32 / height as f32 - 1.0,
69                ],
70            })
71            .collect();
72        let indices = glium::index::NoIndices(glium::index::PrimitiveType::Points);
73        let dims: [f32; 2] = [
74            2.0 / grid.get_width() as f32,
75            2.0 / grid.get_height() as f32,
76        ];
77        let uniforms = &uniform! { dims: dims };
78        let vertex_buffer = glium::VertexBuffer::new(display, &verts[..]).unwrap();
79        surface.draw(
80            &vertex_buffer,
81            &indices,
82            &self.square,
83            uniforms,
84            &draw_params,
85        )
86    }
87}