From ecee10d87f5f2c8b56647ce2a2790f03880f573c Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Sat, 8 Aug 2026 05:13:18 -0700 Subject: move models into their own struct and file Force-Push: yes Change-Id: Ic6aa38b7d069825beadeb144eace5a9d23f0d21b --- src/graphics/model.rs | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/graphics/model.rs (limited to 'src/graphics/model.rs') diff --git a/src/graphics/model.rs b/src/graphics/model.rs new file mode 100644 index 0000000..b691d99 --- /dev/null +++ b/src/graphics/model.rs @@ -0,0 +1,141 @@ +#![deny(unsafe_code)] +use crate::error::*; +use crate::graphics::permanent::{ + PermanentGraphicsState, GraphicsStateForReinit +}; +use crate::graphics::render_state::RenderState; +use crate::graphics::util::init_buffer; +use crate::graphics::window_dressing::WindowDressing; +use crate::linear_algebra::{ Vec3, Vec4, Transformation }; +use crate::model_loader::load_model; +use crate::shader_data::{ Vertex, VertexPushBlock }; + +use std::f32::consts::{ TAU }; + +use vulkanalia::{ Device, Instance }; +use vulkanalia::vk::{ self, DeviceV1_0 }; + + +#[derive(Debug)] +pub struct Model { + pub vertex_buffer: vk::Buffer, + vertex_buffer_memory: vk::DeviceMemory, + + pub index_buffer: vk::Buffer, + index_buffer_memory: vk::DeviceMemory, + pub index_count: usize, +} + + +impl Model { + pub fn new(permanent: &PermanentGraphicsState, + for_reinit: &GraphicsStateForReinit, + window_dressing: &WindowDressing) + -> Result + { + let device = &permanent.device; + let instance = &permanent.instance; + let graphics_queue = &permanent.graphics_queue; + let physical_device = &for_reinit.physical_device; + let transient_command_pool = &window_dressing.transient_command_pool; + + let (vertices, indices) = load_model()?; + let index_count = indices.len(); + + let (vertex_buffer, vertex_buffer_memory) + = init_vertex_buffer(vertices, instance, physical_device, device, + graphics_queue, &transient_command_pool)?; + let (index_buffer, index_buffer_memory) + = init_index_buffer(indices, instance, physical_device, device, + graphics_queue, &transient_command_pool)?; + + Ok(Model { + vertex_buffer, + vertex_buffer_memory, + index_buffer, + index_buffer_memory, + index_count, + }) + } + + #[allow(unsafe_code)] + pub fn destroy(self, device: &Device) { + unsafe { device.destroy_buffer(self.vertex_buffer, None) }; + unsafe { device.free_memory(self.vertex_buffer_memory, None) }; + + unsafe { device.destroy_buffer(self.index_buffer, None) }; + unsafe { device.free_memory(self.index_buffer_memory, None) }; + } + + #[allow(unsafe_code)] + pub fn render(&self, time: f32, device: &Device, render_state: &RenderState, + command_buffer: &vk::CommandBuffer, + descriptor_set: &vk::DescriptorSet) + { + unsafe { + device.cmd_bind_vertex_buffers(*command_buffer, 0, + &[self.vertex_buffer], &[0]) + }; + + unsafe { + device.cmd_bind_index_buffer(*command_buffer, self.index_buffer, + 0, vk::IndexType::UINT32) + }; + + unsafe { + device.cmd_bind_descriptor_sets(*command_buffer, + vk::PipelineBindPoint::GRAPHICS, + render_state.pipeline_layout, + 0, + &[*descriptor_set], + &[]) + }; + + let scale = Vec3::new(1.0, 1.0, 1.0); + let model = Transformation { + rotation: Vec4::rotation_quaternion(&Vec3::new(0.0, 1.0, 0.0), + time % TAU), + translation: Vec3::new(0.0, 0.0, 0.0), + }; + let push_block = VertexPushBlock:: { scale, model }; + let size = size_of::>(); + let push_block_bytes = unsafe { + std::slice::from_raw_parts(&push_block as *const VertexPushBlock + as *const u8, + size) + }; + + unsafe { + device.cmd_push_constants(*command_buffer, render_state.pipeline_layout, + vk::ShaderStageFlags::VERTEX, + 0, + push_block_bytes) + }; + + unsafe { + device.cmd_draw_indexed(*command_buffer, self.index_count as u32, + 1, 0, 0, 0) + }; + } +} + + +fn init_vertex_buffer(vertices: Vec>, instance: &Instance, + physical_device: &vk::PhysicalDevice, device: &Device, + queue: &vk::Queue, command_pool: &vk::CommandPool) + -> Result<(vk::Buffer, vk::DeviceMemory)> +{ + init_buffer(instance, physical_device, device, queue, command_pool, + vk::BufferUsageFlags::VERTEX_BUFFER, &vertices) +} + + +fn init_index_buffer(indices: Vec, instance: &Instance, + physical_device: &vk::PhysicalDevice, device: &Device, + queue: &vk::Queue, command_pool: &vk::CommandPool) + -> Result<(vk::Buffer, vk::DeviceMemory)> +{ + init_buffer(instance, physical_device, device, queue, command_pool, + vk::BufferUsageFlags::INDEX_BUFFER, &indices) +} + -- cgit 1.4.1