作業系統: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];
其中viewType和format字段用于描述圖像資料該被如何解釋。viewType參數允許将圖像定義為1D textures, 2D textures, 3D textures 和cube maps。
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = swapChainImageFormat;
components字段允許調整顔色通道的最終的映射邏輯。比如,我們可以将所有顔色通道映射為紅色通道,以實作單色紋理。我們也可以将通道映射具體的常量數值0和1。在章節中我們使用預設的映射政策。
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,被稱作幀緩沖區。但首先我們要設定圖形管線。