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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::context::Context;
use na::{Matrix3, Point2, Point3};
use crate::planar_camera::PlanarCamera;
use crate::resource::{AllocationType, BufferType, Effect, GPUVec, ShaderAttribute, ShaderUniform};
#[path = "error.rs"]
mod error;
pub struct PlanarLineRenderer {
shader: Effect,
pos: ShaderAttribute<Point2<f32>>,
color: ShaderAttribute<Point3<f32>>,
view: ShaderUniform<Matrix3<f32>>,
proj: ShaderUniform<Matrix3<f32>>,
colors: GPUVec<Point3<f32>>,
lines: GPUVec<Point2<f32>>,
}
impl PlanarLineRenderer {
pub fn new() -> PlanarLineRenderer {
let mut shader = Effect::new_from_str(LINES_VERTEX_SRC, LINES_FRAGMENT_SRC);
shader.use_program();
PlanarLineRenderer {
lines: GPUVec::new(Vec::new(), BufferType::Array, AllocationType::StreamDraw),
colors: GPUVec::new(Vec::new(), BufferType::Array, AllocationType::StreamDraw),
pos: shader
.get_attrib::<Point2<f32>>("position")
.expect("Failed to get shader attribute."),
color: shader
.get_attrib::<Point3<f32>>("color")
.expect("Failed to get shader attribute."),
view: shader
.get_uniform::<Matrix3<f32>>("view")
.expect("Failed to get shader uniform."),
proj: shader
.get_uniform::<Matrix3<f32>>("proj")
.expect("Failed to get shader uniform."),
shader: shader,
}
}
pub fn needs_rendering(&self) -> bool {
self.lines.len() != 0
}
pub fn draw_line(&mut self, a: Point2<f32>, b: Point2<f32>, color: Point3<f32>) {
for lines in self.lines.data_mut().iter_mut() {
lines.push(a);
lines.push(b);
}
for colors in self.colors.data_mut().iter_mut() {
colors.push(color);
colors.push(color);
}
}
pub fn render(&mut self, camera: &mut dyn PlanarCamera) {
if self.lines.len() == 0 {
return;
}
self.shader.use_program();
self.pos.enable();
self.color.enable();
camera.upload(&mut self.proj, &mut self.view);
self.color.bind_sub_buffer(&mut self.colors, 0, 0);
self.pos.bind_sub_buffer(&mut self.lines, 0, 0);
let ctxt = Context::get();
verify!(ctxt.draw_arrays(Context::LINES, 0, self.lines.len() as i32));
self.pos.disable();
self.color.disable();
for lines in self.lines.data_mut().iter_mut() {
lines.clear()
}
for colors in self.colors.data_mut().iter_mut() {
colors.clear()
}
}
}
static LINES_VERTEX_SRC: &'static str = A_VERY_LONG_STRING;
static LINES_FRAGMENT_SRC: &'static str = ANOTHER_VERY_LONG_STRING;
const A_VERY_LONG_STRING: &'static str = "#version 100
attribute vec2 position;
attribute vec3 color;
varying vec3 vColor;
uniform mat3 proj;
uniform mat3 view;
void main() {
vec3 projected_pos = proj * view * vec3(position, 1.0);
projected_pos.z = 0.0;
gl_Position = vec4(projected_pos, 1.0);
vColor = color;
}";
const ANOTHER_VERY_LONG_STRING: &'static str = "#version 100
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
varying vec3 vColor;
void main() {
gl_FragColor = vec4(vColor, 1.0);
}";