rust/lib-hedgewars-engine/src/render/gear.rs
changeset 15762 84c07aa94b61
parent 15760 ff1432e873bd
child 15763 f6af9d05b03c
equal deleted inserted replaced
15761:e7eb0cd5b0e4 15762:84c07aa94b61
     1 use crate::render::{
     1 use crate::render::{
     2     atlas::{AtlasCollection, SpriteIndex, SpriteLocation},
     2     atlas::{AtlasCollection, SpriteIndex, SpriteLocation},
     3     camera::Camera,
     3     camera::Camera,
     4     gl::{Texture2D, TextureDataType, TextureFilter, TextureFormat, TextureInternalFormat},
     4     gl::{
       
     5         Buffer, BufferType, BufferUsage, InputElement, InputFormat, InputLayout, PipelineState,
       
     6         Shader, Texture2D, TextureDataType, TextureFilter, TextureFormat, TextureInternalFormat,
       
     7     },
     5 };
     8 };
     6 
     9 
     7 use integral_geometry::{Rect, Size};
    10 use integral_geometry::{Rect, Size};
     8 
    11 
     9 use png::{ColorType, Decoder, DecodingError};
    12 use png::{ColorType, Decoder, DecodingError};
    12     collections::HashMap,
    15     collections::HashMap,
    13     ffi::OsString,
    16     ffi::OsString,
    14     fs::{read_dir, File},
    17     fs::{read_dir, File},
    15     io,
    18     io,
    16     io::BufReader,
    19     io::BufReader,
       
    20     mem::size_of,
    17     path::{Path, PathBuf},
    21     path::{Path, PathBuf},
    18 };
    22 };
       
    23 
       
    24 const VERTEX_SHADER: &'static str = r#"
       
    25 #version 330 core
       
    26 
       
    27 layout(location = 0) in vec2 position;
       
    28 
       
    29 uniform mat4 projection;
       
    30 
       
    31 void main() {
       
    32 	gl_Position = projection * vec4(position, 0.0, 1.0);
       
    33 }
       
    34 "#;
       
    35 
       
    36 const PIXEL_SHADER: &'static str = r#"
       
    37 #version 330 core
       
    38 
       
    39 out vec4 outColor;
       
    40 
       
    41 void main() {
       
    42 	 outColor = vec4(0.0, 1.0, 0.0, 1.0);
       
    43 }
       
    44 "#;
       
    45 
       
    46 #[repr(C)]
       
    47 #[derive(Copy, Clone)]
       
    48 struct Vertex {
       
    49     pos: [f32; 2],
       
    50 }
    19 
    51 
    20 #[derive(PartialEq, Debug, Clone, Copy)]
    52 #[derive(PartialEq, Debug, Clone, Copy)]
    21 pub enum SpriteId {
    53 pub enum SpriteId {
    22     Mine = 0,
    54     Mine = 0,
    23     Grenade,
    55     Grenade,
    36     ),
    68     ),
    37 ];
    69 ];
    38 
    70 
    39 const MAX_SPRITES: usize = SpriteId::MaxSprite as usize + 1;
    71 const MAX_SPRITES: usize = SpriteId::MaxSprite as usize + 1;
    40 
    72 
       
    73 pub struct GearEntry {
       
    74     position: [f32; 2],
       
    75     size: Size,
       
    76 }
       
    77 
       
    78 impl GearEntry {
       
    79     pub fn new(x: f32, y: f32, size: Size) -> Self {
       
    80         Self {
       
    81             position: [x, y],
       
    82             size,
       
    83         }
       
    84     }
       
    85 }
       
    86 
    41 pub struct GearRenderer {
    87 pub struct GearRenderer {
    42     atlas: AtlasCollection,
    88     atlas: AtlasCollection,
    43     allocation: Box<[SpriteLocation; MAX_SPRITES]>,
    89     allocation: Box<[SpriteLocation; MAX_SPRITES]>,
       
    90     shader: Shader,
       
    91     layout: InputLayout,
       
    92     vertex_buffer: Buffer,
    44 }
    93 }
    45 
    94 
    46 struct SpriteData {
    95 struct SpriteData {
    47     size: Size,
    96     size: Size,
    48     filename: PathBuf,
    97     filename: PathBuf,
    83             );
   132             );
    84 
   133 
    85             allocation[*sprite as usize] = (texture_index, rect);
   134             allocation[*sprite as usize] = (texture_index, rect);
    86         }
   135         }
    87 
   136 
    88         Self { atlas, allocation }
   137         let shader = Shader::new(VERTEX_SHADER, Some(PIXEL_SHADER), &[]).unwrap();
    89     }
   138 
    90 
   139         let layout = InputLayout::new(vec![
    91     pub fn render(&mut self, camera: &Camera) {
   140             // position
       
   141             InputElement {
       
   142                 shader_slot: 0,
       
   143                 buffer_slot: 0,
       
   144                 format: InputFormat::Float(gl::FLOAT, false),
       
   145                 components: 2,
       
   146                 stride: size_of::<Vertex>() as u32,
       
   147                 offset: 0,
       
   148             },
       
   149         ]);
       
   150 
       
   151         let vertex_buffer = Buffer::empty(BufferType::Array, BufferUsage::DynamicDraw);
       
   152 
       
   153         Self {
       
   154             atlas,
       
   155             allocation,
       
   156             shader,
       
   157             layout,
       
   158             vertex_buffer,
       
   159         }
       
   160     }
       
   161 
       
   162     pub fn render(&mut self, camera: &Camera, entries: &[GearEntry]) {
    92         let projection = camera.projection();
   163         let projection = camera.projection();
       
   164         self.shader.bind();
       
   165         self.shader.set_matrix("projection", projection.as_ptr());
       
   166 
       
   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 
       
   205         self.vertex_buffer.write_typed(&data);
       
   206         let _buffer_bind = self.layout.bind(&[(0, &self.vertex_buffer)], None);
       
   207         let _state = PipelineState::new().with_blend();
       
   208 
       
   209         unsafe {
       
   210             gl::DrawArrays(gl::TRIANGLES, 0, entries.len() as i32 * 2);
       
   211         }
    93     }
   212     }
    94 }
   213 }
    95 
   214 
    96 fn load_sprite_pixels(path: &Path, buffer: &mut [u8]) -> io::Result<Size> {
   215 fn load_sprite_pixels(path: &Path, buffer: &mut [u8]) -> io::Result<Size> {
    97     let decoder = Decoder::new(BufReader::new(File::open(path)?));
   216     let decoder = Decoder::new(BufReader::new(File::open(path)?));