Textures cache

This commit is contained in:
Piotr 2020-09-25 21:13:33 +02:00
parent 6278aabb97
commit ae1eba3d73
6 changed files with 87 additions and 63 deletions

View File

@ -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<ModelComponent>,
@ -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();

28
src/gaia/assets_cache.rs Normal file
View File

@ -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<String, Texture>
}
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
}
}
}
}

View File

@ -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);

View File

@ -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<dyn Client>,
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(),
}
}
}

View File

@ -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;

View File

@ -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::<Mesh>::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
}
}