Draw a rectangle with an Index buffer

This commit is contained in:
Timothy Warren 2023-04-12 15:13:52 -04:00
parent 71d1e923f0
commit 399cce3d81
3 changed files with 75 additions and 17 deletions

View File

@ -28,6 +28,17 @@ pub const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[vk::KHR_SWAPCHAIN_EXTENSIO
/// The maximum number of frames that can be processed concurrently. /// The maximum number of frames that can be processed concurrently.
pub const MAX_FRAMES_IN_FLIGHT: usize = 2; pub const MAX_FRAMES_IN_FLIGHT: usize = 2;
lazy_static! {
pub static ref VERTICES: Vec<Vertex> = 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. /// Our Vulkan app.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct App { pub struct App {

View File

@ -39,30 +39,32 @@ extern "system" fn debug_callback(
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub(crate) struct AppData { pub(crate) struct AppData {
// Debug // Debug
pub(super) messenger: vk::DebugUtilsMessengerEXT, messenger: vk::DebugUtilsMessengerEXT,
// Surface // Surface
pub(super) surface: vk::SurfaceKHR, pub(super) surface: vk::SurfaceKHR,
// Physical Device / Logical Device // Physical Device / Logical Device
pub(super) physical_device: vk::PhysicalDevice, physical_device: vk::PhysicalDevice,
pub(super) graphics_queue: vk::Queue, pub(super) graphics_queue: vk::Queue,
pub(super) present_queue: vk::Queue, pub(super) present_queue: vk::Queue,
// Swapchain // Swapchain
pub(super) swapchain_format: vk::Format, swapchain_format: vk::Format,
pub(super) swapchain_extent: vk::Extent2D, swapchain_extent: vk::Extent2D,
pub(super) swapchain: vk::SwapchainKHR, pub(super) swapchain: vk::SwapchainKHR,
pub(super) swapchain_images: Vec<vk::Image>, swapchain_images: Vec<vk::Image>,
pub(super) swapchain_image_views: Vec<vk::ImageView>, swapchain_image_views: Vec<vk::ImageView>,
// Pipeline // Pipeline
pub(super) render_pass: vk::RenderPass, render_pass: vk::RenderPass,
pub(super) pipeline_layout: vk::PipelineLayout, pipeline_layout: vk::PipelineLayout,
pub(super) pipeline: vk::Pipeline, pipeline: vk::Pipeline,
// Framebuffers // Framebuffers
pub(super) framebuffers: Vec<vk::Framebuffer>, framebuffers: Vec<vk::Framebuffer>,
// Command Pool // Command Pool
pub(super) command_pool: vk::CommandPool, command_pool: vk::CommandPool,
// Buffers // Buffers
pub(super) vertex_buffer: vk::Buffer, vertex_buffer: vk::Buffer,
pub(super) vertex_buffer_memory: vk::DeviceMemory, vertex_buffer_memory: vk::DeviceMemory,
index_buffer: vk::Buffer,
index_buffer_memory: vk::DeviceMemory,
// Command Buffers // Command Buffers
pub(super) command_buffers: Vec<vk::CommandBuffer>, pub(super) command_buffers: Vec<vk::CommandBuffer>,
// Sync Objects // Sync Objects
@ -95,6 +97,7 @@ impl AppData {
self.create_framebuffers(&device)?; self.create_framebuffers(&device)?;
self.create_command_pool(&instance, &device)?; self.create_command_pool(&instance, &device)?;
self.create_vertex_buffer(&instance, &device)?; self.create_vertex_buffer(&instance, &device)?;
self.create_index_buffer(&instance, &device)?;
self.create_command_buffers(&device)?; self.create_command_buffers(&device)?;
self.create_sync_objects(&device)?; self.create_sync_objects(&device)?;
@ -208,6 +211,8 @@ impl AppData {
/// # Safety /// # Safety
/// Here be Dragons /// Here be Dragons
pub unsafe fn destroy(&mut self, instance: &Instance, device: &Device) { 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.destroy_buffer(self.vertex_buffer, None);
device.free_memory(self.vertex_buffer_memory, None); device.free_memory(self.vertex_buffer_memory, None);
@ -748,6 +753,44 @@ impl AppData {
Ok(()) Ok(())
} }
pub(super) unsafe fn create_index_buffer(
&mut self,
instance: &Instance,
device: &Device,
) -> Result<()> {
let size = (size_of::<u16>() * 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 // Command Buffers
//================================================ //================================================
@ -795,7 +838,13 @@ impl AppData {
self.pipeline, self.pipeline,
); );
device.cmd_bind_vertex_buffers(*command_buffer, 0, &[self.vertex_buffer], &[0]); 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.cmd_end_render_pass(*command_buffer);
device.end_command_buffer(*command_buffer)?; device.end_command_buffer(*command_buffer)?;

View File

@ -26,9 +26,7 @@ pub fn run() -> Result<()> {
*control_flow = ControlFlow::Poll; *control_flow = ControlFlow::Poll;
match event { match event {
// Render a frame if our Vulkan app is not being destroyed // Render a frame if our Vulkan app is not being destroyed
Event::MainEventsCleared if !destroying && !minimized => { Event::MainEventsCleared if !destroying && !minimized => app.render(&window).unwrap(),
app.render(&window).unwrap()
}
// Let the app know it has been resized // Let the app know it has been resized
Event::WindowEvent { Event::WindowEvent {
event: WindowEvent::Resized(size), event: WindowEvent::Resized(size),