rust/lib-hedgewars-engine/src/render/gear.rs
changeset 15764 b10bbfb2b354
parent 15763 f6af9d05b03c
child 15765 713f89f6c6ab
equal deleted inserted replaced
15763:f6af9d05b03c 15764:b10bbfb2b354
     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,
    84     }
    94     }
    85 }
    95 }
    86 
    96 
    87 pub struct GearRenderer {
    97 pub struct GearRenderer {
    88     atlas: AtlasCollection,
    98     atlas: AtlasCollection,
       
    99     texture: Texture2D,
    89     allocation: Box<[SpriteLocation; MAX_SPRITES]>,
   100     allocation: Box<[SpriteLocation; MAX_SPRITES]>,
    90     shader: Shader,
   101     shader: Shader,
    91     layout: InputLayout,
   102     layout: InputLayout,
    92     vertex_buffer: Buffer,
   103     vertex_buffer: Buffer,
    93 }
   104 }
   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         }