diff --git a/.vscode/launch.json b/.vscode/launch.json index 617ca91..eff0825 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,7 @@ { "type": "lldb", "request": "launch", - "name": "Debug executable 'rust-engine'", + "name": "engine - debug", "cargo": { "args": [ "build", @@ -22,6 +22,25 @@ "args": [], "cwd": "${workspaceFolder}" }, + { + "type": "lldb", + "request": "launch", + "name": "engine - release", + "cargo": { + "args": [ + "build", + "--bin=rust-engine", + "--package=rust-engine", + "--release" + ], + "filter": { + "name": "rust-engine", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, { "type": "lldb", "request": "launch", diff --git a/Cargo.toml b/Cargo.toml index 88a38f2..36aa38a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,7 @@ serde = "1.0.114" serde_derive = "1.0.114" toml = "0.5.6" gilrs = "0.7.4" -gltf = "0.15.2" \ No newline at end of file +gltf = "0.15.2" + +[profile.dev.package."*"] +opt-level = 3 \ No newline at end of file diff --git a/models/plane.blend b/models/plane.blend index 5f17985..d4bd69b 100644 Binary files a/models/plane.blend and b/models/plane.blend differ diff --git a/models/plane.glb b/models/plane.glb index 2c845b3..db26e9c 100644 Binary files a/models/plane.glb and b/models/plane.glb differ diff --git a/shaders/triangle.frag b/shaders/triangle.frag index f4d2221..859df85 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -9,7 +9,8 @@ layout(binding = 0) uniform ObjectUniformData { vec3 camera_position; } ubo; -layout(binding = 1) uniform sampler2D tex; +layout(binding = 1) uniform sampler2D diffuse_tex; +layout(binding = 2) uniform sampler2D normal_tex; layout(location = 0) in vec2 tex_coords; layout(location = 1) in vec3 normal_wld; @@ -18,7 +19,9 @@ layout(location = 2) in vec3 position_wld; layout(location = 0) out vec4 out_color; void main() { - vec3 normal_cam_u = normalize(normal_wld); +// vec3 normal_cam_u = normalize(normal_wld); // TODO + vec3 normal_cam_u = texture(normal_tex, tex_coords).rgb; + normal_cam_u = normalize(normal_cam_u * 2.0 - 1.0); vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld); float ambient_strength = 0.1; @@ -35,5 +38,5 @@ void main() { float specular_strength = pow(max(dot(reflect_direction, view_direction), 0.0), 64); vec3 specular_color = specular_value * specular_strength * light_color; - out_color = vec4(ambient_color + diffuse_color + specular_color, 1.0) * texture(tex, tex_coords); + out_color = vec4(ambient_color + diffuse_color + specular_color, 1.0) * texture(diffuse_tex, tex_coords); } \ No newline at end of file diff --git a/shaders/triangle.vert b/shaders/triangle.vert index bb6484e..145d379 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -11,7 +11,6 @@ layout(binding = 0) uniform ObjectUniformData { float time; vec3 light_position; vec3 camera_position; - } ubo; layout(location = 0) in vec3 position; diff --git a/src/gameobject.rs b/src/gameobject.rs index 75116df..f888a72 100644 --- a/src/gameobject.rs +++ b/src/gameobject.rs @@ -1,5 +1,5 @@ use std::sync::Arc; -use crate::vulkan::RendererDescriptorSets; +use crate::vulkan::{RendererDescriptorSets, TextureHandle}; use cgmath::{Matrix4, Vector3, Quaternion, Euler, Deg}; use crate::vulkan::{MeshHandle, VulkanRenderer}; use crate::input::InputState; @@ -7,7 +7,8 @@ use crate::input::InputState; #[derive(Clone)] pub struct GameObject { pub mesh_index: usize, - pub texture_index: usize, + pub texture_index: TextureHandle, + pub normal_map_index: TextureHandle, pub position: Vector3, pub rotation: Quaternion, pub scale: Vector3, @@ -16,8 +17,8 @@ pub struct GameObject { } impl GameObject { - pub fn new(mesh: MeshHandle, texture_index: usize) -> GameObject { - GameObject { mesh_index: mesh, texture_index, position: Vector3::new(0.0, 0.0, 0.0), + pub fn new(mesh: MeshHandle) -> GameObject { + GameObject { mesh_index: mesh.index, texture_index: mesh.diffuse_handle, normal_map_index: mesh.normal_handle, position: Vector3::new(0.0, 0.0, 0.0), rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0), scale: Vector3::new(1.0, 1.0, 1.0), children: vec![], descriptor_sets: vec![] } } diff --git a/src/main.rs b/src/main.rs index 08c0b62..c5c2d67 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,12 @@ -use crate::vulkan::TextureHandle; -use crate::player::{Player}; -use cgmath::{Matrix4, Vector3, vec3, Vector4}; +use cgmath::{Matrix4, vec3, Vector3, Vector4}; use winit::event::Event; use crate::config::LogConfig; +use crate::gameobject::{GameObject, GameObjectHandle, Updatable}; use crate::input::InputState; +use crate::player::Player; use crate::vulkan::{Game, LinePoint, MeshHandle, VulkanRenderer}; use crate::vulkan::vs::ty::ObjectUniformData; -use crate::gameobject::{GameObject, GameObjectHandle, Updatable}; mod vulkan; mod input; @@ -19,7 +18,7 @@ mod player; struct TestGame { input: InputState, player: Player, - meshes: Vec<(MeshHandle, TextureHandle)>, + meshes: Vec, game_objects: Vec, log_config: LogConfig, texture_index_counter: usize, @@ -117,6 +116,13 @@ impl TestGame { println!("Game loaded!"); } + fn offset_texture_id(&mut self, local_tex_id: Option) -> usize { + match local_tex_id { + Some(local_id) => local_id + self.texture_index_counter, + None => 0, + } + } + fn load_gltf(&mut self, renderer: &mut VulkanRenderer, gltf_path: &str) -> Vec { let mut mesh_handles = Vec::new(); @@ -125,23 +131,23 @@ impl TestGame { for cpu_mesh in meshes.into_iter() { // Convert file texture id to game texture id - let id = match cpu_mesh.texture_index { - Some(local_tex_id) => local_tex_id + self.texture_index_counter, - None => 0, - }; - if cpu_mesh.texture_index.is_some() { - self.texture_index_counter += 1; - } + let diffuse_id = self.offset_texture_id(cpu_mesh.local_texture_index); + let normal_id = self.offset_texture_id(cpu_mesh.local_normal_map_index); // Upload mesh - let mesh_handle = renderer.upload_mesh(cpu_mesh); - self.meshes.push((mesh_handle, id)); + let mesh_id = renderer.upload_mesh(cpu_mesh); + let mesh_handle = MeshHandle { + index: mesh_id, + diffuse_handle: diffuse_id, + normal_handle: normal_id, + }; + self.meshes.push(mesh_handle); mesh_handles.push(mesh_handle); } - // TODO: this assumes each texture is actually used in a mesh above textures.iter().for_each(|tex| { renderer.upload_texture(tex); + self.texture_index_counter += 1; }); mesh_handles } @@ -152,8 +158,7 @@ impl TestGame { } fn add_game_object(&mut self, renderer: &mut VulkanRenderer, mesh: MeshHandle) -> &mut GameObjectHandle { - let (mesh_id, mesh_texture_id) = self.meshes[mesh]; - let obj = GameObject::new(mesh_id, mesh_texture_id); + let obj = GameObject::new(mesh); let obj_handle = renderer.add_game_object(obj); self.game_objects.push(obj_handle); self.game_objects.last_mut().unwrap() diff --git a/src/mesh.rs b/src/mesh.rs index 0ec5ed8..2156d5d 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -28,7 +28,8 @@ impl From for LoadError { pub struct CPUMesh { pub vertices: Vec, pub indices: Vec, - pub texture_index: Option, + pub local_texture_index: Option, + pub local_normal_map_index: Option, pub name: Option, } @@ -49,6 +50,7 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, V for mesh in document.meshes() { for primitive in mesh.primitives() { let texture_index = primitive.material().pbr_metallic_roughness().base_color_texture().map(|tex_info| tex_info.texture().index()); + let normal_map_index = primitive.material().normal_texture().map(|tex_info| tex_info.texture().index()); let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()])); let indices = reader.read_indices().ok_or(NoIndices)?; @@ -57,7 +59,8 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, V let cpu_mesh = CPUMesh { vertices, indices: indices.into_u32().collect(), - texture_index, + local_texture_index: texture_index, + local_normal_map_index: normal_map_index, name: mesh.name().map(|n| n.to_owned()), }; if print_status { diff --git a/src/vulkan.rs b/src/vulkan.rs index 7238a74..5d33cad 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -34,7 +34,6 @@ use crate::mesh::CPUMesh; use crate::gameobject::{GameObject, GameObjectHandle}; const VALIDATION_LAYERS: &[&str] = &[ - "VK_LAYER_LUNARG_standard_validation" ]; #[derive(Default, Debug, Clone)] @@ -65,7 +64,13 @@ pub struct Mesh { index_buffer: Arc>, } -pub(crate) type MeshHandle = usize; +#[derive(Debug, Copy, Clone)] +pub struct MeshHandle { + pub index: usize, + pub diffuse_handle: TextureHandle, + pub normal_handle: TextureHandle, +} + pub(crate) type TextureHandle = usize; pub struct GameData { @@ -437,7 +442,7 @@ impl VulkanRenderer { }; } - pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> MeshHandle { + pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> usize { let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, mesh.vertices.into_iter()).unwrap(); let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap(); self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer }); @@ -463,11 +468,14 @@ impl VulkanRenderer { pub fn add_game_object(self: &mut Self, mut game_object: GameObject) -> GameObjectHandle { let descriptor_set_layout = self.pipeline.descriptor_set_layout(0).unwrap().clone(); + println!("Diff: {:?}, Norm: {:?}", game_object.texture_index, game_object.normal_map_index); + let descriptor_sets = self.uniform_buffers.iter().map(|uniform_buffer| { let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone()); let result: Arc = Arc::new(builder .add_buffer(uniform_buffer.clone()).unwrap() .add_sampled_image(self.game_data.textures[game_object.texture_index].clone(), self.sampler.clone()).unwrap() + .add_sampled_image(self.game_data.textures[game_object.normal_map_index].clone(), self.sampler.clone()).unwrap() .build().unwrap()); result }).collect();