diff --git a/src/example_client.rs b/src/example_client.rs index eec3b73..e77a4a0 100644 --- a/src/example_client.rs +++ b/src/example_client.rs @@ -6,6 +6,8 @@ use crate::gaia::engine::Engine; use crate::gaia::*; use cgmath::{perspective, vec3, Deg, Matrix4, Point3}; use imgui_glfw_rs::glfw; +use crate::gaia::assets_cache::AssetsCache; + pub struct ExampleClient { models: Vec, @@ -18,46 +20,11 @@ pub struct ExampleClient { impl ExampleClient { pub fn create() -> ExampleClient { - let tree = ModelComponent { - transform: Transform { - position: vec3(10.0, 0.0, 26.0), - scale: vec3(2.5, 2.5, 2.5), - ..Transform::default() - }, - model: model::Model::new_ext("resources/objects/tree/tree_6_d.obj", Some("tree_e.png")), - }; - let tree2 = ModelComponent { - transform: Transform { - position: vec3(-9.0, 0.0, -15.0), - scale: vec3(2.5, 2.5, 2.5), - ..Transform::default() - }, - model: model::Model::new_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png")), - }; - let tree3 = ModelComponent { - transform: Transform { - position: vec3(15.0, 0.0, -7.0), - scale: vec3(2.5, 2.5, 2.5), - ..Transform::default() - }, - model: model::Model::new_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png")), - }; - let ground = ModelComponent { - transform: Transform { - scale: vec3(0.5, 0.5, 0.5), - ..Transform::default() - }, - model: model::Model::new("resources/objects/ground/ground.obj"), - }; - let robot = ModelComponent { - transform: Transform::default(), - model: model::Model::new("resources/objects/robot/robot.obj"), - }; ExampleClient { object_info_id: 0, show_camera_info: true, show_object_info: false, - models: vec![tree, tree2, tree3, ground, robot], + models: vec![], camera: Camera { position: Point3::new(0.0, 8.0, 13.0), front: vec3(0.0, -0.4, -1.0), @@ -76,6 +43,45 @@ impl ExampleClient { } impl Client for ExampleClient { + fn load_assets(&mut self, cache: &mut AssetsCache) { + let ground = ModelComponent { + transform: Transform { + scale: vec3(0.5, 0.5, 0.5), + ..Transform::default() + }, + model: model::Model::new("resources/objects/ground/ground.obj",cache), + }; + let robot = ModelComponent { + transform: Transform::default(), + model: model::Model::new("resources/objects/robot/robot.obj",cache), + }; + let tree = ModelComponent { + transform: Transform { + position: vec3(10.0, 0.0, 26.0), + scale: vec3(2.5, 2.5, 2.5), + ..Transform::default() + }, + model: model::Model::new_ext("resources/objects/tree/tree_6_d.obj", Some("tree_e.png"),cache), + }; + let tree2 = ModelComponent { + transform: Transform { + position: vec3(-9.0, 0.0, -15.0), + scale: vec3(2.5, 2.5, 2.5), + ..Transform::default() + }, + model: model::Model::new_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png"),cache), + }; + let tree3 = ModelComponent { + transform: Transform { + position: vec3(15.0, 0.0, -7.0), + scale: vec3(2.5, 2.5, 2.5), + ..Transform::default() + }, + model: model::Model::new_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png"),cache), + }; + self.models = vec![tree, tree2, tree3, ground, robot]; + } + unsafe fn draw(&mut self) { self.shader.use_program(); diff --git a/src/gaia/assets_cache.rs b/src/gaia/assets_cache.rs new file mode 100644 index 0000000..8f8bb19 --- /dev/null +++ b/src/gaia/assets_cache.rs @@ -0,0 +1,28 @@ +use crate::gaia::utils::load_texture_from_dir; +use std::collections::HashMap; +use crate::gaia::mesh::Texture; +use std::path::Path; + +#[derive(Default)] +pub struct AssetsCache { + textures: HashMap +} + +impl AssetsCache { + pub fn load_material_texture(&mut self, dir: &str, path: &str, type_name: &str) -> Texture { + match self.textures.get(path) { + Some(texture) => texture.clone(), + None => { + let directory : String = dir.into(); + println!("{}",directory); + let texture = Texture { + id: unsafe { load_texture_from_dir(path, &directory) }, + type_: type_name.into(), + path: path.into(), + }; + self.textures.insert(path.to_string(),texture.clone()); + texture + } + } + } +} \ No newline at end of file diff --git a/src/gaia/client.rs b/src/gaia/client.rs index fd21125..7ee2c42 100644 --- a/src/gaia/client.rs +++ b/src/gaia/client.rs @@ -1,7 +1,9 @@ use crate::gaia::engine::Engine; use imgui_glfw_rs::glfw; +use crate::gaia::assets_cache::AssetsCache; pub trait Client { + fn load_assets(&mut self, cache: &mut AssetsCache); fn update(&mut self, engine: &mut Engine); fn process_input(&mut self, window: &glfw::Window, delta: f32); fn on_mouse_scroll(&mut self, yoffset: f32); diff --git a/src/gaia/engine.rs b/src/gaia/engine.rs index 6c71e26..120fa6b 100644 --- a/src/gaia/engine.rs +++ b/src/gaia/engine.rs @@ -3,6 +3,7 @@ use crate::gaia::bg_info::BgInfo; use crate::gaia::camera::*; use crate::gaia::client::Client; use crate::gaia::consts; +use crate::gaia::assets_cache::AssetsCache; use cgmath::Point3; use imgui_glfw_rs::glfw; use imgui_glfw_rs::glfw::{Action, Context, Key}; @@ -20,10 +21,12 @@ pub struct Engine { pub imgui_glfw: ImguiGLFW, pub client: Box, enable_debug_layer: bool, + assets_cache: AssetsCache, } impl Engine { pub fn run(&mut self) { + self.client.load_assets(&mut self.assets_cache); let mut first_mouse = true; let mut last_x: f32 = consts::SCR_WIDTH as f32 / 2.0; let mut last_y: f32 = consts::SCR_HEIGHT as f32 / 2.0; @@ -276,6 +279,7 @@ impl Default for Engine { }, enable_debug_layer: true, client: Box::new(ExampleClient::create()), + assets_cache: AssetsCache::default(), } } } diff --git a/src/gaia/mod.rs b/src/gaia/mod.rs index fe8b653..6899717 100644 --- a/src/gaia/mod.rs +++ b/src/gaia/mod.rs @@ -7,6 +7,7 @@ pub mod components; pub mod consts; pub mod engine; pub mod mesh; +pub mod assets_cache; pub mod model; pub mod shader; pub mod utils; diff --git a/src/gaia/model.rs b/src/gaia/model.rs index 4e41d81..4edb339 100644 --- a/src/gaia/model.rs +++ b/src/gaia/model.rs @@ -4,6 +4,7 @@ use crate::gaia::mesh::{Mesh, Texture, Vertex}; use crate::gaia::shader::Shader; use crate::gaia::utils::*; +use crate::gaia::assets_cache::AssetsCache; use cgmath::{vec2, vec3}; use std::path::Path; use tobj; @@ -18,7 +19,7 @@ pub struct Model { impl Model { /// constructor, expects a filepath to a 3D model. - pub fn new_ext(path: &str, diff_texture: Option<&str>) -> Model { + pub fn new_ext(path: &str, diff_texture: Option<&str>, cache: &mut AssetsCache) -> Model { let pathObj = Path::new(path); let mut model = Model { meshes: Vec::::new(), @@ -30,12 +31,12 @@ impl Model { .unwrap() .into(), }; - model.load_model(path, diff_texture); + model.load_model(path, diff_texture, cache); model } - pub fn new(path: &str) -> Model { - Model::new_ext(path, None) + pub fn new(path: &str, cache: &mut AssetsCache) -> Model { + Model::new_ext(path, None, cache) } pub fn Draw(&self, shader: &Shader) { @@ -47,7 +48,7 @@ impl Model { } // loads a model from file and stores the resulting meshes in the meshes vector. - fn load_model(&mut self, path: &str, diffuse_path: Option<&str>) { + fn load_model(&mut self, path: &str, diffuse_path: Option<&str>, cache: &mut AssetsCache) { let path = Path::new(path); println!("Started loading model from path: {}", path.display()); @@ -86,26 +87,25 @@ impl Model { // 1. diffuse map if !material.diffuse_texture.is_empty() { - let texture = - self.load_material_texture(&material.diffuse_texture, "texture_diffuse"); + let texture = cache.load_material_texture(&self.directory, &material.diffuse_texture, "texture_diffuse"); textures.push(texture); } // 2. specular map if !material.specular_texture.is_empty() { let texture = - self.load_material_texture(&material.specular_texture, "texture_specular"); + cache.load_material_texture(&self.directory, &material.specular_texture, "texture_specular"); textures.push(texture); } // 3. normal map if !material.normal_texture.is_empty() { let texture = - self.load_material_texture(&material.normal_texture, "texture_normal"); + cache.load_material_texture(&self.directory, &material.normal_texture, "texture_normal"); textures.push(texture); } // NOTE: no height maps } else if diffuse_path.is_some() { println!("Loading {}", &diffuse_path.unwrap()); - let texture = self.load_material_texture(&diffuse_path.unwrap(), "texture_diffuse"); + let texture = cache.load_material_texture(&self.directory, &diffuse_path.unwrap(), "texture_diffuse"); textures.push(texture); } else { println!("There are no materials for: {}", path.display()); @@ -115,21 +115,4 @@ impl Model { } println!("Finished loading model from path: {}", path.display()); } - - fn load_material_texture(&mut self, path: &str, typeName: &str) -> Texture { - { - let texture = self.textures_loaded.iter().find(|t| t.path == path); - if let Some(texture) = texture { - return texture.clone(); - } - } - - let texture = Texture { - id: unsafe { load_texture_from_dir(path, &self.directory) }, - type_: typeName.into(), - path: path.into(), - }; - self.textures_loaded.push(texture.clone()); - texture - } }