2 atlas::{AtlasCollection, SpriteIndex, SpriteLocation}, |
2 atlas::{AtlasCollection, SpriteIndex, SpriteLocation}, |
3 camera::Camera, |
3 camera::Camera, |
4 gl::{ |
4 gl::{ |
5 Buffer, BufferType, BufferUsage, InputElement, InputFormat, InputLayout, PipelineState, |
5 Buffer, BufferType, BufferUsage, InputElement, InputFormat, InputLayout, PipelineState, |
6 Shader, Texture2D, TextureDataType, TextureFilter, TextureFormat, TextureInternalFormat, |
6 Shader, Texture2D, TextureDataType, TextureFilter, TextureFormat, TextureInternalFormat, |
|
7 VariableBinding, |
7 }, |
8 }, |
8 }; |
9 }; |
9 |
10 |
10 use integral_geometry::{Rect, Size}; |
11 use integral_geometry::{Rect, Size}; |
11 |
12 |
22 }; |
23 }; |
23 |
24 |
24 const VERTEX_SHADER: &'static str = r#" |
25 const VERTEX_SHADER: &'static str = r#" |
25 #version 330 core |
26 #version 330 core |
26 |
27 |
|
28 uniform mat4 projection; |
|
29 |
27 layout(location = 0) in vec2 position; |
30 layout(location = 0) in vec2 position; |
28 |
31 layout(location = 1) in vec2 texCoords; |
29 uniform mat4 projection; |
32 |
|
33 out vec2 varTexCoords; |
30 |
34 |
31 void main() { |
35 void main() { |
|
36 varTexCoords = texCoords; |
32 gl_Position = projection * vec4(position, 0.0, 1.0); |
37 gl_Position = projection * vec4(position, 0.0, 1.0); |
33 } |
38 } |
34 "#; |
39 "#; |
35 |
40 |
36 const PIXEL_SHADER: &'static str = r#" |
41 const PIXEL_SHADER: &'static str = r#" |
37 #version 330 core |
42 #version 330 core |
38 |
43 |
|
44 uniform sampler2D texture; |
|
45 |
|
46 in vec2 varTexCoords; |
|
47 |
39 out vec4 outColor; |
48 out vec4 outColor; |
40 |
49 |
41 void main() { |
50 void main() { |
42 outColor = vec4(0.0, 1.0, 0.0, 1.0); |
51 outColor = texture2D(texture, varTexCoords); |
43 } |
52 } |
44 "#; |
53 "#; |
45 |
54 |
46 #[repr(C)] |
55 #[repr(C)] |
47 #[derive(Copy, Clone)] |
56 #[derive(Copy, Clone)] |
48 struct Vertex { |
57 struct Vertex { |
49 pos: [f32; 2], |
58 position: [f32; 2], |
|
59 tex_coords: [f32; 2], |
50 } |
60 } |
51 |
61 |
52 #[derive(PartialEq, Debug, Clone, Copy)] |
62 #[derive(PartialEq, Debug, Clone, Copy)] |
53 pub enum SpriteId { |
63 pub enum SpriteId { |
54 Mine = 0, |
64 Mine = 0, |
117 let index = atlas |
128 let index = atlas |
118 .insert_sprite(size) |
129 .insert_sprite(size) |
119 .expect(&format!("Could not store sprite {:?}", sprite)); |
130 .expect(&format!("Could not store sprite {:?}", sprite)); |
120 let (texture_index, rect) = atlas.get_rect(index).unwrap(); |
131 let (texture_index, rect) = atlas.get_rect(index).unwrap(); |
121 |
132 |
122 let mut pixels = vec![0; size.area()].into_boxed_slice(); |
133 let mut pixels = vec![255u8; size.area() * 4].into_boxed_slice(); |
123 load_sprite_pixels(path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..])) |
134 load_sprite_pixels(path, &mut pixels).expect("Unable to load Graphics"); |
124 .expect("Unable to load Graphics"); |
|
125 |
135 |
126 texture.update( |
136 texture.update( |
127 rect, |
137 rect, |
128 mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]), |
138 &pixels, |
129 None, |
139 None, |
130 TextureFormat::Rgba, |
140 TextureFormat::Rgba, |
131 TextureDataType::UnsignedByte, |
141 TextureDataType::UnsignedByte, |
132 ); |
142 ); |
133 |
143 |
134 allocation[*sprite as usize] = (texture_index, rect); |
144 allocation[*sprite as usize] = (texture_index, rect); |
135 } |
145 } |
136 |
146 |
137 let shader = Shader::new(VERTEX_SHADER, Some(PIXEL_SHADER), &[]).unwrap(); |
147 let shader = Shader::new( |
|
148 VERTEX_SHADER, |
|
149 Some(PIXEL_SHADER), |
|
150 &[VariableBinding::Sampler("texture", 0)], |
|
151 ) |
|
152 .unwrap(); |
138 |
153 |
139 let layout = InputLayout::new(vec![ |
154 let layout = InputLayout::new(vec![ |
140 // position |
|
141 InputElement { |
155 InputElement { |
142 shader_slot: 0, |
156 shader_slot: 0, |
143 buffer_slot: 0, |
157 buffer_slot: 0, |
144 format: InputFormat::Float(gl::FLOAT, false), |
158 format: InputFormat::Float(gl::FLOAT, false), |
145 components: 2, |
159 components: 2, |
146 stride: size_of::<Vertex>() as u32, |
160 stride: size_of::<Vertex>() as u32, |
147 offset: 0, |
161 offset: 0, |
148 }, |
162 }, |
|
163 InputElement { |
|
164 shader_slot: 1, |
|
165 buffer_slot: 0, |
|
166 format: InputFormat::Float(gl::FLOAT, false), |
|
167 components: 2, |
|
168 stride: size_of::<Vertex>() as u32, |
|
169 offset: size_of::<[f32; 2]>() as u32, |
|
170 }, |
149 ]); |
171 ]); |
150 |
172 |
151 let vertex_buffer = Buffer::empty(BufferType::Array, BufferUsage::DynamicDraw); |
173 let vertex_buffer = Buffer::empty(BufferType::Array, BufferUsage::DynamicDraw); |
152 |
174 |
153 Self { |
175 Self { |
154 atlas, |
176 atlas, |
|
177 texture, |
155 allocation, |
178 allocation, |
156 shader, |
179 shader, |
157 layout, |
180 layout, |
158 vertex_buffer, |
181 vertex_buffer, |
159 } |
182 } |
160 } |
183 } |
161 |
184 |
162 pub fn render(&mut self, camera: &Camera, entries: &[GearEntry]) { |
185 pub fn render(&mut self, camera: &Camera, entries: &[GearEntry]) { |
|
186 let mut data = Vec::with_capacity(entries.len() * 6); |
|
187 |
|
188 for entry in entries { |
|
189 let v = [ |
|
190 Vertex { |
|
191 position: [ |
|
192 entry.position[0] - entry.size.width as f32 / 2.0, |
|
193 entry.position[1] + entry.size.height as f32 / 2.0, |
|
194 ], |
|
195 tex_coords: [0.0, 0.015625], |
|
196 }, |
|
197 Vertex { |
|
198 position: [ |
|
199 entry.position[0] + entry.size.width as f32 / 2.0, |
|
200 entry.position[1] + entry.size.height as f32 / 2.0, |
|
201 ], |
|
202 tex_coords: [0.015625, 0.015625], |
|
203 }, |
|
204 Vertex { |
|
205 position: [ |
|
206 entry.position[0] - entry.size.width as f32 / 2.0, |
|
207 entry.position[1] - entry.size.height as f32 / 2.0, |
|
208 ], |
|
209 tex_coords: [0.0, 0.0], |
|
210 }, |
|
211 Vertex { |
|
212 position: [ |
|
213 entry.position[0] + entry.size.width as f32 / 2.0, |
|
214 entry.position[1] - entry.size.height as f32 / 2.0, |
|
215 ], |
|
216 tex_coords: [0.015625, 0.0], |
|
217 }, |
|
218 ]; |
|
219 |
|
220 data.extend_from_slice(&[v[0], v[1], v[2], v[1], v[3], v[2]]); |
|
221 } |
|
222 |
163 let projection = camera.projection(); |
223 let projection = camera.projection(); |
164 self.shader.bind(); |
224 self.shader.bind(); |
165 self.shader.set_matrix("projection", projection.as_ptr()); |
225 self.shader.set_matrix("projection", projection.as_ptr()); |
166 |
226 self.shader.bind_texture_2d(0, &self.texture); |
167 let mut data = Vec::with_capacity(entries.len() * 12); |
|
168 |
|
169 for entry in entries { |
|
170 let vertices = [ |
|
171 [ |
|
172 entry.position[0] - entry.size.width as f32 / 2.0, |
|
173 entry.position[1] + entry.size.height as f32 / 2.0, |
|
174 ], |
|
175 [ |
|
176 entry.position[0] + entry.size.width as f32 / 2.0, |
|
177 entry.position[1] + entry.size.height as f32 / 2.0, |
|
178 ], |
|
179 [ |
|
180 entry.position[0] - entry.size.width as f32 / 2.0, |
|
181 entry.position[1] - entry.size.height as f32 / 2.0, |
|
182 ], |
|
183 [ |
|
184 entry.position[0] + entry.size.width as f32 / 2.0, |
|
185 entry.position[1] - entry.size.height as f32 / 2.0, |
|
186 ], |
|
187 ]; |
|
188 |
|
189 data.extend_from_slice(&[ |
|
190 vertices[0][0], |
|
191 vertices[0][1], |
|
192 vertices[1][0], |
|
193 vertices[1][1], |
|
194 vertices[2][0], |
|
195 vertices[2][1], |
|
196 vertices[1][0], |
|
197 vertices[1][1], |
|
198 vertices[3][0], |
|
199 vertices[3][1], |
|
200 vertices[2][0], |
|
201 vertices[2][1], |
|
202 ]); |
|
203 } |
|
204 |
227 |
205 self.vertex_buffer.write_typed(&data); |
228 self.vertex_buffer.write_typed(&data); |
206 let _buffer_bind = self.layout.bind(&[(0, &self.vertex_buffer)], None); |
229 let _buffer_bind = self.layout.bind(&[(0, &self.vertex_buffer)], None); |
|
230 |
207 let _state = PipelineState::new().with_blend(); |
231 let _state = PipelineState::new().with_blend(); |
208 |
232 |
209 unsafe { |
233 unsafe { |
210 gl::DrawArrays(gl::TRIANGLES, 0, entries.len() as i32 * 6); |
234 gl::DrawArrays(gl::TRIANGLES, 0, entries.len() as i32 * 6); |
211 } |
235 } |