diff --git a/src/main.c b/src/main.c index 5745a1e..d46cea0 100644 --- a/src/main.c +++ b/src/main.c @@ -73,6 +73,9 @@ typedef struct ApplicationState { VkBuffer vertex_buffer; VkDeviceMemory vertex_buffer_memory; + + VkBuffer index_buffer; + VkDeviceMemory index_buffer_memory; } ApplicationState; typedef struct QueueFamilyIndices { @@ -88,9 +91,14 @@ typedef struct Vertex { } Vertex; const Vertex vertices[] = { - {{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}}, - {{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, - {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}} + {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, + {{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}}, + {{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, + {{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}} +}; + +const uint16_t indices[] = { + 0, 1, 2, 2, 3, 0 }; void create_window(ApplicationState* state) { @@ -999,6 +1007,29 @@ void create_vertex_buffer(ApplicationState* state) { vkFreeMemory(state->device, staging_buffer_memory, NULL); } +void create_index_buffer(ApplicationState* state) { + VkDeviceSize buffer_size = sizeof(uint16_t) * ARRSIZE(indices); + + //we use a staging buffer for transferring data in order to use a more efficient memory type for the index buffer + VkBuffer staging_buffer; + VkDeviceMemory staging_buffer_memory; + create_buffer(state, buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + &staging_buffer, &staging_buffer_memory); + + void* data; + vkMapMemory(state->device, staging_buffer_memory, 0, buffer_size, 0, &data); + memcpy(data, indices, buffer_size); + vkUnmapMemory(state->device, staging_buffer_memory); + + create_buffer(state, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &state->index_buffer, &state->index_buffer_memory); + + copy_buffer(state, staging_buffer, state->index_buffer, buffer_size); + + vkDestroyBuffer(state->device, staging_buffer, NULL); + vkFreeMemory(state->device, staging_buffer_memory, NULL); +} + void create_command_buffer(ApplicationState* state) { VkCommandBufferAllocateInfo command_buf_allocate_info = {0}; command_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; @@ -1049,6 +1080,7 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff VkBuffer vertex_buffers[] = {state->vertex_buffer}; VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets); + vkCmdBindIndexBuffer(command_buffer, state->index_buffer, 0, VK_INDEX_TYPE_UINT16); //setup dynamic state VkViewport viewport = {0}; @@ -1069,7 +1101,7 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff vkCmdSetScissor(command_buffer, 0, 1, &scissor); //vertex count, instance count, first vertex and first instance - vkCmdDraw(command_buffer, ARRSIZE(vertices), 1, 0, 0); + vkCmdDrawIndexed(command_buffer, ARRSIZE(indices), 1, 0, 0, 0); vkCmdEndRenderPass(command_buffer); @@ -1112,6 +1144,7 @@ void init_vulkan(ApplicationState* state) { create_framebuffers(state); create_command_pool(state); create_vertex_buffer(state); + create_index_buffer(state); create_command_buffer(state); create_sync_objects(state); } @@ -1194,6 +1227,8 @@ void terminate(ApplicationState* state) { } vkDestroyBuffer(state->device, state->vertex_buffer, NULL); vkFreeMemory(state->device, state->vertex_buffer_memory, NULL); + vkDestroyBuffer(state->device, state->index_buffer, NULL); + vkFreeMemory(state->device, state->index_buffer_memory, NULL); vkDestroySwapchainKHR(state->device, state->swapchain, NULL); vkDestroyDevice(state->device, NULL);