@TOC
先叨叨
上篇介紹了如何使用VertexBuffer傳入頂點信息。兩個多星期了我們一直在玩三個點,本篇介紹如何渲染更多的點。
在渲染前考慮一個問題,渲染一個三角形需要三個點,渲染兩個相接的三角形需要幾個點? 答案是6個點,不過其中有兩個點是重復的,如下圖的P1和P2就是重復的。
為了節約內存我們決定給Vulkan只傳四個點。那么想讓Vulkan畫出兩個三角形,就需要告訴Vulkan如何利用這四個點。方法就是給Vulkan一個索引序列。 如下:
VerteixBuffer:【P1, P2, P3, P4】
IndexBuffer:【1,2,3, 1,2,4】
這樣Vulkan會根據IndexBuffer,從VertexBuffer中先取出P1、P2、P3畫一個三角形,再從VertexBuffer中取出P1、P2、P4畫一個三角形。
關鍵代碼
git信息
- repository: https://gitee.com/J8_series/easy-car-ui
- tag:16-IndexBuffer
- url: https://gitee.com/J8_series/easy-car-ui/tree/16-IndexBuffer
TestNode::TestNode()
在TestNode的構造函數中構建數據,4個點和6個索引
TestNode::TestNode()
{m_vertes = {{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}},{{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}},{{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}},{{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}}};m_indices = {0, 1, 2, 2, 3, 0};
}
TestNode::CreateIndexBuffer()
其實原理與VertexBuffer一樣,申請Buffer,為Buffer分配Memory,然后將數據拷貝的Memory,將Buffer綁定到CommandBuffer上。
void TestNode::CreateIndexBuffer()
{VkBuffer indexBuffer{};VkDeviceMemory indexMemory{};VkDeviceSize bufferSize = sizeof(m_indices[0]) * m_indices.size();CreateBuffer(bufferSize,VK_BUFFER_USAGE_TRANSFER_SRC_BIT,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexBuffer,indexMemory);void* data {nullptr};vkMapMemory(m_device, indexMemory, 0, bufferSize, 0, &data);memcpy(data, m_indices.data(), (size_t) bufferSize);vkUnmapMemory(m_device, indexMemory);CreateBuffer(bufferSize,VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,m_deviceIndexBuffer,m_deviceIndexMemory);CopyBuffer(indexBuffer, m_deviceIndexBuffer, bufferSize);vkDestroyBuffer(m_device, indexBuffer, nullptr);vkFreeMemory(m_device, indexMemory, nullptr);
}
void VulkanRender::RecordCommandBuffer()
使用Index后,方式描畫需要將之前vkCmdDraw方法,改為vkCmdDrawIndexed方法
void VulkanRender::RecordCommandBuffer()
{
...vkCmdDrawIndexed(m_commandBuffer, testNode.GetIndexSize(), 1, 0, 0, 0);
...
}