From 102eadf5c9526c7608a24d82392cf5d3522205a1 Mon Sep 17 00:00:00 2001 From: Piotr Siuszko Date: Tue, 14 Sep 2021 22:16:49 +0200 Subject: [PATCH] Init work on 2d --- examples/2d.rs | 72 ++++++++++++++++++++++++ examples/client.rs | 11 ++++ resources/defaults/plane.mtl | 10 ++++ resources/defaults/plane.obj | 16 ++++++ resources/test_map.yaml | 77 +++++++++++++++++-------- resources/test_objects.txt | 7 ++- src/assets_cache.rs | 20 ++++++- src/components.rs | 12 ++++ src/light.rs | 2 +- src/mesh.rs | 2 +- src/model.rs | 105 ++++++++++++++++++++++------------- src/utils.rs | 9 ++- 12 files changed, 276 insertions(+), 67 deletions(-) create mode 100644 examples/2d.rs create mode 100644 resources/defaults/plane.mtl create mode 100644 resources/defaults/plane.obj diff --git a/examples/2d.rs b/examples/2d.rs new file mode 100644 index 0000000..9c07096 --- /dev/null +++ b/examples/2d.rs @@ -0,0 +1,72 @@ +use doppler::assets_cache::AssetsCache; +use doppler::camera::*; +use doppler::client::Client; +use doppler::glutin::event::{ElementState, VirtualKeyCode}; +use doppler::shader::Shader; +use doppler::map::*; +use doppler::components::*; + +pub struct Client2D{ + delta: f32, + models_2d: ModelComponent, + shader: Shader +} + +impl Default for Client2D { + fn default() -> Self { + Client2D { + delta: 0.0, + models_2d: ModelComponent::default(), + shader: Shader::from_file( + "resources/shaders/multiple_lights.vs", + "resources/shaders/multiple_lights.fs", + ) + } + } +} + + +impl Client for Client2D { + fn on_keyboard(&mut self, code: &VirtualKeyCode, state: &ElementState) { + match (code, state) { + (VirtualKeyCode::W, ElementState::Pressed) => (), + (VirtualKeyCode::S, ElementState::Pressed) => (), + (VirtualKeyCode::A, ElementState::Pressed) => (), + (VirtualKeyCode::D, ElementState::Pressed) => (), + (VirtualKeyCode::LControl, _) => (), + (_, _) => (), + } + } + + fn load_assets(&mut self, cache: &mut AssetsCache) { + self.models_2d.model = cache.load_2d("resources/objects/ddd.jpg"); + } + + unsafe fn draw(&mut self) { + use doppler::math::prelude::*; + self.models_2d.draw(&self.shader); + // let projection: Matrix4 = perspective( + // Deg(self.camera.zoom), + // consts::SCR_WIDTH as f32 / consts::SCR_HEIGHT as f32, + // 0.1, + // 1000.0, + // ); + } + + fn update(&mut self, delta: f32) { + self.delta = delta; + } + + fn debug_draw(&mut self, ui: &doppler::imgui::Ui) { + } + + fn on_mouse_scroll(&mut self, yoffset: f32) { + } + + fn on_mouse_move(&mut self, x: f32, y: f32) { + } +} + +pub fn main() { + doppler::engine::Engine::default().run::(); +} diff --git a/examples/client.rs b/examples/client.rs index 8bd3cec..960027d 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -12,6 +12,7 @@ pub struct ExampleClient { delta: f32, show_object_info: bool, show_camera_info: bool, + imgui_grabs_input: bool, object_info_id: i32, show_light_info: bool, light_info_id: i32, @@ -26,6 +27,7 @@ impl Default for ExampleClient { show_camera_info: false, show_object_info: false, show_light_info: false, + imgui_grabs_input: false, light_info_id: 0, } } @@ -189,12 +191,21 @@ impl Client for ExampleClient { self.show_light_info = show_window; } } + self.imgui_grabs_input = ui.is_any_item_hovered() || ui.is_any_item_focused(); } fn on_mouse_scroll(&mut self, yoffset: f32) { + if self.imgui_grabs_input { + println!("DD"); + return; + } self.map.camera.process_mouse_scroll(yoffset as f32); } fn on_mouse_move(&mut self, x: f32, y: f32) { + if self.imgui_grabs_input { + println!("DD"); + return; + } self.map.camera.process_mouse_movement(x, y, true); } } diff --git a/resources/defaults/plane.mtl b/resources/defaults/plane.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/defaults/plane.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/defaults/plane.obj b/resources/defaults/plane.obj new file mode 100644 index 0000000..7c39ec9 --- /dev/null +++ b/resources/defaults/plane.obj @@ -0,0 +1,16 @@ +# Blender v2.93.4 OBJ File: '' +# www.blender.org +mtllib plane.mtl +o Plane +v -1.000000 0.000000 1.000000 +v 1.000000 0.000000 1.000000 +v -1.000000 0.000000 -1.000000 +v 1.000000 0.000000 -1.000000 +vt 0.999900 0.999900 +vt 0.000100 0.999900 +vt 0.000100 0.000100 +vt 0.999900 0.000100 +vn 0.0000 1.0000 0.0000 +usemtl None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 diff --git a/resources/test_map.yaml b/resources/test_map.yaml index e2729bf..750d602 100644 --- a/resources/test_map.yaml +++ b/resources/test_map.yaml @@ -54,28 +54,6 @@ objects: y: 0.0 z: 0.0 scale: 1.0 - - model_hash: 4360533331876312021 - transform: - position: - x: 0.0 - y: 0.0 - z: 0.0 - rotation: - x: 0.0 - y: 0.0 - z: 0.0 - scale: 1.0 - - model_hash: 6024833582843300776 - transform: - position: - x: 8.3 - y: 0.0 - z: 3.0 - rotation: - x: 0.0 - y: 120.0 - z: 0.0 - scale: 0.025 - model_hash: 12474845581084103280 transform: position: @@ -87,6 +65,61 @@ objects: y: 0.0 z: 0.0 scale: 1.0 + - model_hash: 7463349984896526650 + transform: + position: + x: 2.0 + y: 0.0 + z: 0.0 + rotation: + x: 0.0 + y: 0.0 + z: 0.0 + scale: 1.0 + - model_hash: 13800530402659272349 + transform: + position: + x: 44.0 + y: 0.0 + z: 33.0 + rotation: + x: 0.0 + y: 128.0 + z: 0.0 + scale: 3.0 + - model_hash: 10609347989321310959 + transform: + position: + x: 55.0 + y: 0.0 + z: -28.0 + rotation: + x: 0.0 + y: -67.0 + z: 0.0 + scale: 2.0 + - model_hash: 14496278726830200225 + transform: + position: + x: 39.0 + y: 0.0 + z: -39.0 + rotation: + x: -12.0 + y: 70.0 + z: 30.0 + scale: 1.5 + - model_hash: 448611579693571817 + transform: + position: + x: 11.0 + y: 0.0 + z: -40.0 + rotation: + x: 0.0 + y: 0.0 + z: 0.0 + scale: 2.0 camera: position: x: 0.0 diff --git a/resources/test_objects.txt b/resources/test_objects.txt index 7fde642..3e69181 100644 --- a/resources/test_objects.txt +++ b/resources/test_objects.txt @@ -1,8 +1,11 @@ resources/objects/ground/ground.obj resources/objects/robot/robot.obj resources/objects/grass/grass.obj foliage.png -resources/objects/gaz_tank/gaz_tank.obj resources/objects/tree/tree_6_d.obj tree_e.png resources/objects/tree/tree_6_c.obj tree_e.png resources/objects/tree/tree_6_c.obj tree_e.png -resources/objects/ruins/ruins.obj \ No newline at end of file +resources/objects/citypack/policeman.obj +resources/objects/sclavinia/wapienne_skaly.obj wapno.png +resources/objects/sclavinia/wapienne_skaly_2.obj wapno.png +resources/objects/sclavinia/wapienne_skaly_3.obj wapno.png +resources/objects/sclavinia/chata_zniszczona_1.obj palev2.png \ No newline at end of file diff --git a/src/assets_cache.rs b/src/assets_cache.rs index c317158..58afc0e 100644 --- a/src/assets_cache.rs +++ b/src/assets_cache.rs @@ -5,6 +5,7 @@ use log::{error, info}; use std::collections::hash_map::DefaultHasher; use std::collections::HashMap; use std::hash::{Hash, Hasher}; +use std::path::Path; #[derive(Default)] pub struct AssetsCache { @@ -13,6 +14,23 @@ pub struct AssetsCache { } impl AssetsCache { + pub fn load_2d(&mut self, path: &str) -> Model { + let fullpath = Path::new(&path); + let dir = fullpath + .parent() + .unwrap() + .to_str() + .unwrap() + .to_string(); + let filename = fullpath.file_name().unwrap().to_str().unwrap(); + let texture = self.get_material_texture(&dir, &filename, "texture_diffuse"); + let mut model = Model::new_2d( self); + for ele in &mut model.meshes { + ele.textures.push(texture.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); @@ -70,7 +88,7 @@ impl AssetsCache { fn load_model_ext(&mut self, path: &str, diff_texture: Option<&str>) { let hash = Self::path_hash(path); info!("Loading model: {}({})", path, hash); - let model = Model::new_ext(path, diff_texture, self); + let model = Model::new_ext(path, diff_texture, self, false); self.models.insert(hash, model); } diff --git a/src/components.rs b/src/components.rs index ef85870..b9df7ab 100644 --- a/src/components.rs +++ b/src/components.rs @@ -1,3 +1,5 @@ +use std::default; + #[cfg(feature = "imgui_inspect")] use crate::imgui_helper::*; use crate::model::Model; @@ -47,6 +49,16 @@ pub struct ModelComponent { pub transform: Transform, } +impl Default for ModelComponent { + fn default() -> Self { + ModelComponent { + model: Model::default(), + hash: u64::default(), + transform: Transform::default(), + } + } +} + impl ModelComponent { pub unsafe fn draw(&self, shader: &Shader) { let matrix = self.transform.get_matrix(); diff --git a/src/light.rs b/src/light.rs index 33f0fa1..0a74c3c 100644 --- a/src/light.rs +++ b/src/light.rs @@ -101,7 +101,7 @@ impl Default for DirectionalLight { DirectionalLight { direction: vec3(-0.3, -1.0, -0.3), ambient: vec3(0.05, 0.05, 0.05), - diffuse: vec3(0.4, 0.4, 0.4), + diffuse: vec3(0.9, 0.9, 0.8), specular: vec3(0.5, 0.5, 0.5), } } diff --git a/src/mesh.rs b/src/mesh.rs index 0298eef..fac0bcd 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -10,6 +10,7 @@ use cgmath::prelude::*; use cgmath::{Vector2, Vector3}; use gl; +use crate::assets_cache::AssetsCache; use crate::shader::Shader; // NOTE: without repr(C) the compiler may reorder the fields or use different padding/alignment than C. @@ -90,7 +91,6 @@ impl Mesh { VBO: 0, EBO: 0, }; - // now that we have all the required data, set the vertex buffers and its attribute pointers. unsafe { mesh.setupMesh() } mesh diff --git a/src/model.rs b/src/model.rs index 448e410..8b9b9e9 100644 --- a/src/model.rs +++ b/src/model.rs @@ -28,8 +28,17 @@ impl Default for Model { } impl Model { + pub fn new_2d(cache: &mut AssetsCache) -> Model { + Self::new_ext("resources/defaults/plane.obj", None, cache, true) + } + /// constructor, expects a filepath to a 3D model. - pub fn new_ext(path: &str, diff_texture: Option<&str>, cache: &mut AssetsCache) -> Model { + pub fn new_ext( + path: &str, + diff_texture: Option<&str>, + cache: &mut AssetsCache, + skip_textures: bool, + ) -> Model { let pathObj = Path::new(path); let mut model = Model { meshes: Vec::::new(), @@ -43,7 +52,7 @@ impl Model { }; if pathObj.exists() { - model.load_model(path, diff_texture, cache); + model.load_model(path, diff_texture, cache, skip_textures); } else { warn!("{} does not exist, returning empty model", path); } @@ -52,7 +61,7 @@ impl Model { } pub fn new(path: &str, cache: &mut AssetsCache) -> Model { - Model::new_ext(path, None, cache) + Model::new_ext(path, None, cache, false) } pub fn Draw(&self, shader: &Shader) { @@ -64,7 +73,13 @@ 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>, cache: &mut AssetsCache) { + fn load_model( + &mut self, + path: &str, + diffuse_path: Option<&str>, + cache: &mut AssetsCache, + skip_textures: bool, + ) { let path = Path::new(path); // println!("Started loading model from path: {}", path.display()); @@ -98,47 +113,61 @@ impl Model { // process material let mut textures = Vec::new(); - if let Some(material_id) = mesh.material_id { - let material = &materials[material_id]; - // 1. diffuse map - if !material.diffuse_texture.is_empty() { + if !skip_textures { + if let Some(material_id) = mesh.material_id { + let material = &materials[material_id]; + + // 1. diffuse map + if !material.diffuse_texture.is_empty() { + let texture = cache.get_material_texture( + &self.directory, + &material.diffuse_texture, + "texture_diffuse", + ); + textures.push(texture); + } + // 2. specular map + if !material.specular_texture.is_empty() { + let texture = cache.get_material_texture( + &self.directory, + &material.specular_texture, + "texture_specular", + ); + textures.push(texture); + } + // 3. normal map + if !material.normal_texture.is_empty() { + let texture = cache.get_material_texture( + &self.directory, + &material.normal_texture, + "texture_normal", + ); + textures.push(texture); + } + // NOTE: no height maps + } else if diffuse_path.is_some() { + let path = diffuse_path.unwrap(); + println!("Loading {}", path); + let dir: String = if path.contains("/") { + Path::new(&path) + .parent() + .unwrap() + .to_str() + .unwrap() + .to_string() + } else { + self.directory.to_string() + }; let texture = cache.get_material_texture( &self.directory, - &material.diffuse_texture, + &diffuse_path.unwrap(), "texture_diffuse", ); textures.push(texture); + } else { + warn!("There are no materials for: {}", path.display()); } - // 2. specular map - if !material.specular_texture.is_empty() { - let texture = cache.get_material_texture( - &self.directory, - &material.specular_texture, - "texture_specular", - ); - textures.push(texture); - } - // 3. normal map - if !material.normal_texture.is_empty() { - let texture = cache.get_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 = cache.get_material_texture( - &self.directory, - &diffuse_path.unwrap(), - "texture_diffuse", - ); - textures.push(texture); - } else { - warn!("There are no materials for: {}", path.display()); } self.meshes.push(Mesh::new(vertices, indices, textures)); diff --git a/src/utils.rs b/src/utils.rs index 2f1770c..c161637 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -64,8 +64,13 @@ pub unsafe fn load_texture(path: &str, file_format: &str) -> u32 { pub unsafe fn load_texture_from_dir(filename: &str, directory: &str) -> u32 { let fullpath = format!("{}/{}", directory, filename); - let dot = filename.find(".").unwrap_or_default() + 1usize; - let (_, format) = filename.split_at(dot); + + load_texture_from_fullpath(&fullpath) +} + +pub unsafe fn load_texture_from_fullpath(fullpath: &str) -> u32 { + let dot = fullpath.find(".").unwrap_or_default() + 1usize; + let (_, format) = fullpath.split_at(dot); load_texture(&fullpath, format) }