Vulkan Tutorial 09 圖像與視圖


操作系統:Windows8.1

顯卡:Nivida GTX965M

開發工具:Visual Studio 2017


使用任何的VkImage,包括在交換鏈或者渲染管線中的,我們都需要創建VkImageView對象。從字面上理解它就是一個針對圖像的視圖或容器,通過它具體的渲染管線才能夠讀寫渲染數據,換句話說VkImage不能與渲染管線進行交互。除此之外,圖像視圖可以進一步定義具體Image的格式,比如定義為2D貼圖,那么本質上就不需要任何級別的mipmapping。

 

在本章節我們會新增一個createImageViews函數,為每一個交換鏈中的圖像創建基本的視圖,這些視圖在后面的內容中會被作為顏色目標與渲染管線配合使用。

 

首先添加一個類成員用於保存圖像視圖的句柄集:

std::vector<VkImageView> swapChainImageViews;

創建createImagesViews函數,並在創建交換鏈完成之后調用:

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

void createImageViews() {

}

我們需要做的第一件事情需要定義保存圖像視圖集合的大小:

void createImageViews() {
    swapChainImageViews.resize(swapChainImages.size());

}

下一步,循環迭代所有的交換鏈圖像。

for (size_t i = 0; i < swapChainImages.size(); i++) {

}

創建圖像視圖的參數被定義在VkImageViewCreateInfo結構體中。前幾個參數的填充非常簡單、直接。

VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = swapChainImages[i];

其中viewTypeformat字段用於描述圖像數據該被如何解釋。viewType參數允許將圖像定義為1D textures, 2D textures, 3D textures 和cube maps。

createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = swapChainImageFormat;

components字段允許調整顏色通道的最終的映射邏輯。比如,我們可以將所有顏色通道映射為紅色通道,以實現單色紋理。我們也可以將通道映射具體的常量數值01。在章節中我們使用默認的映射策略。

createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;

subresourceRangle 字段用於描述圖像的使用目標是什么,以及可以被訪問的有效區域。我們的圖像將會作為color targets,沒有任何mipmapping levels 或是多層 multiple layers。

createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;

如果在編寫沉浸式的3D應用程序,比如VR,就需要創建支持多層的交換鏈。並且通過不同的層為每一個圖像創建多個視圖,以滿足不同層的圖像在左右眼渲染時對視圖的需要。

 

創建圖像視圖調用vkCreateImageView函數:

if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
    throw std::runtime_error("failed to create image views!");
}

與圖像不同的是,圖像視圖需要明確的創建過程,所以在程序退出的時候,我們需要添加一個循環去銷毀他們。

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

    ...
}

擁有了圖像視圖后,使用圖像作為貼圖已經足夠了,但是它還沒有准備好作為渲染的 target 。它需要更多的間接步驟去准備,其中一個就是 framebuffer,被稱作幀緩沖區。但首先我們要設置圖形管線。

 

項目代碼 GitHub 獲取。


免責聲明!

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



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