Loading assets listed in file,g hash for assets ids

This commit is contained in:
Piotr Siuszko 2021-09-11 21:25:52 +02:00
parent de94391295
commit 776ffb3a32
5 changed files with 515 additions and 412 deletions

829
doppler/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,75 @@
use crate::mesh::Texture;
use crate::model::Model;
use crate::utils::load_texture_from_dir;
use log::info;
use log::{info, error};
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
#[derive(Default)]
pub struct AssetsCache {
textures: HashMap<String, Texture>,
models: HashMap<String, Model>,
textures: HashMap<u64, Texture>,
models: HashMap<u64, Model>
}
impl AssetsCache {
pub fn get_model(&mut self, path: &str) -> Model {
match self.models.get(path) {
Some(model) => model.clone(),
None => {
info!("Loading model: {}", path);
let model = Model::new(path, self);
self.models.insert(path.to_string(), model.clone());
model
}
pub fn load_all_from_file(&mut self, path: &str) {
let path = std::path::Path::new(path);
let meta = std::fs::metadata(path);
if !meta.is_ok() {
error!("There is no assets file");
return;
}
use std::fs;
use std::io::prelude::*;
use std::io::BufReader;
let buf = BufReader::new(fs::File::open(path).expect("no such file"));
let lines: Vec<String> = buf
.lines()
.map(|l| l.expect("Could not parse line"))
.collect();
for line in lines {
let mut splitted = line.split_whitespace();
let id = splitted.next();
let path = splitted.next();
if id.is_none() || path.is_none() || self.has_model(&path.unwrap()) {
error!("Skip wrong line: {}", line);
continue;
}
let texture = splitted.next();
self.load_model_ext(path.unwrap(), texture);
info!("Added model {} from path {}", id.unwrap(), path.unwrap());
}
}
pub fn has_model(&self, path: &str) -> bool {
self.models.contains_key(&Self::to_hash(path))
}
pub fn get_model(&mut self, path: &str) -> Model {
self.get_model_ext(path, None)
}
pub fn get_model_ext(&mut self, path: &str, diff_texture: Option<&str>) -> Model {
match self.models.get(path) {
match self.models.get(&Self::to_hash(path)) {
Some(model) => model.clone(),
None => {
info!("Loading model: {}", path);
let model = Model::new_ext(path, diff_texture, self);
self.models.insert(path.to_string(), model.clone());
model
self.load_model_ext(path, diff_texture);
self.get_model_ext(path,diff_texture)
}
}
}
fn load_model_ext(&mut self, path: &str, diff_texture: Option<&str>) {
let hash = Self::to_hash(path);
info!("Loading model: {}({})", path, hash);
let model = Model::new_ext(path, diff_texture, self);
self.models.insert(hash, model);
}
pub fn get_material_texture(&mut self, dir: &str, path: &str, type_name: &str) -> Texture {
match self.textures.get(path) {
match self.textures.get(&Self::to_hash(path)) {
Some(texture) => texture.clone(),
None => {
let directory: String = dir.into();
@ -45,9 +78,15 @@ impl AssetsCache {
type_: type_name.into(),
path: path.into(),
};
self.textures.insert(path.to_string(), texture.clone());
self.textures.insert(Self::to_hash(path), texture.clone());
texture
}
}
}
fn to_hash(path: &str) -> u64 {
let mut hasher = DefaultHasher::new();
path.hash(&mut hasher);
hasher.finish()
}
}

View File

@ -217,6 +217,7 @@ impl Engine {
let mut last_frame = std::time::Instant::now();
let mut screensize = self.size;
info!("Assets loaded");
event_loop.run(move |event, _, control_flow| {
use glutin::event_loop::ControlFlow;
@ -310,7 +311,6 @@ impl Engine {
#[cfg(feature = "imgui_inspect")]
if self.debug_layer {
let frames_vec = timestep.frames();
imgui.io_mut().display_size = [screensize.0 as f32, screensize.1 as f32];
let imgui_size = imgui.io().display_size;

View File

@ -17,6 +17,12 @@ pub struct Model {
directory: String,
}
impl Default for Model {
fn default() -> Self {
Model { meshes: Vec::new(), textures_loaded: Vec::new(), directory: "".to_string() }
}
}
impl Model {
/// constructor, expects a filepath to a 3D model.
pub fn new_ext(path: &str, diff_texture: Option<&str>, cache: &mut AssetsCache) -> Model {
@ -120,7 +126,7 @@ impl Model {
}
// NOTE: no height maps
} else if diffuse_path.is_some() {
// println!("Loading {}", &diffuse_path.unwrap());
println!("Loading {}", &diffuse_path.unwrap());
let texture = cache.get_material_texture(
&self.directory,
&diffuse_path.unwrap(),

View File

@ -14,9 +14,14 @@ pub unsafe fn load_texture(path: &str, file_format: &str) -> u32 {
let mut id = 0;
gl::GenTextures(1, &mut id);
let content = io::read_u8(path);
if content.is_err() {
error!("Error: {:?}",content.err());
panic!();
}
let (data, dim, format) = match file_format {
"png" => {
let img: ImagePtr<u8, Rgba> = io::read_u8(path).unwrap();
let img: ImagePtr<u8, Rgba> = content.unwrap();
let img_data = img.data().to_vec();
let (x, y, _) = img.shape();