diff --git a/.gitignore b/.gitignore index ea8c4bf..767ad53 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/res \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 938a906..2a76af5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -20,6 +20,7 @@ "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", + "RUST_BACKTRACE": "1", } } ] diff --git a/Cargo.toml b/Cargo.toml index ebf9dd4..53021fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ log = "0.4" wgpu = "0.13" pollster = "0.2" bytemuck = { version = "1.4", features = [ "derive" ] } -image = { version = "0.24", features = [ "png" ] } +image = { version = "0.24", features = [ "png", "tga" ] } anyhow = "1.0" cgmath = "0.18" tobj = { version = "3.2.1", features = [ "async", ] } diff --git a/build.rs b/build.rs index bdcbbaa..618e24c 100644 --- a/build.rs +++ b/build.rs @@ -4,7 +4,7 @@ use fs_extra::dir::CopyOptions; use std::env; fn main() -> Result<()> { - println!("cargo:rerun-if-changed=res/*"); + println!("cargo:rerun-if-changed=res/**/*"); let out_dir = env::var("OUT_DIR")?; let mut copy_options = CopyOptions::new(); @@ -13,5 +13,5 @@ fn main() -> Result<()> { paths_to_copy.push("res/"); copy_items(&paths_to_copy, out_dir, ©_options)?; - Ok(()) + return Ok(()); } diff --git a/src/core/resources.rs b/src/core/resources.rs index 2ab9a7c..11a5f08 100644 --- a/src/core/resources.rs +++ b/src/core/resources.rs @@ -28,6 +28,7 @@ pub async fn load_texture( device: &wgpu::Device, queue: &wgpu::Queue, ) -> anyhow::Result { + println!("load_texture {}", file_name); let data = load_binary(file_name).await?; return Texture::from_bytes(device, queue, &data, file_name, is_normal_map); } @@ -58,8 +59,23 @@ pub async fn load_model( let mut materials = Vec::new(); for m in obj_materials? { - let diffuse_texture = load_texture(&m.diffuse_texture, false, device, queue).await?; - let normal_texture = load_texture(&m.normal_texture, true, device, queue).await?; + let diffuse_texture_result = load_texture(&m.diffuse_texture, false, device, queue).await; + let normal_texture_result = load_texture(&m.normal_texture, true, device, queue).await; + + let diffuse_texture: Texture; + let normal_texture: Texture; + + if diffuse_texture_result.is_err() { + diffuse_texture = load_texture("gray.png", false, device, queue).await?; + } else { + diffuse_texture = diffuse_texture_result?; + } + + if normal_texture_result.is_err() { + normal_texture = load_texture("gray.png", true, device, queue).await?; + } else { + normal_texture = normal_texture_result?; + } materials.push(Material::new( device, diff --git a/src/core/state.rs b/src/core/state.rs index 0ebd34d..3017314 100644 --- a/src/core/state.rs +++ b/src/core/state.rs @@ -11,7 +11,7 @@ use super::model::{DrawModel, Model, ModelVertex, Vertex}; use super::resources; use super::texture::Texture; -const NUM_INSTANCES_PER_ROW: u32 = 10; +const NUM_INSTANCES_PER_ROW: u32 = 1; pub struct State { pub size: winit::dpi::PhysicalSize, @@ -116,7 +116,7 @@ impl State { let camera_controller = CameraController::new(1.0, 2.0); - let light_uniform = LightUniform::new([2.0, 4.0, 2.0], [1.0, 1.0, 1.0]); + let light_uniform = LightUniform::new([900.0, 60.0, 200.0], [1.0, 1.0, 1.0]); // We'll want to update our lights position, so we use COPY_DST let light_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { @@ -193,32 +193,44 @@ impl State { }); let obj_model = - resources::load_model("cube.obj", &device, &queue, &texture_bind_group_layout) + resources::load_model("sponza.obj", &device, &queue, &texture_bind_group_layout) .await .unwrap(); - const SPACE_BETWEEN: f32 = 3.0; - let instances = (0..NUM_INSTANCES_PER_ROW) - .flat_map(|z| { - (0..NUM_INSTANCES_PER_ROW).map(move |x| { - let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); - let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); + let instances: Vec; + if NUM_INSTANCES_PER_ROW > 1 { + const SPACE_BETWEEN: f32 = 3.0; + instances = (0..NUM_INSTANCES_PER_ROW) + .flat_map(|z| { + (0..NUM_INSTANCES_PER_ROW).map(move |x| { + let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); + let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); - let position = cgmath::Vector3 { x, y: 0.0, z }; + let position = cgmath::Vector3 { x, y: 0.0, z }; - let rotation = if position.is_zero() { - cgmath::Quaternion::from_axis_angle( - cgmath::Vector3::unit_z(), - cgmath::Deg(0.0), - ) - } else { - cgmath::Quaternion::from_axis_angle(position.normalize(), cgmath::Deg(45.0)) - }; + let rotation = if position.is_zero() { + cgmath::Quaternion::from_axis_angle( + cgmath::Vector3::unit_z(), + cgmath::Deg(0.0), + ) + } else { + cgmath::Quaternion::from_axis_angle( + position.normalize(), + cgmath::Deg(45.0), + ) + }; - Instance { position, rotation } + Instance { position, rotation } + }) }) - }) - .collect::>(); + .collect::>(); + } else { + instances = [Instance { + position: [0.0, 0.0, 0.0].into(), + rotation: cgmath::Quaternion::one(), + }] + .into(); + } let instance_data = instances.iter().map(Instance::to_raw).collect::>(); let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { diff --git a/src/core/texture.rs b/src/core/texture.rs index db7a14b..719c772 100644 --- a/src/core/texture.rs +++ b/src/core/texture.rs @@ -33,9 +33,9 @@ impl Texture { let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, + address_mode_u: wgpu::AddressMode::Repeat, + address_mode_v: wgpu::AddressMode::Repeat, + address_mode_w: wgpu::AddressMode::Repeat, mag_filter: wgpu::FilterMode::Linear, min_filter: wgpu::FilterMode::Linear, mipmap_filter: wgpu::FilterMode::Nearest, @@ -110,9 +110,9 @@ impl Texture { let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, + address_mode_u: wgpu::AddressMode::Repeat, + address_mode_v: wgpu::AddressMode::Repeat, + address_mode_w: wgpu::AddressMode::Repeat, mag_filter: wgpu::FilterMode::Linear, min_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest, diff --git a/src/shaders/light.wgsl b/src/shaders/light.wgsl index 09fd96d..098499a 100644 --- a/src/shaders/light.wgsl +++ b/src/shaders/light.wgsl @@ -28,7 +28,7 @@ struct VertexOutput { fn vs_main( model: VertexInput, ) -> VertexOutput { - let scale = 0.25; + let scale = 0.01; var out: VertexOutput; out.clip_position = camera.proj * camera.view * vec4(model.position * scale + light.position, 1.0); out.color = light.color; diff --git a/src/shaders/test.wgsl b/src/shaders/test.wgsl index 19073cf..c30b700 100644 --- a/src/shaders/test.wgsl +++ b/src/shaders/test.wgsl @@ -94,7 +94,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4 { let half_dir = normalize(view_dir + light_dir); // ambient - let ambient_strength = 0.05; + let ambient_strength = 0.025; let ambient_color = light.color * ambient_strength; // diffuse