diff -r 6c939e6de981 -r c929e25a7da2 rust/lib-hedgewars-engine/src/render/gear.rs --- a/rust/lib-hedgewars-engine/src/render/gear.rs Wed Nov 11 22:41:31 2020 +0300 +++ b/rust/lib-hedgewars-engine/src/render/gear.rs Thu Nov 12 00:24:58 2020 +0300 @@ -1,22 +1,46 @@ -use super::{atlas::AtlasCollection, gl::Texture2D}; -use crate::render::camera::Camera; +use crate::render::{ + atlas::{AtlasCollection, SpriteIndex, SpriteLocation}, + camera::Camera, + gl::Texture2D, +}; use integral_geometry::{Rect, Size}; -use crate::render::atlas::SpriteIndex; use png::{ColorType, Decoder, DecodingError}; -use std::path::PathBuf; + use std::{ collections::HashMap, ffi::OsString, fs::{read_dir, File}, io, io::BufReader, - path::Path, + path::{Path, PathBuf}, }; +#[derive(PartialEq, Debug, Clone, Copy)] +enum SpriteId { + Mine = 0, + Grenade, + + MaxSprite, +} + +const SPRITE_LOAD_LIST: &[(SpriteId, &str)] = &[ + ( + SpriteId::Mine, + "../../share/hedgewars/Data/Graphics/MineOn.png", + ), + ( + SpriteId::Grenade, + "../../share/hedgewars/Data/Graphics/Bomb.png", + ), +]; + +const MAX_SPRITES: usize = SpriteId::MaxSprite as usize + 1; + pub struct GearRenderer { atlas: AtlasCollection, + allocation: Box<[SpriteLocation; MAX_SPRITES]>, } struct SpriteData { @@ -28,49 +52,36 @@ impl GearRenderer { pub fn new() -> Self { - let mut lookup = Vec::with_capacity(2048); - let mut atlas = AtlasCollection::new(ATLAS_SIZE); - let mut sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/")) - .expect("Unable to load Graphics"); - let max_size = sprites - .iter() - .fold(Size::EMPTY, |size, sprite| size.join(sprite.size)); - for sprite in sprites.drain(..) { - lookup.push((sprite.filename, atlas.insert_sprite(sprite.size).unwrap())); - } - - println!( - "Filled atlas with {} sprites:\n{}", - sprites.len(), - atlas.used_space() - ); let texture = Texture2D::new(ATLAS_SIZE, gl::RGBA8, gl::LINEAR); - let mut pixels = vec![0; max_size.area()].into_boxed_slice(); - let mut pixels_transposed = vec![0; max_size.area()].into_boxed_slice(); + let mut allocation = Box::new([(0, Rect::at_origin(Size::EMPTY)); MAX_SPRITES]); - for (path, sprite_index) in lookup.drain(..) { - if let Some((atlas_index, rect)) = atlas.get_rect(sprite_index) { - let size = load_sprite_pixels(&path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..])).expect("Unable to load Graphics"); + for (sprite, file) in SPRITE_LOAD_LIST { + let path = Path::new(file); + let size = load_sprite_size(path).expect(&format!("Unable to open {}", file)); + let index = atlas + .insert_sprite(size) + .expect(&format!("Could not store sprite {:?}", sprite)); + let (texture_index, rect) = atlas.get_rect(index).unwrap(); - let used_pixels = if size.width != rect.width() { - for y in 0..rect.height() { - for x in 0..rect.width() { - pixels_transposed[y * rect.width() + x] = pixels[x * rect.height() + y]; - } - } - &mut pixels_transposed[..] - } else { - &mut pixels[..] - }; + 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"); - texture.update(rect, mapgen::theme::slice_u32_to_u8_mut(used_pixels), 0, gl::RGBA, gl::UNSIGNED_BYTE); - } + texture.update( + rect, + mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]), + 0, + gl::RGBA, + gl::UNSIGNED_BYTE, + ); + + allocation[*sprite as usize] = (texture_index, rect); } - Self { atlas } + Self { atlas, allocation } } pub fn render(&mut self, camera: &Camera) {