diff --git a/src/example_client.rs b/src/example_client.rs index 8d58b2c..40a1066 100644 --- a/src/example_client.rs +++ b/src/example_client.rs @@ -48,11 +48,11 @@ impl Client for ExampleClient { scale: vec3(0.5, 0.5, 0.5), ..Transform::default() }, - model: model::Model::new("resources/objects/ground/ground.obj", cache), + model: cache.get_model("resources/objects/ground/ground.obj"), }; let robot = ModelComponent { transform: Transform::default(), - model: model::Model::new("resources/objects/robot/robot.obj", cache), + model: cache.get_model("resources/objects/robot/robot.obj"), }; let tree = ModelComponent { transform: Transform { @@ -60,10 +60,9 @@ impl Client for ExampleClient { scale: vec3(2.5, 2.5, 2.5), ..Transform::default() }, - model: model::Model::new_ext( + model: cache.get_model_ext( "resources/objects/tree/tree_6_d.obj", - Some("tree_e.png"), - cache, + Some("tree_e.png") ), }; let tree2 = ModelComponent { @@ -72,10 +71,9 @@ impl Client for ExampleClient { scale: vec3(2.5, 2.5, 2.5), ..Transform::default() }, - model: model::Model::new_ext( + model: cache.get_model_ext( "resources/objects/tree/tree_6_c.obj", - Some("tree_e.png"), - cache, + Some("tree_e.png") ), }; let tree3 = ModelComponent { @@ -84,10 +82,9 @@ impl Client for ExampleClient { scale: vec3(2.5, 2.5, 2.5), ..Transform::default() }, - model: model::Model::new_ext( + model: cache.get_model_ext( "resources/objects/tree/tree_6_c.obj", - Some("tree_e.png"), - cache, + Some("tree_e.png") ), }; self.models = vec![tree, tree2, tree3, ground, robot]; diff --git a/src/gaia/assets_cache.rs b/src/gaia/assets_cache.rs index 14e2135..ee5a67c 100644 --- a/src/gaia/assets_cache.rs +++ b/src/gaia/assets_cache.rs @@ -1,4 +1,5 @@ use crate::gaia::mesh::Texture; +use crate::gaia::model::Model; use crate::gaia::utils::load_texture_from_dir; use std::collections::HashMap; use std::path::Path; @@ -6,15 +7,40 @@ use std::path::Path; #[derive(Default)] pub struct AssetsCache { textures: HashMap, + models: HashMap, } impl AssetsCache { - pub fn load_material_texture(&mut self, dir: &str, path: &str, type_name: &str) -> Texture { + pub fn get_model(&mut self, path: &str) -> Model { + match self.models.get(path) { + Some(model) => model.clone(), + None => { + println!("Loading model: {}", path); + let model = Model::new(path, self); + self.models.insert(path.to_string(), model.clone()); + model + } + } + } + + pub fn get_model_ext(&mut self, path: &str, diff_texture: Option<&str>) -> Model { + match self.models.get(path) { + Some(model) => model.clone(), + None => { + println!("Loading model: {}", path); + let model = Model::new_ext(path, diff_texture, self); + self.models.insert(path.to_string(), model.clone()); + model + } + } + } + + pub fn get_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); + println!("Loading texture: {}", path); let texture = Texture { id: unsafe { load_texture_from_dir(path, &directory) }, type_: type_name.into(), diff --git a/src/gaia/mesh.rs b/src/gaia/mesh.rs index 50e74af..6600904 100644 --- a/src/gaia/mesh.rs +++ b/src/gaia/mesh.rs @@ -16,6 +16,7 @@ use crate::gaia::shader::Shader; // Depending on how you pass the data to OpenGL, this may be bad. In this case it's not strictly // necessary though because of the `offset!` macro used below in setupMesh() #[repr(C)] +#[derive(Clone)] pub struct Vertex { // position pub position: Vector3, @@ -48,6 +49,7 @@ pub struct Texture { pub path: String, } +#[derive(Clone)] pub struct Mesh { /* Mesh Data */ pub vertices: Vec, diff --git a/src/gaia/model.rs b/src/gaia/model.rs index 2ab93aa..524bcf6 100644 --- a/src/gaia/model.rs +++ b/src/gaia/model.rs @@ -9,7 +9,7 @@ use cgmath::{vec2, vec3}; use std::path::Path; use tobj; -// #[derive(Default)] +#[derive(Clone)] pub struct Model { /* Model Data */ pub meshes: Vec, @@ -87,7 +87,7 @@ impl Model { // 1. diffuse map if !material.diffuse_texture.is_empty() { - let texture = cache.load_material_texture( + let texture = cache.get_material_texture( &self.directory, &material.diffuse_texture, "texture_diffuse", @@ -96,7 +96,7 @@ impl Model { } // 2. specular map if !material.specular_texture.is_empty() { - let texture = cache.load_material_texture( + let texture = cache.get_material_texture( &self.directory, &material.specular_texture, "texture_specular", @@ -105,7 +105,7 @@ impl Model { } // 3. normal map if !material.normal_texture.is_empty() { - let texture = cache.load_material_texture( + let texture = cache.get_material_texture( &self.directory, &material.normal_texture, "texture_normal", @@ -115,7 +115,7 @@ impl Model { // NOTE: no height maps } else if diffuse_path.is_some() { println!("Loading {}", &diffuse_path.unwrap()); - let texture = cache.load_material_texture( + let texture = cache.get_material_texture( &self.directory, &diffuse_path.unwrap(), "texture_diffuse", diff --git a/src/gaia/utils.rs b/src/gaia/utils.rs index 48b39fe..bda2ee2 100644 --- a/src/gaia/utils.rs +++ b/src/gaia/utils.rs @@ -1,7 +1,7 @@ use gl; +use image2::image::Image; use image2::{io, ImagePtr, Rgb, Rgba}; use std::os::raw::c_void; -use image2::image::Image; pub unsafe fn load_texture(path: &str, file_format: &str) -> u32 { println!( @@ -30,7 +30,10 @@ pub unsafe fn load_texture(path: &str, file_format: &str) -> u32 { gl::BindTexture(gl::TEXTURE_2D, id); gl::TexImage2D( - gl::TEXTURE_2D, 0, format as i32, dim.0 as i32, + gl::TEXTURE_2D, + 0, + format as i32, + dim.0 as i32, dim.1 as i32, 0, format,