1use gl;
5use nalgebra::Matrix4;
6use nalgebra::Vector2;
7use shader::Shader;
8use shader::DEFAULT_SHADER;
9use texture::Texture;
10
11lazy_static! {
20 static ref DEFAULT_CONTEXT: Context<'static> = Context::default();
21}
22
23lazy_static! {
24 pub static ref IDENTITY: Matrix4<f32> = Matrix4::identity();
25}
26
27#[derive(Debug)]
28pub enum BlendMode {
30 Alpha,
31 Beta,
32 Ceta,
33}
34
35impl BlendMode {
36 fn blend_to_gl(&self) {
37 match self {
38 BlendMode::Alpha => unsafe { gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA) },
39 _ => {}
40 }
41 }
42
43 pub fn unactive(&self) {
44 unsafe {
45 gl::Disable(gl::BLEND);
46 }
47 }
48
49 pub fn active(&self) {
50 unsafe {
51 gl::Enable(gl::BLEND);
52 match self {
53 BlendMode::Alpha => {
54 gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
55 }
56 BlendMode::Beta => {
57 gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
58 }
59 BlendMode::Ceta => {
60 gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
61 }
62 }
63 }
64 }
65}
66
67#[derive(Debug)]
76pub struct Context<'a> {
80 texture: Option<&'a Texture>,
81 shader: &'a Shader,
82 transform: Vec<(String, &'a Matrix4<f32>)>,
83 blend_mode: BlendMode,
84}
85
86impl<'a> Context<'a> {
87 pub fn new(
89 texture: Option<&'a Texture>,
90 shader: &'a Shader,
91 transform: Vec<(String, &'a Matrix4<f32>)>,
92 blend_mode: BlendMode,
93 ) -> Context<'a> {
94 Context {
95 texture,
96 shader,
97 transform,
98 blend_mode,
99 }
100 }
101
102 pub fn apply_texture(&mut self, id: i32) {
104 if let Some(texture) = self.texture {
105 texture.active(id);
106 }
107 }
108
109 pub fn apply_blendmode(&mut self) {
111 self.blend_mode.active();
112 }
113
114 pub fn setup_shader(&self) {
116 self.shader.activate();
117 for (name, mat) in &self.transform {
118 self.shader.uniform_mat4f(name.as_str(), mat);
119 }
120 }
121}
122
123impl<'a> Default for Context<'a> {
124 fn default() -> Context<'a> {
126 Context {
127 texture: None,
128 shader: &*DEFAULT_SHADER,
129 transform: vec![("transform".to_string(), &*IDENTITY)],
130 blend_mode: BlendMode::Alpha,
131 }
132 }
133}
134
135pub trait Drawer {
145 fn draw<T: Drawable>(&mut self, drawable: &T);
147
148 fn draw_with_context_mut<T: DrawableMut>(&mut self, drawable: &mut T, context: &mut Context) {
150 self.draw_with_context(drawable, context);
151 }
152
153 fn draw_mut<T: DrawableMut>(&mut self, drawable: &mut T) {
155 self.draw(drawable);
156 }
157
158 fn draw_with_context<T: Drawable>(&mut self, drawable: &mut T, context: &mut Context) {
160 drawable.draw_with_context(context);
161 }
162
163 fn get_center(&self) -> Vector2<f32>;
164
165 fn get_sizes(&self) -> Vector2<f32>;
166
167 fn projection(&self) -> &Matrix4<f32>;
168}
169
170pub trait Drawable {
172 fn draw<T: Drawer>(&self, window: &mut T);
174
175 fn draw_with_context(&self, context: &mut Context);
177
178 fn update(&mut self);
181
182 fn setup_draw(&self, context: &mut Context) {
184 context.apply_texture(0);
185 context.apply_blendmode();
186 context.setup_shader();
187 }
188}
189
190pub trait DrawableMut: Drawable {
191 fn draw_mut<T: Drawer>(&mut self, window: &mut T) {
193 self.draw(window);
194 }
195
196 fn draw_with_context_mut(&mut self, context: &mut Context) {
198 self.draw_with_context(context);
199 }
200}