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