@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);
...
}