diff --git a/src/app.rs b/src/app.rs index 032af4e..6b25052 100644 --- a/src/app.rs +++ b/src/app.rs @@ -28,6 +28,17 @@ pub const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[vk::KHR_SWAPCHAIN_EXTENSIO /// The maximum number of frames that can be processed concurrently. pub const MAX_FRAMES_IN_FLIGHT: usize = 2; +lazy_static! { + pub static ref VERTICES: Vec = vec![ + Vertex::new(glm::vec2(-0.5, -0.5), glm::vec3(1.0, 0.0, 0.0)), + Vertex::new(glm::vec2(0.5, -0.5), glm::vec3(0.0, 1.0, 0.0)), + Vertex::new(glm::vec2(0.5, 0.5), glm::vec3(0.0, 0.0, 1.0)), + Vertex::new(glm::vec2(-0.5, 0.5), glm::vec3(1.0, 1.0, 1.0)), + ]; +} + +pub const INDICES: &[u16] = &[0, 1, 2, 2, 3, 0]; + /// Our Vulkan app. #[derive(Clone, Debug)] pub struct App { diff --git a/src/app/data.rs b/src/app/data.rs index dc50477..1de55eb 100644 --- a/src/app/data.rs +++ b/src/app/data.rs @@ -39,30 +39,32 @@ extern "system" fn debug_callback( #[derive(Clone, Debug, Default)] pub(crate) struct AppData { // Debug - pub(super) messenger: vk::DebugUtilsMessengerEXT, + messenger: vk::DebugUtilsMessengerEXT, // Surface pub(super) surface: vk::SurfaceKHR, // Physical Device / Logical Device - pub(super) physical_device: vk::PhysicalDevice, + physical_device: vk::PhysicalDevice, pub(super) graphics_queue: vk::Queue, pub(super) present_queue: vk::Queue, // Swapchain - pub(super) swapchain_format: vk::Format, - pub(super) swapchain_extent: vk::Extent2D, + swapchain_format: vk::Format, + swapchain_extent: vk::Extent2D, pub(super) swapchain: vk::SwapchainKHR, - pub(super) swapchain_images: Vec, - pub(super) swapchain_image_views: Vec, + swapchain_images: Vec, + swapchain_image_views: Vec, // Pipeline - pub(super) render_pass: vk::RenderPass, - pub(super) pipeline_layout: vk::PipelineLayout, - pub(super) pipeline: vk::Pipeline, + render_pass: vk::RenderPass, + pipeline_layout: vk::PipelineLayout, + pipeline: vk::Pipeline, // Framebuffers - pub(super) framebuffers: Vec, + framebuffers: Vec, // Command Pool - pub(super) command_pool: vk::CommandPool, + command_pool: vk::CommandPool, // Buffers - pub(super) vertex_buffer: vk::Buffer, - pub(super) vertex_buffer_memory: vk::DeviceMemory, + vertex_buffer: vk::Buffer, + vertex_buffer_memory: vk::DeviceMemory, + index_buffer: vk::Buffer, + index_buffer_memory: vk::DeviceMemory, // Command Buffers pub(super) command_buffers: Vec, // Sync Objects @@ -95,6 +97,7 @@ impl AppData { self.create_framebuffers(&device)?; self.create_command_pool(&instance, &device)?; self.create_vertex_buffer(&instance, &device)?; + self.create_index_buffer(&instance, &device)?; self.create_command_buffers(&device)?; self.create_sync_objects(&device)?; @@ -208,6 +211,8 @@ impl AppData { /// # Safety /// Here be Dragons pub unsafe fn destroy(&mut self, instance: &Instance, device: &Device) { + device.destroy_buffer(self.index_buffer, None); + device.free_memory(self.index_buffer_memory, None); device.destroy_buffer(self.vertex_buffer, None); device.free_memory(self.vertex_buffer_memory, None); @@ -748,6 +753,44 @@ impl AppData { Ok(()) } + pub(super) unsafe fn create_index_buffer( + &mut self, + instance: &Instance, + device: &Device, + ) -> Result<()> { + let size = (size_of::() * INDICES.len()) as u64; + let (staging_buffer, staging_buffer_memory) = self.create_buffer( + instance, + device, + size, + vk::BufferUsageFlags::TRANSFER_SRC, + vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, + )?; + + let memory = + device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; + memcpy(INDICES.as_ptr(), memory.cast(), INDICES.len()); + device.unmap_memory(staging_buffer_memory); + + let (index_buffer, index_buffer_memory) = self.create_buffer( + instance, + device, + size, + vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::INDEX_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + )?; + + self.index_buffer = index_buffer; + self.index_buffer_memory = index_buffer_memory; + + self.copy_buffer(device, staging_buffer, index_buffer, size)?; + + device.destroy_buffer(staging_buffer, None); + device.free_memory(staging_buffer_memory, None); + + Ok(()) + } + //================================================ // Command Buffers //================================================ @@ -795,7 +838,13 @@ impl AppData { self.pipeline, ); device.cmd_bind_vertex_buffers(*command_buffer, 0, &[self.vertex_buffer], &[0]); - device.cmd_draw(*command_buffer, 3, 1, 0, 0); + device.cmd_bind_index_buffer( + *command_buffer, + self.index_buffer, + 0, + vk::IndexType::UINT16, + ); + device.cmd_draw_indexed(*command_buffer, INDICES.len() as u32, 1, 0, 0, 0); device.cmd_end_render_pass(*command_buffer); device.end_command_buffer(*command_buffer)?; diff --git a/src/lib.rs b/src/lib.rs index 93eea26..188cd7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,9 +26,7 @@ pub fn run() -> Result<()> { *control_flow = ControlFlow::Poll; match event { // Render a frame if our Vulkan app is not being destroyed - Event::MainEventsCleared if !destroying && !minimized => { - app.render(&window).unwrap() - } + Event::MainEventsCleared if !destroying && !minimized => app.render(&window).unwrap(), // Let the app know it has been resized Event::WindowEvent { event: WindowEvent::Resized(size),