【Vulkan入门】16-IndexBuffer

发布于:2024-12-19 ⋅ 阅读:(10) ⋅ 点赞:(0)

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

运行结果

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到