rust/lib-hedgewars-engine/src/render/gear.rs
changeset 15286 16bd389fc735
parent 15190 e2adb40c7988
child 15288 0f734fa371e1
equal deleted inserted replaced
15285:6382a14c9e83 15286:16bd389fc735
     1 use super::atlas::AtlasCollection;
     1 use super::{atlas::AtlasCollection, gl::Texture2D};
     2 use crate::render::camera::Camera;
     2 use crate::render::camera::Camera;
     3 
     3 
     4 use integral_geometry::Size;
     4 use integral_geometry::{Rect, Size};
     5 
     5 
       
     6 use crate::render::atlas::SpriteIndex;
     6 use png::{ColorType, Decoder, DecodingError};
     7 use png::{ColorType, Decoder, DecodingError};
       
     8 use std::path::PathBuf;
     7 use std::{
     9 use std::{
       
    10     collections::HashMap,
       
    11     ffi::OsString,
     8     fs::{read_dir, File},
    12     fs::{read_dir, File},
     9     io,
    13     io,
    10     io::BufReader,
    14     io::BufReader,
    11     path::Path,
    15     path::Path,
    12 };
    16 };
    13 
    17 
    14 pub struct GearRenderer {
    18 pub struct GearRenderer {
    15     atlas: AtlasCollection,
    19     atlas: AtlasCollection,
    16 }
    20 }
    17 
    21 
    18 const ATLAS_SIZE: Size = Size::square(1024);
    22 struct SpriteData {
       
    23     size: Size,
       
    24     filename: PathBuf,
       
    25 }
       
    26 
       
    27 const ATLAS_SIZE: Size = Size::square(2024);
    19 
    28 
    20 impl GearRenderer {
    29 impl GearRenderer {
    21     pub fn new() -> Self {
    30     pub fn new() -> Self {
       
    31         let mut lookup = Vec::with_capacity(2048);
       
    32 
    22         let mut atlas = AtlasCollection::new(ATLAS_SIZE);
    33         let mut atlas = AtlasCollection::new(ATLAS_SIZE);
    23         let sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
    34         let mut sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
    24             .expect("Unable to load Graphics");
    35             .expect("Unable to load Graphics");
    25         for sprite in &sprites {
    36         let max_size = sprites
    26             atlas.insert_sprite(*sprite);
    37             .iter()
       
    38             .fold(Size::EMPTY, |size, sprite| size.join(sprite.size));
       
    39         for sprite in sprites.drain(..) {
       
    40             lookup.push((sprite.filename, atlas.insert_sprite(sprite.size).unwrap()));
    27         }
    41         }
       
    42 
    28         println!(
    43         println!(
    29             "Filled atlas with {} sprites:\n{}",
    44             "Filled atlas with {} sprites:\n{}",
    30             sprites.len(),
    45             sprites.len(),
    31             atlas.used_space()
    46             atlas.used_space()
    32         );
    47         );
       
    48 
       
    49         let texture = Texture2D::new(max_size, gl::RGBA8, gl::LINEAR);
       
    50 
       
    51         let mut pixels = Vec::with_capacity(max_size.area()).into_boxed_slice();
       
    52         for (path, sprite_index) in lookup.drain(..) {
       
    53             if let Some((atlas_index, rect)) = atlas.get_rect(sprite_index) {
       
    54                 load_sprite_pixels(&path, &mut pixels[..]).expect("Unable to load Graphics");
       
    55                 texture.update(rect, &pixels, 0, gl::RGBA, gl::UNSIGNED_BYTE);
       
    56             }
       
    57         }
       
    58 
    33         Self { atlas }
    59         Self { atlas }
    34     }
    60     }
    35 
    61 
    36     pub fn render(&mut self, camera: &Camera) {
    62     pub fn render(&mut self, camera: &Camera) {
    37         let projection = camera.projection();
    63         let projection = camera.projection();
    38     }
    64     }
    39 }
    65 }
    40 
    66 
    41 fn load_sprite(path: &Path) -> io::Result<Size> {
    67 fn load_sprite_pixels(path: &Path, buffer: &mut [u8]) -> io::Result<()> {
       
    68     let decoder = Decoder::new(BufReader::new(File::open(path)?));
       
    69     let (info, mut reader) = decoder.read_info()?;
       
    70 
       
    71     let size = Size::new(info.width as usize, info.height as usize);
       
    72     reader.next_frame(buffer)?;
       
    73     Ok(())
       
    74 }
       
    75 
       
    76 fn load_sprite_size(path: &Path) -> io::Result<Size> {
    42     let decoder = Decoder::new(BufReader::new(File::open(path)?));
    77     let decoder = Decoder::new(BufReader::new(File::open(path)?));
    43     let (info, mut reader) = decoder.read_info()?;
    78     let (info, mut reader) = decoder.read_info()?;
    44 
    79 
    45     let size = Size::new(info.width as usize, info.height as usize);
    80     let size = Size::new(info.width as usize, info.height as usize);
    46     Ok(size)
    81     Ok(size)
    47 }
    82 }
    48 
    83 
    49 fn load_sprites(path: &Path) -> io::Result<Vec<Size>> {
    84 fn load_sprites(path: &Path) -> io::Result<Vec<SpriteData>> {
    50     let mut result = vec![];
    85     let mut result = vec![];
    51     for file in read_dir(path)? {
    86     for file in read_dir(path)? {
    52         let file = file?;
    87         let file = file?;
    53         if let Some(extension) = file.path().extension() {
    88         if let Some(extension) = file.path().extension() {
    54             if extension == "png" {
    89             if extension == "png" {
    55                 let sprite = load_sprite(&file.path())?;
    90                 let path = file.path();
    56                 result.push(sprite);
    91                 let sprite = load_sprite_size(&path)?;
       
    92                 result.push(SpriteData {
       
    93                     size: sprite,
       
    94                     filename: path,
       
    95                 });
    57             }
    96             }
    58         }
    97         }
    59     }
    98     }
    60     Ok(result)
    99     Ok(result)
    61 }
   100 }