使用任何 VkImage 对象,包括处于交换链中的,处于渲染管线中的,都需要我们创建一个 VkImageView 对象来绑定访问它。图像视图描述了访问图像的方式,以及图像的哪一部分可以被访问。比如,图像可以被图像视图描述为一个没有细化级别的二维深度纹理,进而可以在其上进行与二维深度纹理相关的操作。
示例demo:
//存储图像视图--5
std::vector<VkImageView> swapChainImageViews;
//为交换链中的每一个图像建立图像视图--5
void createImageViews(){
//分配足够的数组空间来存储图像视图
swapChainImageViews.resize(swapChainImages.size());
//遍历所有交换链图像,创建图像视图
for(size_t i=0; i< swapChainImages.size(); i++){
//设置图像视图结构体相关信息
VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = swapChainImages[i];
//viewType 和 format 成员变量用于指定图像数据的解释方式。
//viewType用于指定图像被看作是一维纹理、二维纹理、三维纹理还是立方体贴图
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;
//subresourceRange用于指定图像的用途和图像的哪一部分可以被访问
//在这里,我们的图像被用作渲染目标,并且没有细分级别,只存在一个图层
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;
/**
如果读者在编写 VR 一类的应用程序,可能会使用支持多个层次的交换链。
这时,读者应该为每个图像创建多个图像视图,分别用来访问左眼和右眼两个不同的图层
*/
//创建图像视图
if(vkCreateImageView(device,&createInfo,nullptr,
&swapChainImageViews[i]) != VK_SUCCESS){
throw std::runtime_error("failed to create image views!");
}
//有了图像视图,就可以将图像作为纹理使用,但作为渲染目标,还需要帧缓冲对象
}
}
//销毁图像视图--5
for(auto imageView : swapChainImageViews){
vkDestroyImageView(device,imageView,nullptr);
}