From 41ed63e7329d3fb3912290a0689200f1ce91196a Mon Sep 17 00:00:00 2001 From: Lucas Vas Date: Sun, 10 May 2026 22:15:39 -0400 Subject: [PATCH] fix: rendering now displays using camera uniforms --- src/app.rs | 39 +++++++++++++++++++++++++++------- src/common/camera.rs | 23 +++++++++++--------- src/common/mesh.rs | 33 ++++++++++++++++------------ src/shaders/triangle_vert.glsl | 8 +------ test_scene.scene | 2 +- 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/app.rs b/src/app.rs index 2d51947..3419743 100644 --- a/src/app.rs +++ b/src/app.rs @@ -66,7 +66,7 @@ struct VulkanContext { cmd_buffers: Vec>, mesh_registry: Arc, instance_registry: Arc, - camera: Arc, + camera: Camera, camera_resources: Arc, } @@ -169,7 +169,7 @@ impl VulkanContext { let image_extents = swapchain.image_extent(); // Create the camera. - let camera = Arc::new(Camera::new(image_extents)); + let camera = Camera::new(image_extents); let pipeline = Self::create_pipeline( &device, @@ -240,6 +240,8 @@ impl VulkanContext { /// Draws a frame on the current [`Surface`]. pub fn draw_frame(&mut self) -> Result<(), Box> { + self.camera.move_right(0.1); + self.camera_resources.update(&self.camera); let (image_idx, suboptimal, acquire_future) = match swapchain::acquire_next_image(self.swapchain.clone(), None) .map_err(Validated::unwrap) @@ -260,17 +262,35 @@ impl VulkanContext { self.recreate_swapchain(false)? } - let execution = sync::now(self.device.clone()) + // Rebuild command buffers + let cmd_buffers = Self::get_command_buffers( + &self.cmd_allocator, + &self.queue, + &self.pipeline, + &self.framebuffers, + self.camera_resources.descriptor_set(), + self.mesh_registry.clone(), + RenderBatch::build_batches( + self.mem_allocator.clone(), + self.mesh_registry.clone(), + self.instance_registry.clone() + ) + )?; + + let future = sync::now(self.device.clone()) .join(acquire_future) .then_execute( self.queue.clone(), - self.cmd_buffers[image_idx as usize].clone(), + cmd_buffers[image_idx as usize].clone(), )? .then_swapchain_present( self.queue.clone(), SwapchainPresentInfo::swapchain_image_index(self.swapchain.clone(), image_idx), ) - .then_signal_fence_and_flush(); + .then_signal_fence_and_flush() + .map_err(|e| format!("Failed to draw frame: {e}"))?; + + future.wait(None)?; Ok(()) } @@ -431,7 +451,7 @@ impl VulkanContext { let mut builder = AutoCommandBufferBuilder::primary( cmd_allocator.clone(), queue.queue_family_index(), - CommandBufferUsage::MultipleSubmit, + CommandBufferUsage::OneTimeSubmit, ) .expect("Couldn't create command buffer builder"); @@ -495,8 +515,10 @@ impl VulkanContext { self.device.wait_idle()?; }; + let image_extents = self.swapchain.image_extent(); + let (new_swapchain, new_images) = self.swapchain.recreate(SwapchainCreateInfo { - image_extent: self.window.inner_size().into(), + image_extent: image_extents.clone().into(), ..self.swapchain.create_info() })?; @@ -510,7 +532,6 @@ impl VulkanContext { self.framebuffers = new_framebuffers; if resized { - let image_extents = self.swapchain.image_extent(); let new_pipeline = Self::create_pipeline( &self.device, &self.vert_shader, @@ -519,6 +540,8 @@ impl VulkanContext { [image_extents[0] as f32, image_extents[1] as f32], )?; + self.camera.extents(image_extents); + let batches = RenderBatch::build_batches( self.mem_allocator.clone(), self.mesh_registry.clone(), diff --git a/src/common/camera.rs b/src/common/camera.rs index aa6000b..16cb581 100644 --- a/src/common/camera.rs +++ b/src/common/camera.rs @@ -11,7 +11,7 @@ use crate::gpu::camera::CameraUniform; /// A camera set within 3D space. pub struct Camera { /// The position of the camera. - position: Vector3, + pub position: Vector3, /// The forward direction of the camera. forward: Vector3, /// The upward direction of the camera. @@ -31,17 +31,20 @@ impl Camera { extents: impl Into> ) -> Self { let extents = extents.into(); - let position = Vector3::new(1.0, 1.0, 1.0); + let position = Vector3::new(20.0, 20.0, 20.0); let target = Vector3::zeros(); - // Traveling along this vector moves us upward. - let up = Vector3::new(0.0, 1.0, 0.0); + // Traveling along this vector moves us toward the target. + let forward = (target - position).normalize(); + + // A world up vector. + let up_world = Vector3::y_axis(); // Traveling along this vector moves us to the right. - let right = up.cross(&(position - target)).normalize(); + let right = up_world.cross(&forward).normalize(); - // Traveling along this vector moves us toward the target. - let forward = target - position; + // Traveling along this vector moves us upward. + let up = forward.cross(&right).normalize(); Self { position, @@ -55,17 +58,17 @@ impl Camera { /// Moves the camera forward, or backward if given negative speed. pub fn move_forward(&mut self, speed: f32) { - self.forward += self.forward * speed; + self.position += self.forward * speed; } /// Moves the camera to the right, or left if given negative speed. pub fn move_right(&mut self, speed: f32) { - self.right += self.right * speed; + self.position += self.right * speed; } /// Moves the camera upwards, or downward if given negative speed. pub fn move_up(&mut self, speed: f32) { - self.up += self.up * speed; + self.position += self.up * speed; } /// Sets the extents of the viewport. diff --git a/src/common/mesh.rs b/src/common/mesh.rs index b851189..77a7ecd 100644 --- a/src/common/mesh.rs +++ b/src/common/mesh.rs @@ -58,16 +58,21 @@ impl MeshRegistry { }) .collect::>(); - let mut verts = Vec::new(); - let mut indices = Vec::new(); + let mut buf_verts = Vec::new(); + let mut buf_indices = Vec::new(); let mut mesh_list = HashMap::new(); meshes.into_iter().for_each(|(id, obj)| { // Information will be added directly to the verts and indices vectors, and a new Mesh // struct will be created and inserted into the mesh_list. - let vert_start = verts.len(); - let all_verts = obj.vertices(); - let vert_len = all_verts.len(); - verts.extend(all_verts.map(|v| Vertex3::new(v.position(), v.normal().unwrap_or_default()))); + let vert_start = buf_verts.len(); + let all_verts = obj.positions(); + let all_norms = obj.normals(); + let obj_num_verts = all_verts.len(); + all_verts.iter().zip(all_norms.iter()) + .for_each(|(pos, norm)| { + buf_verts.push(Vertex3::new(*pos, *norm)); + }); + // buf_verts.extend(all_verts.map(|v| Vertex3::new(v.position(), v.normal().unwrap_or_default()))); let index_list = obj .triangles() @@ -77,9 +82,11 @@ impl MeshRegistry { .collect::>() }) .collect::>(); - let index_start = indices.len(); - let index_len = index_list.len(); - indices.extend(index_list); + let index_start = buf_indices.len(); + let obj_num_idx = index_list.len(); + buf_indices.extend(index_list); + + println!("Loaded mesh {} with {} vertices and {} indices", id, obj_num_verts, obj_num_idx); // TODO Create bounding boxes for each mesh and associate them with the struct. mesh_list.insert( @@ -87,16 +94,16 @@ impl MeshRegistry { Mesh { id, vertex_loc: vert_start, - vertex_count: vert_len, + vertex_count: obj_num_verts, index_loc: index_start, - index_count: index_len, + index_count: obj_num_idx, }, ); }); // Allocate buffers for the information. - let vertex_buffer = Self::alloc_vert_buffer(allocator.clone(), verts); - let index_buffer = Self::alloc_index_buffer(allocator.clone(), indices); + let vertex_buffer = Self::alloc_vert_buffer(allocator.clone(), buf_verts); + let index_buffer = Self::alloc_index_buffer(allocator.clone(), buf_indices); // Finally, return the struct. Self { diff --git a/src/shaders/triangle_vert.glsl b/src/shaders/triangle_vert.glsl index 41f089d..4a9b67c 100644 --- a/src/shaders/triangle_vert.glsl +++ b/src/shaders/triangle_vert.glsl @@ -11,11 +11,6 @@ layout(location = 4) in vec4 transform_col3; layout(location = 5) in vec4 transform_col4; // Per-frame information - CameraUniform struct -//layout(location = 6) uniform vec4 proj_col1; -//layout(location = 7) uniform vec4 proj_col2; -//layout(location = 8) uniform vec4 proj_col3; -//layout(location = 9) uniform vec4 proj_col4; - layout(set = 0, binding = 0) uniform CameraUniform { mat4 view; mat4 projection; @@ -24,9 +19,8 @@ layout(set = 0, binding = 0) uniform CameraUniform { void main() { // We then multiply each vertex by its transform to find the correct location in the scene. mat4 transform = mat4(transform_col1, transform_col2, transform_col3, transform_col4); - //mat4 proj = mat4(proj_col1, proj_col2, proj_col3, proj_col4); mat4 mvp = camera.projection * camera.view * transform; - gl_Position = transform * vec4(position, 1.0f); + gl_Position = mvp * vec4(position, 1.0f); } diff --git a/test_scene.scene b/test_scene.scene index f5818f2..5ff2d1f 100644 --- a/test_scene.scene +++ b/test_scene.scene @@ -1,7 +1,7 @@ { "name": "Testing Scene", "mesh_paths": { - "gunship": "laat_gunship/laat.obj" + "gunship": "laat_gunship/scene.obj" }, "instances": { "gunship": {