rust/lib-hedgewars-engine/src/render/gear.rs
changeset 15759 c929e25a7da2
parent 15291 07ab4206f2a9
child 15760 ff1432e873bd
equal deleted inserted replaced
15758:6c939e6de981 15759:c929e25a7da2
     1 use super::{atlas::AtlasCollection, gl::Texture2D};
     1 use crate::render::{
     2 use crate::render::camera::Camera;
     2     atlas::{AtlasCollection, SpriteIndex, SpriteLocation},
       
     3     camera::Camera,
       
     4     gl::Texture2D,
       
     5 };
     3 
     6 
     4 use integral_geometry::{Rect, Size};
     7 use integral_geometry::{Rect, Size};
     5 
     8 
     6 use crate::render::atlas::SpriteIndex;
       
     7 use png::{ColorType, Decoder, DecodingError};
     9 use png::{ColorType, Decoder, DecodingError};
     8 use std::path::PathBuf;
    10 
     9 use std::{
    11 use std::{
    10     collections::HashMap,
    12     collections::HashMap,
    11     ffi::OsString,
    13     ffi::OsString,
    12     fs::{read_dir, File},
    14     fs::{read_dir, File},
    13     io,
    15     io,
    14     io::BufReader,
    16     io::BufReader,
    15     path::Path,
    17     path::{Path, PathBuf},
    16 };
    18 };
       
    19 
       
    20 #[derive(PartialEq, Debug, Clone, Copy)]
       
    21 enum SpriteId {
       
    22     Mine = 0,
       
    23     Grenade,
       
    24 
       
    25     MaxSprite,
       
    26 }
       
    27 
       
    28 const SPRITE_LOAD_LIST: &[(SpriteId, &str)] = &[
       
    29     (
       
    30         SpriteId::Mine,
       
    31         "../../share/hedgewars/Data/Graphics/MineOn.png",
       
    32     ),
       
    33     (
       
    34         SpriteId::Grenade,
       
    35         "../../share/hedgewars/Data/Graphics/Bomb.png",
       
    36     ),
       
    37 ];
       
    38 
       
    39 const MAX_SPRITES: usize = SpriteId::MaxSprite as usize + 1;
    17 
    40 
    18 pub struct GearRenderer {
    41 pub struct GearRenderer {
    19     atlas: AtlasCollection,
    42     atlas: AtlasCollection,
       
    43     allocation: Box<[SpriteLocation; MAX_SPRITES]>,
    20 }
    44 }
    21 
    45 
    22 struct SpriteData {
    46 struct SpriteData {
    23     size: Size,
    47     size: Size,
    24     filename: PathBuf,
    48     filename: PathBuf,
    26 
    50 
    27 const ATLAS_SIZE: Size = Size::square(2048);
    51 const ATLAS_SIZE: Size = Size::square(2048);
    28 
    52 
    29 impl GearRenderer {
    53 impl GearRenderer {
    30     pub fn new() -> Self {
    54     pub fn new() -> Self {
    31         let mut lookup = Vec::with_capacity(2048);
       
    32 
       
    33         let mut atlas = AtlasCollection::new(ATLAS_SIZE);
    55         let mut atlas = AtlasCollection::new(ATLAS_SIZE);
    34         let mut sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
       
    35             .expect("Unable to load Graphics");
       
    36         let max_size = sprites
       
    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()));
       
    41         }
       
    42 
       
    43         println!(
       
    44             "Filled atlas with {} sprites:\n{}",
       
    45             sprites.len(),
       
    46             atlas.used_space()
       
    47         );
       
    48 
    56 
    49         let texture = Texture2D::new(ATLAS_SIZE, gl::RGBA8, gl::LINEAR);
    57         let texture = Texture2D::new(ATLAS_SIZE, gl::RGBA8, gl::LINEAR);
    50 
    58 
    51         let mut pixels = vec![0; max_size.area()].into_boxed_slice();
    59         let mut allocation = Box::new([(0, Rect::at_origin(Size::EMPTY)); MAX_SPRITES]);
    52         let mut pixels_transposed = vec![0; max_size.area()].into_boxed_slice();
       
    53 
    60 
    54         for (path, sprite_index) in lookup.drain(..) {
    61         for (sprite, file) in SPRITE_LOAD_LIST {
    55             if let Some((atlas_index, rect)) = atlas.get_rect(sprite_index) {
    62             let path = Path::new(file);
    56                 let size = load_sprite_pixels(&path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..])).expect("Unable to load Graphics");
    63             let size = load_sprite_size(path).expect(&format!("Unable to open {}", file));
       
    64             let index = atlas
       
    65                 .insert_sprite(size)
       
    66                 .expect(&format!("Could not store sprite {:?}", sprite));
       
    67             let (texture_index, rect) = atlas.get_rect(index).unwrap();
    57 
    68 
    58                 let used_pixels = if size.width != rect.width() {
    69             let mut pixels = vec![0; size.area()].into_boxed_slice();
    59                     for y in 0..rect.height() {
    70             load_sprite_pixels(path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]))
    60                         for x in 0..rect.width() {
    71                 .expect("Unable to load Graphics");
    61                             pixels_transposed[y * rect.width() + x] = pixels[x * rect.height() + y];
       
    62                         }
       
    63                     }
       
    64                     &mut pixels_transposed[..]
       
    65                 } else {
       
    66                     &mut pixels[..]
       
    67                 };
       
    68 
    72 
    69                 texture.update(rect, mapgen::theme::slice_u32_to_u8_mut(used_pixels), 0, gl::RGBA, gl::UNSIGNED_BYTE);
    73             texture.update(
    70             }
    74                 rect,
       
    75                 mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]),
       
    76                 0,
       
    77                 gl::RGBA,
       
    78                 gl::UNSIGNED_BYTE,
       
    79             );
       
    80 
       
    81             allocation[*sprite as usize] = (texture_index, rect);
    71         }
    82         }
    72 
    83 
    73         Self { atlas }
    84         Self { atlas, allocation }
    74     }
    85     }
    75 
    86 
    76     pub fn render(&mut self, camera: &Camera) {
    87     pub fn render(&mut self, camera: &Camera) {
    77         let projection = camera.projection();
    88         let projection = camera.projection();
    78     }
    89     }