Vulkan,一个物体需要什么变量?如同在可以单独更新的单独网格中一样



所以我一直在试验,我可以添加一个新的"对象";通过将场景中的每个模型添加到同一个顶点缓冲区,但这对体素游戏不好,因为我不想每次玩家破坏块时都必须重新组织整个世界的顶点。

看来我还可以添加一个新的";对象";通过为它创建一个新的顶点和索引缓冲区,并简单地将它和所有其他顶点缓冲区同时绑定到命令缓冲区数组,如下所示:

        vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
        vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
        vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i], 0, nullptr);
        // mesh 1
        VkBuffer vertexBuffers[] = { vertexBuffer };
        VkDeviceSize offsets[] = { 0 };
        vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets);
        vkCmdBindIndexBuffer(commandBuffers[i], indexBuffer, 0, VK_INDEX_TYPE_UINT32);
        vkCmdDrawIndexed(commandBuffers[i], static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
        // mesh 2
        VkBuffer vertexBuffers2[] = { vertexBuffer2 };
        vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers2, offsets);
        vkCmdBindIndexBuffer(commandBuffers[i], indexBuffer2, 0, VK_INDEX_TYPE_UINT32);
        vkCmdDrawIndexed(commandBuffers[i], static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
        vkCmdEndRenderPass(commandBuffers[i]);

但这需要我每次都将所有顶点缓冲区绑定到命令缓冲区阵列,即使只有一个网格被更新或创建/销毁。那么我该如何";添加";新的";游戏对象;哪些顶点和索引可以更新,而不必遍历场景中的所有其他内容?还是绑定到已经计算好的顶点和索引缓冲区相对较快,这是标准的?

我尝试过用每个对象的命令缓冲区:

 VkSubmitInfo submits[] = { submitInfo, submitInfo2 };
    if (vkQueueSubmit(graphicsQueue, 2, submits, inFlightFences[currentFrame]) != VK_SUCCESS) {
        throw std::runtime_error("failed to submit draw command buffer!");
    }

但它只渲染队列中的最后一个对象(如果我说提交大小为1,它将渲染第一个对象(。

我已经尝试添加一个单独的描述符集、描述符池和管道,但它仍然只呈现队列中的最后一个命令缓冲区。我试着为每个对象添加一个新的命令池,但commandPool被几十个其他函数使用,而且看起来应该只有一个。

您将世界划分为块,一次绘制一个块。所有块在(单个(顶点缓冲区中都为它们保留了一些空间,当某个内容发生变化时,您只更新那一个块。如果区块变得太大。。。嗯,你可能需要某种内存分配系统。

不要为每一件小事创建单独的缓冲区。缓冲区只容纳数据。任何数据。您甚至可以将不同管道的不同顶点格式存储在同一个缓冲区中——只是存储在缓冲区内的不同位置,并使用偏移量进行绑定。若所有顶点都整齐地排列在数组中(很可能是这样(,不要为了绘制不同的网格而重新绑定。如果只想绘制缓冲区的一部分,只需使用draw命令即可。

命令缓冲区只是gpu的一个指令块。你不需要每个物体一个。然而,一个不能同时使用和写入,因此在运行中每帧至少需要一个,一个要写入。管道(描述符集,以及几乎所有绑定的东西(只是gpu在绑定后开始使用的一组状态。在命令缓冲区开始时,状态是未定义的-它不会以任何方式在命令缓冲区时继承。

最新更新