Vulkan Tutorial 15 Framebuffers


操作系統:Windows8.1

顯卡:Nivida GTX965M

開發工具:Visual Studio 2017


我們在前面的章節中已經討論了很多次framebuffers幀緩沖區,到目前為止我們配置了render pass渲染通道並希望輸出一個與交換鏈圖像格式一致的幀緩沖區,但是我們實際上還沒有創建。

 

在render pass創建階段我們指定了具體的附件,並通過VkFramebuffer對象包裝綁定。幀緩沖區對象引用表示為附件的所有的VkImageView對象。在我們的例子中只會使用一個幀緩沖區:color attachment。然而我們作為附件的圖像依賴交換鏈用於呈現時返回的圖像。這意味着我們必須為交換鏈中的所有圖像創建一個幀緩沖區,並在繪制的時候使用對應的圖像。

 

最后,在類成員中創建另一個std::vector用於保存framebuffers:

std::vector<VkFramebuffer> swapChainFramebuffers;

我們在新的函數createFramebuffers中為數組創建對象集合,這個函數在initVulkan創建完管線后調用:

void initVulkan() {
    createInstance();
    setupDebugCallback();
    createSurface();
    pickPhysicalDevice();
    createLogicalDevice();
    createSwapChain();
    createImageViews();
    createRenderPass();
    createGraphicsPipeline();
    createFramebuffers();
}

...

void createFramebuffers() {

}

動態調整用於保存framebuffers的容器大小:

void createFramebuffers() {
    swapChainFramebuffers.resize(swapChainImageViews.size());
}

我們接下來迭代左右的圖像視圖並通過它們創建對應的framebuffers:

for (size_t i = 0; i < swapChainImageViews.size(); i++) {
    VkImageView attachments[] = {
        swapChainImageViews[i]
    };

    VkFramebufferCreateInfo framebufferInfo = {};
    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    framebufferInfo.renderPass = renderPass;
    framebufferInfo.attachmentCount = 1;
    framebufferInfo.pAttachments = attachments;
    framebufferInfo.width = swapChainExtent.width;
    framebufferInfo.height = swapChainExtent.height;
    framebufferInfo.layers = 1;

    if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
        throw std::runtime_error("failed to create framebuffer!");
    }
}

如你所見,創建framebuffers是非常直接的。首先需要指定framebuffer需要兼容的renderPass。我們只能使用與其兼容的渲染通道的幀緩沖區,這大體上意味着它們使用相同的附件數量和類型。

 

attachmentCountpAttachments參數指定在渲染通道的pAttachment數組中綁定到相應的附件描述的VkImageView對象。

 

widthheight參數是容易理解的,layer是指定圖像數組中的層數。我們的交換鏈圖像是單個圖像,因此層數為1

 

我們在圖像視圖和渲染通道渲染完畢之后,刪除對應的幀緩沖區:

void cleanup() {
    for (size_t i = 0; i < swapChainFramebuffers.size(); i++) {
        vkDestroyFramebuffer(device, swapChainFramebuffers[i], nullptr);
    }

    ...
}

我們已經達到了一個里程碑,我們擁有渲染需要的所有對象。在下一章中,我們將編寫第一個實際繪制的命令。

 

項目代碼 GitHub 地址。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM