diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-08-08 05:13:18 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-08-08 05:13:18 -0700 |
| commit | ecee10d87f5f2c8b56647ce2a2790f03880f573c (patch) | |
| tree | ebd1078caa5f727acedd4641f102024ce9370148 | |
| parent | 698c9493c89fb0c41eb7a10186c6befc7ad01d79 (diff) | |
move models into their own struct and file
Force-Push: yes Change-Id: Ic6aa38b7d069825beadeb144eace5a9d23f0d21b
| -rw-r--r-- | src/graphics/mod.rs | 1 | ||||
| -rw-r--r-- | src/graphics/model.rs | 141 | ||||
| -rw-r--r-- | src/graphics/render_state.rs | 95 | ||||
| -rw-r--r-- | src/graphics/scene.rs | 51 | ||||
| -rw-r--r-- | src/graphics/util.rs | 27 | ||||
| -rw-r--r-- | src/main.rs | 7 |
6 files changed, 190 insertions, 132 deletions
diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs index 7eca16a..7007429 100644 --- a/src/graphics/mod.rs +++ b/src/graphics/mod.rs @@ -1,5 +1,6 @@ #![deny(unsafe_code)] +pub mod model; pub mod permanent; pub mod render_state; pub mod scene; 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<Self> + { + 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::<f32> { scale, model }; + let size = size_of::<VertexPushBlock::<f32>>(); + let push_block_bytes = unsafe { + std::slice::from_raw_parts(&push_block as *const VertexPushBlock<f32> + 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<Vertex<f32>>, 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<u32>, 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) +} + diff --git a/src/graphics/render_state.rs b/src/graphics/render_state.rs index d8a607c..d918e9a 100644 --- a/src/graphics/render_state.rs +++ b/src/graphics/render_state.rs @@ -3,16 +3,13 @@ use crate::error::*; use crate::graphics::permanent::{ PermanentGraphicsState, GraphicsStateForReinit }; -use crate::graphics::util::{ - allocate_buffer, copy_buffer, stage_in_buffer -}; -use crate::model_loader::load_model; +use crate::graphics::model::Model; use crate::graphics::window_dressing::WindowDressing; use crate::shader_data::{ Vertex, UniformBlock, VertexPushBlock }; use std::mem::size_of; -use vulkanalia::{ Device, Instance }; +use vulkanalia::Device; use vulkanalia::vk::{ self, Handle, HasBuilder, DeviceV1_0 }; @@ -26,12 +23,7 @@ pub struct RenderState { pub pipeline: vk::Pipeline, pub pipeline_layout: vk::PipelineLayout, - pub vertex_buffer: vk::Buffer, - vertex_buffer_memory: vk::DeviceMemory, - - pub index_buffer: vk::Buffer, - index_buffer_memory: vk::DeviceMemory, - pub index_count: usize, + pub model: Option<Model>, pub framebuffers: Vec<vk::Framebuffer>, pub command_buffers: Vec<vk::CommandBuffer>, @@ -46,13 +38,9 @@ impl RenderState { -> Result<Self> { let device = &permanent.device; - let instance = &permanent.instance; - let graphics_queue = &permanent.graphics_queue; - let physical_device = &for_reinit.physical_device; let sample_count = for_reinit.sample_count; let descriptor_set_layout = &for_reinit.descriptor_set_layout; let primary_command_pool = &window_dressing.primary_command_pool; - let transient_command_pool = &window_dressing.transient_command_pool; let swapchain = &window_dressing.swapchain; let depth_format = &window_dressing.depth_format; let color_image_view = &window_dressing.color_image_view; @@ -73,34 +61,22 @@ impl RenderState { device, &swapchain.extent, &swapchain.image_views, &color_image_view, &depth_image_view, &render_pass)?; - let (vertices, indices) = load_model()?; - let index_count = indices.len(); - let command_buffers = init_command_buffers(device, &framebuffers, primary_command_pool)?; - 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)?; - let descriptor_sets = init_descriptor_sets(device, descriptor_set_layout, &uniform_buffers, &descriptor_pool, swapchain.images.len(), &texture_image_view, &sampler)?; + let model = None; + Ok(RenderState { render_pass, pipeline, pipeline_layout, - vertex_buffer, - vertex_buffer_memory, - index_buffer, - index_buffer_memory, - index_count, + model, framebuffers, command_buffers, descriptor_sets, @@ -168,11 +144,9 @@ impl RenderState { { self.destroy_replaceable(device, &window_dressing.primary_command_pool); - 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) }; + if let Some(model) = self.model { + model.destroy(device); + } } #[allow(unsafe_code)] @@ -197,6 +171,10 @@ impl RenderState { unsafe { device.destroy_pipeline_layout(self.pipeline_layout, None) }; unsafe { device.destroy_render_pass(self.render_pass, None) }; } + + pub fn set_model(&mut self, model: Model) { + self.model = Some(model); + } } @@ -476,53 +454,6 @@ fn init_command_buffers(device: &Device, } -fn init_vertex_buffer(vertices: Vec<Vertex<f32>>, 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<u32>, 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) -} - - -#[allow(unsafe_code)] -fn init_buffer<T>(instance: &Instance, - physical_device: &vk::PhysicalDevice, device: &Device, - queue: &vk::Queue, command_pool: &vk::CommandPool, - usage: vk::BufferUsageFlags, contents: &[T]) - -> Result<(vk::Buffer, vk::DeviceMemory)> -{ - let (staging_buffer, staging_memory, size) - = stage_in_buffer(instance, physical_device, device, contents)?; - - let final_usage = vk::BufferUsageFlags::TRANSFER_DST | usage; - let final_memory_flags = vk::MemoryPropertyFlags::DEVICE_LOCAL; - let (final_buffer, device_memory) - = allocate_buffer(instance, physical_device, device, - size as vk::DeviceSize, final_usage, - final_memory_flags)?; - - copy_buffer(device, queue, command_pool, &staging_buffer, &final_buffer, - size as vk::DeviceSize)?; - - unsafe { device.destroy_buffer(staging_buffer, None) }; - unsafe { device.free_memory(staging_memory, None) }; - - Ok((final_buffer, device_memory)) -} - - #[allow(unsafe_code)] fn init_descriptor_sets(device: &Device, layout: &vk::DescriptorSetLayout, buffers: &Vec<vk::Buffer>, pool: &vk::DescriptorPool, diff --git a/src/graphics/scene.rs b/src/graphics/scene.rs index b5cf7bd..f1399b2 100644 --- a/src/graphics/scene.rs +++ b/src/graphics/scene.rs @@ -1,11 +1,6 @@ #![deny(unsafe_code)] use crate::error::*; use crate::graphics::render_state::RenderState; -use crate::linear_algebra::{ Vec3, Vec4, Transformation }; -use crate::shader_data::VertexPushBlock; - -use std::f32::consts::{ TAU }; -use std::mem::size_of; use vulkanalia::Device; use vulkanalia::vk::{ self, HasBuilder, DeviceV1_0 }; @@ -65,49 +60,9 @@ pub fn generate_scene_commands<'a>(image_index: usize, time: f32, render_state.pipeline) }; - unsafe { - device.cmd_bind_vertex_buffers(*command_buffer, 0, - &[render_state.vertex_buffer], &[0]) - }; - - unsafe { - device.cmd_bind_index_buffer(*command_buffer, render_state.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::<f32> { scale, model }; - let size = size_of::<VertexPushBlock::<f32>>(); - let push_block_bytes = unsafe { - std::slice::from_raw_parts(&push_block as *const VertexPushBlock<f32> - 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, render_state.index_count as u32, - 1, 0, 0, 0) - }; + if let Some(model) = &render_state.model { + model.render(time, device, render_state, command_buffer, descriptor_set); + } unsafe { device.cmd_end_render_pass(*command_buffer) }; diff --git a/src/graphics/util.rs b/src/graphics/util.rs index 2debc4e..6190542 100644 --- a/src/graphics/util.rs +++ b/src/graphics/util.rs @@ -8,6 +8,33 @@ use vulkanalia::{ Device, Instance }; use vulkanalia::vk::{ self, Handle, HasBuilder, InstanceV1_0, DeviceV1_0 }; +#[allow(unsafe_code)] +pub fn init_buffer<T>(instance: &Instance, + physical_device: &vk::PhysicalDevice, device: &Device, + queue: &vk::Queue, command_pool: &vk::CommandPool, + usage: vk::BufferUsageFlags, contents: &[T]) + -> Result<(vk::Buffer, vk::DeviceMemory)> +{ + let (staging_buffer, staging_memory, size) + = stage_in_buffer(instance, physical_device, device, contents)?; + + let final_usage = vk::BufferUsageFlags::TRANSFER_DST | usage; + let final_memory_flags = vk::MemoryPropertyFlags::DEVICE_LOCAL; + let (final_buffer, device_memory) + = allocate_buffer(instance, physical_device, device, + size as vk::DeviceSize, final_usage, + final_memory_flags)?; + + copy_buffer(device, queue, command_pool, &staging_buffer, &final_buffer, + size as vk::DeviceSize)?; + + unsafe { device.destroy_buffer(staging_buffer, None) }; + unsafe { device.free_memory(staging_memory, None) }; + + Ok((final_buffer, device_memory)) +} + + pub fn stage_in_buffer<T>(instance: &Instance, physical_device: &vk::PhysicalDevice, device: &Device, contents: &[T]) diff --git a/src/main.rs b/src/main.rs index 1b9d0fe..7bf8f5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![deny(unsafe_code)] use crate::error::*; +use crate::graphics::model::Model; use crate::graphics::permanent::{ PermanentGraphicsState, GraphicsStateForReinit }; @@ -70,8 +71,10 @@ impl Surreality { if enable_swapchain.0 { let window_dressing = WindowDressing::new(&permanent, &for_reinit, enable_anisotropy)?; - let render_state = RenderState::new(&permanent, &for_reinit, - &window_dressing)?; + let mut render_state = RenderState::new(&permanent, &for_reinit, + &window_dressing)?; + render_state.set_model(Model::new(&permanent, &for_reinit, + &window_dressing)?); *self.window_dressing.get_mut() = Some(window_dressing); *self.render_state.get_mut() = Some(render_state); |