//GET/DRAW THE TRIANGLE(s) (we're actually drawing a rectangle as of writing)! :P
VkBuffervertexBuffers[]={vertexBuffer};
VkDeviceSizeoffsets[]={0};
vkCmdBindVertexBuffers(commandBuffers[i],0,1,vertexBuffers,offsets);//Bind the vertex buffers to bindings.
vkCmdBindIndexBuffer(commandBuffers[i],indexBuffer,0,VK_INDEX_TYPE_UINT32);//We can only bind one index buffer for use when drawing.
// /\ Fields: command buffer, offset, # of bindings to specify vert buffers for, array of vertex buffers to bind, byte offsets to read vertex data from.
//Buffer to record to, vertexCount, instanceCount (1 if not doing that), firstVertex (vertex buffer offset), firstInstance (instance offset).
vkCmdDraw(commandBuffers[i],static_cast<uint32_t>(vertices.size()),1,0,0);//vertexCount is now dynamic to vertices.
//Buffer to record to, indicesCount, instanceCount (1 if not doing that), firstIndex (index buffer offset), indexOffset (offset to add to the indices), firstInstance (instance offset).
vkCmdDrawIndexed(commandBuffers[i],static_cast<uint32_t>(indices.size()),1,0,0,0);//vertexCount is now dynamic to vertices.
// /\ The "Indexed" part lets us use the index buffer.
//End the render pass.
vkCmdEndRenderPass(commandBuffers[i]);
...
...
@@ -1436,6 +1451,9 @@ class HelloTriangleApplication {
// Use a memory type that lets us write to it from the CPU (HOST_VISIBLE_BIT), and also use COHERENT_BIT, for vertex buffer.
//NOTE: In a real world app, don't call vkAllocateMemory for each buffer - max simultaneous memory allocations can be as low as 4096, even on high end hardware.
// The right way to do it is to create a custom alocator to split up a single allocation among many different objects, using "offset" parameters.
// This can be implemented oneself - or one can use the VulkanMemoryAllocator library! But for these kinds of things here, we're not coming close to hitting that limit.
copyBuffer(stagingBuffer,indexBuffer,bufferSize);//Do the buffer copy. The GPU gets to read from optimized local memory, the CPU gets to actually write memory at all!
vkDestroyBuffer(device,stagingBuffer,nullptr);
vkFreeMemory(device,stagingBufferMemory,nullptr);//Kill the temp staging buffer and its memory.
}
voidinitVulkan(){
createInstance();//The Vulkan instance is the link between application and Vulkan.
setupDebugCallback();//Setup the debug callback that interfaces with the validation layer.
...
...
@@ -1542,6 +1587,7 @@ class HelloTriangleApplication {
createFramebuffers();//Make the framebuffers for all the images in the swap chain - and use the one that corresponds to the retrieved image at draw time.
createCommandPool();//Commands, like draw/memory transfer, are executed by command buffer objects. All the hard setup can be done in multiple threads, then!
createVertexBuffer();//Vertex buffers store vertex data to be read by the GPU.
createIndexBuffer();//Index buffers store indices to the vertex buffer, to reduce redundancy.
createCommandBuffers();// We need one command buffer for each image in the swap chain, because they bind to framebuffers.
createSemaphore();//Create the sephamores we need to synchronize things.
}
...
...
@@ -1639,6 +1685,9 @@ class HelloTriangleApplication {
voidcleanup(){
cleanupSwapChain();//Does swapchain related cleanup.
vkDestroyBuffer(device,indexBuffer,nullptr);//Kill the index buffer. It does not depend on the swap chain.
vkFreeMemory(device,indexBufferMemory,nullptr);//We need to free all allocated memory manually. This is the memory holding the index buffer.
vkDestroyBuffer(device,vertexBuffer,nullptr);//Kill the vertex buffer. It does not depend on the swap chain.
vkFreeMemory(device,vertexBufferMemory,nullptr);//We need to free all allocated memory manually. This is the memory holding the vertex buffer.