Skip to content

Commit

Permalink
support dds and bmp now
Browse files Browse the repository at this point in the history
  • Loading branch information
rfuzzo committed Jun 7, 2024
1 parent 1b0faa9 commit ef96777
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tes3map"
version = "0.2.0"
version = "0.2.1"
authors = ["Moritz Baron <[email protected]>"]
edition = "2021"

Expand Down
Binary file added assets/ui_conflicts_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ui_landscape_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 40 additions & 37 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub struct TemplateApp {
#[serde(skip)]
pub texture_map_resolution: usize,
#[serde(skip)]
pub texture_map: HashMap<u32, ColorImage>,
pub texture_map: HashMap<String, ColorImage>,

// runtime data
#[serde(skip)]
Expand Down Expand Up @@ -157,45 +157,47 @@ impl TemplateApp {

let key = data[dy][dx] as u32;

// lazy load texture
if let std::collections::hash_map::Entry::Vacant(e) =
self.texture_map.entry(key)
{
// load texture
if let Some(ltex) = self.ltex_records.get(&key) {
if let Some(tex) = load_texture(&self.data_files, ltex)
{
// transform texture and downsize

// scale texture to fit the texture_size
let mut pixels = vec![
Color32::TRANSPARENT;
texture_size * texture_size
];

// textures per tile
for x in 0..texture_size {
for y in 0..texture_size {
// pick every nth pixel from the texture to downsize
let sx =
x * (TEXTURE_MAX_SIZE / texture_size);
let sy =
y * (TEXTURE_MAX_SIZE / texture_size);
let index = (sy * texture_size) + sx;
let color = tex.pixels[index];

let i = (y * texture_size) + x;
pixels[i] = color;
}
// load texture
if let Some(ltex) = self.ltex_records.get(&key) {
// texture name
let texture_name = ltex.file_name.clone();
if self.texture_map.contains_key(&texture_name) {
continue;
}

if let Some(tex) = load_texture(&self.data_files, ltex) {
// transform texture and downsize

// scale texture to fit the texture_size
let mut pixels = vec![
Color32::TRANSPARENT;
texture_size * texture_size
];

// textures per tile
for x in 0..texture_size {
for y in 0..texture_size {
// pick every nth pixel from the texture to downsize
let sx = x * (TEXTURE_MAX_SIZE / texture_size);
let sy = y * (TEXTURE_MAX_SIZE / texture_size);
let index = (sy * texture_size) + sx;
let color = tex.pixels[index];

let i = (y * texture_size) + x;
pixels[i] = color;
}
}

let downsized_texture = ColorImage {
size: [texture_size, texture_size],
pixels,
};
let downsized_texture = ColorImage {
size: [texture_size, texture_size],
pixels,
};

e.insert(downsized_texture);
}
info!("Loaded texture: {}", ltex.file_name);
self.texture_map
.insert(texture_name, downsized_texture);
} else {
error!("Failed to load texture: {}", ltex.file_name);
}
}
}
Expand Down Expand Up @@ -275,6 +277,7 @@ impl TemplateApp {
if let Some(i) = compute_landscape_image(
dimensions,
&self.land_records,
&self.ltex_records,
&self.heights,
&self.texture_map,
) {
Expand Down
18 changes: 13 additions & 5 deletions src/background/landscape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ use std::collections::HashMap;

use egui::{Color32, ColorImage};
use log::info;
use tes3::esp::{Landscape, LandscapeFlags};
use tes3::esp::{Landscape, LandscapeFlags, LandscapeTexture};

use crate::{
CellKey, DEFAULT_COLOR, Dimensions, GRID_SIZE, height_from_screen_space,
overlay_colors_with_alpha, VERTEX_CNT,
height_from_screen_space, overlay_colors_with_alpha, CellKey, Dimensions, DEFAULT_COLOR,
GRID_SIZE, VERTEX_CNT,
};

/// Compute a landscape image from the given landscape records and texture map.
pub fn compute_landscape_image(
dimensions: &Dimensions,
landscape_records: &HashMap<CellKey, Landscape>,
ltex_records: &HashMap<u32, LandscapeTexture>,
heights: &[f32],
texture_map: &HashMap<u32, ColorImage>,
texture_map: &HashMap<String, ColorImage>,
) -> Option<ColorImage> {
let d = dimensions;
let size = d.pixel_size(d.cell_size());
Expand Down Expand Up @@ -43,8 +44,15 @@ pub fn compute_landscape_image(
let dy = (4 * (gy / 4)) + (gx / 4);

let key = data[dy][dx] as u32;
let mut texture_name = String::new();
if let Some(ltex) = ltex_records.get(&key) {
texture_name.clone_from(&ltex.file_name);
}
if texture_name.is_empty() {
continue;
}

if let Some(texture) = texture_map.get(&key) {
if let Some(texture) = texture_map.get(&texture_name) {
for x in 0..d.texture_size {
for y in 0..d.texture_size {
let index = (y * d.texture_size) + x;
Expand Down
43 changes: 34 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use std::{

use egui::{Color32, ColorImage, Pos2};
use image::{
DynamicImage,
error::{ImageFormatHint, UnsupportedError, UnsupportedErrorKind}, ImageError, RgbaImage,
error::{ImageFormatHint, UnsupportedError, UnsupportedErrorKind},
DynamicImage, ImageError, RgbaImage,
};
use log::info;
use log::{info, warn};
use seahash::hash;
use serde::{Deserialize, Serialize};
use tes3::esp::{
Expand Down Expand Up @@ -343,28 +343,54 @@ pub fn get_layered_image(dimensions: &Dimensions, img: ColorImage, img2: ColorIm
}

fn load_texture(data_files: &Option<PathBuf>, ltex: &LandscapeTexture) -> Option<ColorImage> {
// data files
let data_files = data_files.as_ref()?;

let texture = ltex.file_name.clone();
let tex_path = data_files.join("Textures").join(texture);
if !tex_path.exists() {
let _tex_path = data_files.join("Textures").join(ltex.file_name.clone());

let tga_path = _tex_path.with_extension("tga");
let dds_path = _tex_path.with_extension("dds");
let bmp_path = _tex_path.with_extension("bmp");

if !tga_path.exists() && !dds_path.exists() && !bmp_path.exists() {
warn!("Texture not found: {:?}", _tex_path);
return None;
}

// decode image
if let Some(value) = decode_image(dds_path) {
return Some(value);
}
if let Some(value) = decode_image(tga_path) {
return Some(value);
}
if let Some(value) = decode_image(bmp_path) {
return Some(value);
}

None
}

fn decode_image(tex_path: PathBuf) -> Option<ColorImage> {
if let Ok(mut reader) = image::io::Reader::open(&tex_path) {
let ext = tex_path.extension().unwrap().to_string_lossy();
let ext = tex_path
.extension()
.unwrap()
.to_string_lossy()
.to_lowercase();
if ext.contains("tga") {
reader.set_format(image::ImageFormat::Tga);
} else if ext.contains("dds") {
reader.set_format(image::ImageFormat::Dds);
} else if ext.contains("bmp") {
reader.set_format(image::ImageFormat::Bmp);
} else {
// not supported
warn!("Texture format not supported: {:?}", tex_path);
return None;
}

let Ok(image) = reader.decode() else {
log::error!("Error decoding texture: {:?}", tex_path);
return None;
};

Expand All @@ -373,7 +399,6 @@ fn load_texture(data_files: &Option<PathBuf>, ltex: &LandscapeTexture) -> Option
let pixels = image_buffer.as_flat_samples();
return Some(ColorImage::from_rgba_unmultiplied(size, pixels.as_slice()));
}

None
}

Expand Down

0 comments on commit ef96777

Please sign in to comment.