rust/lib-hedgewars-engine/src/render/gear.rs
changeset 15286 16bd389fc735
parent 15190 e2adb40c7988
child 15288 0f734fa371e1
--- a/rust/lib-hedgewars-engine/src/render/gear.rs	Sat Aug 03 00:54:29 2019 +0300
+++ b/rust/lib-hedgewars-engine/src/render/gear.rs	Sat Aug 03 01:13:45 2019 +0300
@@ -1,10 +1,14 @@
-use super::atlas::AtlasCollection;
+use super::{atlas::AtlasCollection, gl::Texture2D};
 use crate::render::camera::Camera;
 
-use integral_geometry::Size;
+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,
@@ -15,21 +19,43 @@
     atlas: AtlasCollection,
 }
 
-const ATLAS_SIZE: Size = Size::square(1024);
+struct SpriteData {
+    size: Size,
+    filename: PathBuf,
+}
+
+const ATLAS_SIZE: Size = Size::square(2024);
 
 impl GearRenderer {
     pub fn new() -> Self {
+        let mut lookup = Vec::with_capacity(2048);
+
         let mut atlas = AtlasCollection::new(ATLAS_SIZE);
-        let sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
+        let mut sprites = load_sprites(Path::new("../../share/hedgewars/Data/Graphics/"))
             .expect("Unable to load Graphics");
-        for sprite in &sprites {
-            atlas.insert_sprite(*sprite);
+        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(max_size, gl::RGBA8, gl::LINEAR);
+
+        let mut pixels = Vec::with_capacity(max_size.area()).into_boxed_slice();
+        for (path, sprite_index) in lookup.drain(..) {
+            if let Some((atlas_index, rect)) = atlas.get_rect(sprite_index) {
+                load_sprite_pixels(&path, &mut pixels[..]).expect("Unable to load Graphics");
+                texture.update(rect, &pixels, 0, gl::RGBA, gl::UNSIGNED_BYTE);
+            }
+        }
+
         Self { atlas }
     }
 
@@ -38,7 +64,16 @@
     }
 }
 
-fn load_sprite(path: &Path) -> io::Result<Size> {
+fn load_sprite_pixels(path: &Path, buffer: &mut [u8]) -> io::Result<()> {
+    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);
+    reader.next_frame(buffer)?;
+    Ok(())
+}
+
+fn load_sprite_size(path: &Path) -> io::Result<Size> {
     let decoder = Decoder::new(BufReader::new(File::open(path)?));
     let (info, mut reader) = decoder.read_info()?;
 
@@ -46,14 +81,18 @@
     Ok(size)
 }
 
-fn load_sprites(path: &Path) -> io::Result<Vec<Size>> {
+fn load_sprites(path: &Path) -> io::Result<Vec<SpriteData>> {
     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);
+                let path = file.path();
+                let sprite = load_sprite_size(&path)?;
+                result.push(SpriteData {
+                    size: sprite,
+                    filename: path,
+                });
             }
         }
     }