fill the atlas with sprites
authoralfadur
Sat, 22 Jun 2019 00:18:24 +0300
changeset 15195 e2adb40c7988
parent 15194 ff397798e812
child 15196 0e8bb82af355
fill the atlas with sprites
rust/lib-hedgewars-engine/Cargo.toml
rust/lib-hedgewars-engine/src/render/atlas.rs
rust/lib-hedgewars-engine/src/render/gear.rs
rust/lib-hedgewars-engine/src/world.rs
--- a/rust/lib-hedgewars-engine/Cargo.toml	Fri Jun 21 20:27:37 2019 +0200
+++ b/rust/lib-hedgewars-engine/Cargo.toml	Sat Jun 22 00:18:24 2019 +0300
@@ -8,6 +8,7 @@
 gl = "0.11"
 netbuf = "0.4"
 itertools = "0.8"
+png = "0.13"
 
 fpnum = { path = "../fpnum" }
 land2d = { path = "../land2d" }
--- a/rust/lib-hedgewars-engine/src/render/atlas.rs	Fri Jun 21 20:27:37 2019 +0200
+++ b/rust/lib-hedgewars-engine/src/render/atlas.rs	Sat Jun 22 00:18:24 2019 +0300
@@ -65,7 +65,7 @@
         write!(
             f,
             "{:.2}%",
-            self.used() as f32 / self.total() as f32 / 100.0
+            self.used() as f32 / self.total() as f32 * 100.0
         )?;
         Ok(())
     }
@@ -249,6 +249,14 @@
             self.consume_index()
         }
     }
+
+    pub fn used_space(&self) -> String {
+        self.atlases
+            .iter()
+            .enumerate()
+            .map(|(i, a)| format!("{}: {:?}", i, a.used_space()))
+            .join("\n")
+    }
 }
 
 impl Index<SpriteIndex> for AtlasCollection {
--- a/rust/lib-hedgewars-engine/src/render/gear.rs	Fri Jun 21 20:27:37 2019 +0200
+++ b/rust/lib-hedgewars-engine/src/render/gear.rs	Sat Jun 22 00:18:24 2019 +0300
@@ -1,15 +1,61 @@
 use super::atlas::AtlasCollection;
+use crate::render::camera::Camera;
+
 use integral_geometry::Size;
 
-struct GearRenderer {
+use png::{ColorType, Decoder, DecodingError};
+use std::{
+    fs::{read_dir, File},
+    io,
+    io::BufReader,
+    path::Path,
+};
+
+pub struct GearRenderer {
     atlas: AtlasCollection,
 }
 
-const ATLAS_SIZE: Size = Size::square(2048);
+const ATLAS_SIZE: Size = Size::square(1024);
 
 impl GearRenderer {
     pub fn new() -> Self {
-        let atlas = AtlasCollection::new(ATLAS_SIZE);
+        let mut atlas = AtlasCollection::new(ATLAS_SIZE);
+        let sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
+            .expect("Unable to load Graphics");
+        for sprite in &sprites {
+            atlas.insert_sprite(*sprite);
+        }
+        println!(
+            "Filled atlas with {} sprites:\n{}",
+            sprites.len(),
+            atlas.used_space()
+        );
         Self { atlas }
     }
+
+    pub fn render(&mut self, camera: &Camera) {
+        let projection = camera.projection();
+    }
 }
+
+fn load_sprite(path: &Path) -> io::Result<Size> {
+    let decoder = Decoder::new(BufReader::new(File::open(path)?));
+    let (info, mut reader) = decoder.read_info()?;
+
+    let size = Size::new(info.width as usize, info.height as usize);
+    Ok(size)
+}
+
+fn load_sprites(path: &Path) -> io::Result<Vec<Size>> {
+    let mut result = vec![];
+    for file in read_dir(path)? {
+        let file = file?;
+        if let Some(extension) = file.path().extension() {
+            if extension == "png" {
+                let sprite = load_sprite(&file.path())?;
+                result.push(sprite);
+            }
+        }
+    }
+    Ok(result)
+}
--- a/rust/lib-hedgewars-engine/src/world.rs	Fri Jun 21 20:27:37 2019 +0200
+++ b/rust/lib-hedgewars-engine/src/world.rs	Sat Jun 22 00:18:24 2019 +0300
@@ -8,7 +8,7 @@
 };
 use lfprng::LaggedFibonacciPRNG;
 
-use crate::render::{camera::Camera, MapRenderer};
+use crate::render::{camera::Camera, GearRenderer, MapRenderer};
 
 struct GameState {
     land: Land2D<u32>,
@@ -25,7 +25,8 @@
     random_numbers_gen: LaggedFibonacciPRNG,
     preview: Option<Land2D<u8>>,
     game_state: Option<GameState>,
-    renderer: Option<MapRenderer>,
+    map_renderer: Option<MapRenderer>,
+    gear_renderer: Option<GearRenderer>,
     camera: Camera,
     last_gear_id: GearId,
 }
@@ -36,7 +37,8 @@
             random_numbers_gen: LaggedFibonacciPRNG::new(&[]),
             preview: None,
             game_state: None,
-            renderer: None,
+            map_renderer: None,
+            gear_renderer: None,
             camera: Camera::new(),
             last_gear_id: GearId::default(),
         }
@@ -44,7 +46,8 @@
 
     pub fn create_renderer(&mut self, width: u16, height: u16) {
         let land_tile_size = Size::square(512);
-        self.renderer = Some(MapRenderer::new(land_tile_size));
+        self.map_renderer = Some(MapRenderer::new(land_tile_size));
+        self.gear_renderer = Some(GearRenderer::new());
         self.camera = Camera::with_size(Size::new(width as usize, height as usize));
 
         use mapgen::{theme::Theme, MapGenerator};
@@ -56,7 +59,7 @@
             let theme =
                 Theme::load(Path::new("../../share/hedgewars/Data/Themes/Cheese/")).unwrap();
             let texture = MapGenerator::new().make_texture(&state.land, &theme);
-            if let Some(ref mut renderer) = self.renderer {
+            if let Some(ref mut renderer) = self.map_renderer {
                 renderer.init(&texture);
             }
         }
@@ -112,7 +115,7 @@
     }
 
     pub fn render(&mut self) {
-        if let Some(ref mut renderer) = self.renderer {
+        if let Some(ref mut renderer) = self.map_renderer {
             unsafe {
                 gl::ClearColor(0.4f32, 0f32, 0.2f32, 1f32);
                 gl::Clear(gl::COLOR_BUFFER_BIT);
@@ -120,6 +123,9 @@
 
             renderer.render(&self.camera);
         }
+        if let Some(ref mut renderer) = self.gear_renderer {
+            renderer.render(&self.camera)
+        }
     }
 
     fn get_unused_gear_id(&mut self) -> GearId {