diff --git a/src/light.rs b/src/light.rs index b685a3f..cd7d150 100644 --- a/src/light.rs +++ b/src/light.rs @@ -3,11 +3,10 @@ use bytemuck::{Zeroable, Pod}; use crate::OPENGL_TO_WGPU_MATRIX; pub struct Light { - pos: cgmath::Point3, - color: wgpu::Color, - fov: f32, - depth: Range, - target_view: wgpu::TextureView, + pub(crate) pos: cgmath::Point3, + pub(crate) color: wgpu::Color, + pub(crate) fov: f32, + pub(crate) depth: Range, } #[repr(C)] diff --git a/src/main.rs b/src/main.rs index 5070ae1..81bf574 100644 --- a/src/main.rs +++ b/src/main.rs @@ -128,7 +128,6 @@ fn main() { power_preference: wgpu::PowerPreference::HighPerformance, compatible_surface: Some(&surface), }) - .await .unwrap(); @@ -156,7 +155,6 @@ fn main() { }, trace_dir.ok().as_ref().map(std::path::Path::new), ) - .await .unwrap(); @@ -226,7 +224,7 @@ fn main() { log::info!("Entering render loop..."); - let mut renderer = render::Renderer::init(); + let mut renderer = render::Renderer::init(&device, &sd_desc); // This is just an winit event loop diff --git a/src/render.rs b/src/render.rs index 6e7f58e..7004e15 100644 --- a/src/render.rs +++ b/src/render.rs @@ -5,6 +5,7 @@ use std::{iter, num::NonZeroU32, ops::Range, rc::Rc}; use crate::OPENGL_TO_WGPU_MATRIX; use crate::light::LightRaw; use crate::geometry::{Vertex, import_mesh, create_plane}; +use wgpu::Buffer; #[repr(C)] @@ -45,7 +46,11 @@ pub struct Renderer { shadow_pass: Pass, forward_pass: Pass, forward_depth: wgpu::TextureView, + light_uniform_buf: wgpu::Buffer, + plane_uniform_buf: wgpu::Buffer, + plane_vertex_buf: wgpu::Buffer, + plane_index_buf: wgpu::Buffer, } impl Renderer { @@ -72,52 +77,58 @@ impl Renderer { impl Renderer { - pub fn create_buffer(&mut self, device: &wgpu::Device) { + pub fn create_buffer(&mut self, + device: &wgpu::Device, + indices: Vec, + vertices: Vec) -> (Rc, Rc) { // Creates the vertex and index buffers for the cube let vertex_size = mem::size_of::(); - let (cube_vertex_data, cube_index_data) = import_mesh("/home/mrh/source/3d-min-viable-eng/resources/my_tree.obj"); - let cube_vertex_buf = Rc::new(device.create_buffer_init( + //import_mesh("/home/mrh/source/3d-min-viable-eng/resources/my_tree.obj"); + + let vertex_buf = Rc::new(device.create_buffer_init( &wgpu::util::BufferInitDescriptor { - label: Some("Cubes Vertex Buffer"), - contents: bytemuck::cast_slice(&cube_vertex_data), + label: Some("vertex-buffer"), + contents: bytemuck::cast_slice(&vertices), usage: wgpu::BufferUsage::VERTEX, }, )); - let cube_index_buf = Rc::new(device.create_buffer_init( + let index_buf = Rc::new(device.create_buffer_init( &wgpu::util::BufferInitDescriptor { - label: Some("Cubes Index Buffer"), - contents: bytemuck::cast_slice(&cube_index_data), + label: Some("index-buffer"), + contents: bytemuck::cast_slice(&indices), usage: wgpu::BufferUsage::INDEX, }, )); - // Creates the vertex and index buffers for the plane - let (plane_vertex_data, plane_index_data) = create_plane(7.0); - let plane_vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Plane Vertex Buffer"), - contents: bytemuck::cast_slice(&plane_vertex_data), - usage: wgpu::BufferUsage::VERTEX, - }); - - let plane_index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Plane Index Buffer"), - contents: bytemuck::cast_slice(&plane_index_data), - usage: wgpu::BufferUsage::INDEX, - }); + // // Creates the vertex and index buffers for the plane + // let (plane_vertex_data, plane_index_data) = create_plane(7.0); + // self.plane_vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + // label: Some("Plane Vertex Buffer"), + // contents: bytemuck::cast_slice(&plane_vertex_data), + // usage: wgpu::BufferUsage::VERTEX, + // }); + // + // self.plane_index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + // label: Some("Plane Index Buffer"), + // contents: bytemuck::cast_slice(&plane_index_data), + // usage: wgpu::BufferUsage::INDEX, + // }); // Creates the uniform for entities, which does the rotation and projection let entity_uniform_size = mem::size_of::() as wgpu::BufferAddress; - let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { + self.plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { label: None, size: entity_uniform_size, usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, mapped_at_creation: false, }); + (vertex_buf, index_buf) + } - pub fn init(device: &wgpu::Device) -> Renderer { + pub fn init(device: &wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Renderer { // Pre init the light uniform, with slots enough for MAX_LIGHTS let light_uniform_size = @@ -160,7 +171,6 @@ impl Renderer { }], }); - /* There appear to be two passes required for shadows, the shadow pass, and the forward pass Need to open this up in renderdoc and see what it's actually doing @@ -309,16 +319,64 @@ impl Renderer { }); let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); + + // I need to know the number of lights... let forward_uniforms = ForwardUniforms { proj: *mx_total.as_ref(), - num_lights: [lights.len() as u32, 0, 0, 0], + //num_lights: [lights.len() as u32, 0, 0, 0], + num_lights: [1 as u32, 0, 0, 0], }; + + let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Uniform Buffer"), contents: bytemuck::bytes_of(&forward_uniforms), usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, }); + let shadow_texture = device.create_texture(&wgpu::TextureDescriptor { + size: Self::SHADOW_SIZE, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: Self::SHADOW_FORMAT, + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED, + label: None, + }); + + let mut shadow_target_views = (0..2) + .map(|i| { + Some(shadow_texture.create_view(&wgpu::TextureViewDescriptor { + label: Some("shadow"), + format: None, + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + level_count: None, + base_array_layer: i as u32, + array_layer_count: NonZeroU32::new(1), + })) + }) + .collect::>(); + // shadow_target_views[0].take().unwrap(), + // pub(crate) target_view: wgpu::TextureView, + + + let shadow_view = shadow_texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let shadow_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("shadow"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Nearest, + compare: Some(wgpu::CompareFunction::LessEqual), + ..Default::default() + }); + + // Create bind group let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_group_layout, diff --git a/src/runtime.rs b/src/runtime.rs index a852223..eb5d3cc 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -2,6 +2,7 @@ use std::rc::Rc; use bytemuck::__core::mem; use crate::light::Light; use crate::render::EntityUniforms; +use bytemuck::__core::num::NonZeroU32; /* @@ -10,8 +11,8 @@ This will eventually be within an ECS... So I will probably take the same approach that I did for tracer and have meta-data for rendering held by the ECS, and a render system which will cycle through them and render - */ + struct Entity { mx_world: cgmath::Matrix4, rotation_speed: f32, @@ -91,6 +92,7 @@ impl Runtime { }], label: None, }); + Entity { mx_world: cgmath::Matrix4::identity(), rotation_speed: 0.0, @@ -154,43 +156,6 @@ impl Runtime { } // Create other resources - let shadow_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("shadow"), - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Nearest, - compare: Some(wgpu::CompareFunction::LessEqual), - ..Default::default() - }); - - let shadow_texture = device.create_texture(&wgpu::TextureDescriptor { - size: Self::SHADOW_SIZE, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: Self::SHADOW_FORMAT, - usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED, - label: None, - }); - let shadow_view = shadow_texture.create_view(&wgpu::TextureViewDescriptor::default()); - - let mut shadow_target_views = (0..2) - .map(|i| { - Some(shadow_texture.create_view(&wgpu::TextureViewDescriptor { - label: Some("shadow"), - format: None, - dimension: Some(wgpu::TextureViewDimension::D2), - aspect: wgpu::TextureAspect::All, - base_mip_level: 0, - level_count: None, - base_array_layer: i as u32, - array_layer_count: NonZeroU32::new(1), - })) - }) - .collect::>(); // This is just metadata we hold for the lights. We can hold onto this let lights = vec![ @@ -204,7 +169,6 @@ impl Runtime { }, fov: 60.0, depth: 1.0..20.0, - target_view: shadow_target_views[0].take().unwrap(), }, Light { pos: cgmath::Point3::new(-5.0, 7.0, 10.0), @@ -216,16 +180,12 @@ impl Runtime { }, fov: 45.0, depth: 1.0..20.0, - target_view: shadow_target_views[1].take().unwrap(), }, ]; Runtime { entities, lights, - lights_are_dirty: true, - - light_uniform_buf, } }