diff -r f6af9d05b03c -r b10bbfb2b354 rust/lib-hedgewars-engine/src/render/gear.rs --- a/rust/lib-hedgewars-engine/src/render/gear.rs Fri Nov 13 20:59:13 2020 +0300 +++ b/rust/lib-hedgewars-engine/src/render/gear.rs Sat Nov 14 03:46:01 2020 +0300 @@ -4,6 +4,7 @@ gl::{ Buffer, BufferType, BufferUsage, InputElement, InputFormat, InputLayout, PipelineState, Shader, Texture2D, TextureDataType, TextureFilter, TextureFormat, TextureInternalFormat, + VariableBinding, }, }; @@ -24,11 +25,15 @@ const VERTEX_SHADER: &'static str = r#" #version 330 core -layout(location = 0) in vec2 position; - uniform mat4 projection; +layout(location = 0) in vec2 position; +layout(location = 1) in vec2 texCoords; + +out vec2 varTexCoords; + void main() { + varTexCoords = texCoords; gl_Position = projection * vec4(position, 0.0, 1.0); } "#; @@ -36,17 +41,22 @@ const PIXEL_SHADER: &'static str = r#" #version 330 core +uniform sampler2D texture; + +in vec2 varTexCoords; + out vec4 outColor; void main() { - outColor = vec4(0.0, 1.0, 0.0, 1.0); + outColor = texture2D(texture, varTexCoords); } "#; #[repr(C)] #[derive(Copy, Clone)] struct Vertex { - pos: [f32; 2], + position: [f32; 2], + tex_coords: [f32; 2], } #[derive(PartialEq, Debug, Clone, Copy)] @@ -86,6 +96,7 @@ pub struct GearRenderer { atlas: AtlasCollection, + texture: Texture2D, allocation: Box<[SpriteLocation; MAX_SPRITES]>, shader: Shader, layout: InputLayout, @@ -119,13 +130,12 @@ .expect(&format!("Could not store sprite {:?}", sprite)); let (texture_index, rect) = atlas.get_rect(index).unwrap(); - let mut pixels = vec![0; size.area()].into_boxed_slice(); - load_sprite_pixels(path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..])) - .expect("Unable to load Graphics"); + let mut pixels = vec![255u8; size.area() * 4].into_boxed_slice(); + load_sprite_pixels(path, &mut pixels).expect("Unable to load Graphics"); texture.update( rect, - mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]), + &pixels, None, TextureFormat::Rgba, TextureDataType::UnsignedByte, @@ -134,10 +144,14 @@ allocation[*sprite as usize] = (texture_index, rect); } - let shader = Shader::new(VERTEX_SHADER, Some(PIXEL_SHADER), &[]).unwrap(); + let shader = Shader::new( + VERTEX_SHADER, + Some(PIXEL_SHADER), + &[VariableBinding::Sampler("texture", 0)], + ) + .unwrap(); let layout = InputLayout::new(vec![ - // position InputElement { shader_slot: 0, buffer_slot: 0, @@ -146,12 +160,21 @@ stride: size_of::() as u32, offset: 0, }, + InputElement { + shader_slot: 1, + buffer_slot: 0, + format: InputFormat::Float(gl::FLOAT, false), + components: 2, + stride: size_of::() as u32, + offset: size_of::<[f32; 2]>() as u32, + }, ]); let vertex_buffer = Buffer::empty(BufferType::Array, BufferUsage::DynamicDraw); Self { atlas, + texture, allocation, shader, layout, @@ -160,50 +183,51 @@ } pub fn render(&mut self, camera: &Camera, entries: &[GearEntry]) { + let mut data = Vec::with_capacity(entries.len() * 6); + + for entry in entries { + let v = [ + Vertex { + position: [ + entry.position[0] - entry.size.width as f32 / 2.0, + entry.position[1] + entry.size.height as f32 / 2.0, + ], + tex_coords: [0.0, 0.015625], + }, + Vertex { + position: [ + entry.position[0] + entry.size.width as f32 / 2.0, + entry.position[1] + entry.size.height as f32 / 2.0, + ], + tex_coords: [0.015625, 0.015625], + }, + Vertex { + position: [ + entry.position[0] - entry.size.width as f32 / 2.0, + entry.position[1] - entry.size.height as f32 / 2.0, + ], + tex_coords: [0.0, 0.0], + }, + Vertex { + position: [ + entry.position[0] + entry.size.width as f32 / 2.0, + entry.position[1] - entry.size.height as f32 / 2.0, + ], + tex_coords: [0.015625, 0.0], + }, + ]; + + data.extend_from_slice(&[v[0], v[1], v[2], v[1], v[3], v[2]]); + } + let projection = camera.projection(); self.shader.bind(); self.shader.set_matrix("projection", projection.as_ptr()); - - let mut data = Vec::with_capacity(entries.len() * 12); - - for entry in entries { - let vertices = [ - [ - entry.position[0] - entry.size.width as f32 / 2.0, - entry.position[1] + entry.size.height as f32 / 2.0, - ], - [ - entry.position[0] + entry.size.width as f32 / 2.0, - entry.position[1] + entry.size.height as f32 / 2.0, - ], - [ - entry.position[0] - entry.size.width as f32 / 2.0, - entry.position[1] - entry.size.height as f32 / 2.0, - ], - [ - entry.position[0] + entry.size.width as f32 / 2.0, - entry.position[1] - entry.size.height as f32 / 2.0, - ], - ]; - - data.extend_from_slice(&[ - vertices[0][0], - vertices[0][1], - vertices[1][0], - vertices[1][1], - vertices[2][0], - vertices[2][1], - vertices[1][0], - vertices[1][1], - vertices[3][0], - vertices[3][1], - vertices[2][0], - vertices[2][1], - ]); - } + self.shader.bind_texture_2d(0, &self.texture); self.vertex_buffer.write_typed(&data); let _buffer_bind = self.layout.bind(&[(0, &self.vertex_buffer)], None); + let _state = PipelineState::new().with_blend(); unsafe {