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
17pub 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 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}