summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-24 03:43:26 +0200
committerLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-24 05:32:41 +0200
commit03c459695021b41f4986707a0fd5d42cd2d31169 (patch)
treef0b4738915cc3edad35685b54459cdd78547bf0d /src
parent46ef7a60b3c88799fd8dfb2faf7c9f1dfb22b964 (diff)
downloadmt_client-03c459695021b41f4986707a0fd5d42cd2d31169.tar.xz
Move texture creation to media.rs
Diffstat (limited to 'src')
-rw-r--r--src/gfx/map/atlas.rs42
-rw-r--r--src/gfx/media.rs46
2 files changed, 49 insertions, 39 deletions
diff --git a/src/gfx/map/atlas.rs b/src/gfx/map/atlas.rs
index 920fbb4..7bcc53f 100644
--- a/src/gfx/map/atlas.rs
+++ b/src/gfx/map/atlas.rs
@@ -1,61 +1,25 @@
use super::{super::media::MediaMgr, AtlasSlice, CUBE};
use mt_net::NodeDef;
-use rand::Rng;
use std::collections::HashMap;
pub(super) fn create_atlas(
nodes: &mut HashMap<u16, NodeDef>,
media: &MediaMgr,
) -> (image::RgbaImage, Vec<AtlasSlice>) {
- let mut rng = rand::thread_rng();
let mut allocator = guillotiere::SimpleAtlasAllocator::new(guillotiere::size2(1, 1));
let mut textures = Vec::new();
+ let mut id_map = HashMap::new();
+
for node in nodes.values_mut() {
let tiles = std::iter::empty()
.chain(node.tiles.iter_mut())
.chain(node.overlay_tiles.iter_mut())
.chain(node.special_tiles.iter_mut());
- let load_texture = |texture: &str| {
- let payload = media
- .get(texture)
- .ok_or_else(|| format!("texture not found: {texture}"))?;
-
- image::load_from_memory(payload)
- .or_else(|_| image::load_from_memory_with_format(payload, image::ImageFormat::Tga))
- .map_err(|e| format!("failed to load texture {texture}: {e}"))
- .map(|x| image::imageops::flip_vertical(&x))
- };
-
- let mut make_texture = |texture: &str| {
- texture
- .split('^')
- .map(|part| match load_texture(part) {
- Ok(v) => v,
- Err(e) => {
- if !texture.is_empty() && !texture.contains('[') {
- eprintln!("{e}");
- }
-
- let mut img = image::RgbImage::new(1, 1);
- rng.fill(&mut img.get_pixel_mut(0, 0).0);
-
- image::DynamicImage::from(img).to_rgba8()
- }
- })
- .reduce(|mut base, top| {
- image::imageops::overlay(&mut base, &top, 0, 0);
- base
- })
- .unwrap()
- };
-
- let mut id_map = HashMap::new();
-
for tile in tiles {
tile.texture.custom = *id_map.entry(tile.texture.name.clone()).or_insert_with(|| {
- let img = make_texture(&tile.texture.name);
+ let img = media.texture_string(&tile.texture.name);
let dimensions = img.dimensions();
let size = guillotiere::size2(dimensions.0 as i32, dimensions.1 as i32);
diff --git a/src/gfx/media.rs b/src/gfx/media.rs
index ac5d158..eca2fcd 100644
--- a/src/gfx/media.rs
+++ b/src/gfx/media.rs
@@ -1,3 +1,4 @@
+use rand::Rng;
use std::collections::HashMap;
#[derive(rust_embed::RustEmbed)]
@@ -39,4 +40,49 @@ impl MediaMgr {
.find_map(|pack| pack.get(file))
.map(Vec::as_slice)
}
+
+ pub fn texture(&self, texture: &str) -> image::RgbaImage {
+ match match self.get(texture) {
+ Some(payload) => image::load_from_memory(payload)
+ .or_else(|_| image::load_from_memory_with_format(payload, image::ImageFormat::Tga))
+ .map_err(|e| eprintln!("while loading {texture}: {e}"))
+ .ok(),
+ None => {
+ eprintln!("unknown texture: {texture}");
+ None
+ }
+ } {
+ Some(v) => image::imageops::flip_vertical(&v),
+ None => {
+ let mut img = image::RgbImage::new(1, 1);
+ rand::thread_rng().fill(&mut img.get_pixel_mut(0, 0).0);
+
+ image::DynamicImage::from(img).to_rgba8()
+ }
+ }
+ }
+
+ pub fn texture_string(&self, texture: &str) -> image::RgbaImage {
+ texture
+ .split('^')
+ .fold(None, |mut base, next| {
+ if let Some(overlay) = match next {
+ "" => Some(self.texture("no_texture.png")),
+ texmod if matches!(texmod.chars().next(), Some('[')) => {
+ eprintln!("unknown texture modifier: {texmod}");
+ None
+ }
+ texture => Some(self.texture(texture)),
+ } {
+ if let Some(base) = &mut base {
+ image::imageops::overlay(base, &overlay, 0, 0);
+ } else {
+ base = Some(overlay);
+ }
+ }
+
+ base
+ })
+ .unwrap()
+ }
}