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
use glium::{
uniforms::{
AsUniformValue,
UniformValue,
},
Program,
Surface,
Texture2d,
};
use crate::{
graph::{
node::Node,
NodeId,
UniformMap,
},
util::RectStrip,
};
pub enum Buffer {
Single(Texture2d),
Double(Texture2d, Texture2d),
}
impl Buffer {
pub fn new_double<F: Fn() -> Texture2d>(f: F) -> Buffer {
Buffer::Double(f(), f())
}
pub fn front(&self) -> &Texture2d {
match self {
Buffer::Single(ref texture) => texture,
Buffer::Double(ref front, _back) => front,
}
}
pub fn back(&self) -> Option<&Texture2d> {
match self {
Buffer::Single(_) => None,
Buffer::Double(_front, back) => Some(back),
}
}
pub fn swap(&mut self) {
if let Buffer::Double(ref mut front, ref mut back) = self {
std::mem::swap(front, back);
}
}
}
pub struct ShaderNode {
pub shader: Program,
pub inputs: Vec<NodeId>,
pub buffer: Buffer,
}
impl std::fmt::Debug for ShaderNode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ShaderGraph")
.field("inputs", &self.inputs)
.finish()
}
}
impl Node for ShaderNode {
fn inputs(&self) -> Vec<NodeId> { self.inputs.to_owned() }
fn outputs(&self) -> (&str, UniformValue) {
match self.buffer {
Buffer::Single(ref texture) => {
("texture", texture.as_uniform_value())
},
Buffer::Double(ref texture, _) => {
("texture", texture.as_uniform_value())
},
}
}
fn texture(&self) -> Option<&Texture2d> { Some(self.buffer.front()) }
fn forward(&mut self, rect_strip: &RectStrip, uniforms: UniformMap) {
self.buffer.swap();
let front = self.buffer.front();
let resolution =
[front.get_width() as f32, front.get_height().unwrap() as f32];
let mut uniforms = uniforms;
uniforms.add("resolution", UniformValue::Vec2(resolution));
if let Some(back) = self.buffer.back() {
uniforms.add("previous", back.as_uniform_value());
}
front
.as_surface()
.draw(
&rect_strip.buffer,
&rect_strip.indices,
&self.shader,
&uniforms,
&Default::default(),
)
.unwrap();
}
}