summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-08-08 05:13:18 -0700
committerIrene Knapp <ireneista@irenes.space>2026-08-08 05:13:18 -0700
commitecee10d87f5f2c8b56647ce2a2790f03880f573c (patch)
treeebd1078caa5f727acedd4641f102024ce9370148
parent698c9493c89fb0c41eb7a10186c6befc7ad01d79 (diff)
move models into their own struct and file
Force-Push: yes
Change-Id: Ic6aa38b7d069825beadeb144eace5a9d23f0d21b
-rw-r--r--src/graphics/mod.rs1
-rw-r--r--src/graphics/model.rs141
-rw-r--r--src/graphics/render_state.rs95
-rw-r--r--src/graphics/scene.rs51
-rw-r--r--src/graphics/util.rs27
-rw-r--r--src/main.rs7
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);