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
use gl;
use graphics::draw_state::*;
pub fn bind_state(old_state: &DrawState, new_state: &DrawState) {
if old_state.scissor != new_state.scissor {
bind_scissor(new_state.scissor);
}
if old_state.stencil != new_state.stencil {
bind_stencil(new_state.stencil);
}
if old_state.blend != new_state.blend {
bind_blend(new_state.blend);
}
}
pub fn bind_scissor(rect: Option<[u32; 4]>) {
match rect {
Some(r) => unsafe {
gl::Enable(gl::SCISSOR_TEST);
gl::Scissor(r[0] as gl::types::GLint,
r[1] as gl::types::GLint,
r[2] as gl::types::GLint,
r[3] as gl::types::GLint);
},
None => unsafe { gl::Disable(gl::SCISSOR_TEST) },
}
}
pub fn bind_stencil(stencil: Option<Stencil>) {
unsafe {
match stencil {
Some(s) => {
gl::Enable(gl::STENCIL_TEST);
match s {
Stencil::Clip(val) => {
gl::StencilFunc(gl::NEVER, val as gl::types::GLint, 255);
gl::StencilMask(255);
gl::StencilOp(gl::REPLACE, gl::KEEP, gl::KEEP);
}
Stencil::Inside(val) => {
gl::StencilFunc(gl::EQUAL, val as gl::types::GLint, 255);
gl::StencilMask(255);
gl::StencilOp(gl::KEEP, gl::KEEP, gl::KEEP);
}
Stencil::Outside(val) => {
gl::StencilFunc(gl::NOTEQUAL, val as gl::types::GLint, 255);
gl::StencilMask(255);
gl::StencilOp(gl::KEEP, gl::KEEP, gl::KEEP);
}
}
}
None => gl::Disable(gl::STENCIL_TEST),
}
}
}
pub fn bind_blend(blend: Option<Blend>) {
unsafe {
match blend {
Some(b) => {
gl::Enable(gl::BLEND);
gl::BlendColor(1.0, 1.0, 1.0, 1.0);
match b {
Blend::Alpha => {
gl::BlendEquationSeparate(gl::FUNC_ADD, gl::FUNC_ADD);
gl::BlendFuncSeparate(gl::SRC_ALPHA,
gl::ONE_MINUS_SRC_ALPHA,
gl::ONE,
gl::ONE);
}
Blend::Add => {
gl::BlendEquationSeparate(gl::FUNC_ADD, gl::FUNC_ADD);
gl::BlendFuncSeparate(gl::ONE, gl::ONE, gl::ONE, gl::ONE);
}
Blend::Multiply => {
gl::BlendEquationSeparate(gl::FUNC_ADD, gl::FUNC_ADD);
gl::BlendFuncSeparate(gl::DST_COLOR, gl::ZERO, gl::DST_ALPHA, gl::ZERO);
}
Blend::Invert => {
gl::BlendEquationSeparate(gl::FUNC_SUBTRACT, gl::FUNC_ADD);
gl::BlendFuncSeparate(gl::CONSTANT_COLOR, gl::SRC_COLOR, gl::ZERO, gl::ONE);
}
}
}
None => gl::Disable(gl::BLEND),
}
}
}