今天创建交换链的ImageView。
之前已经创建了交换链的Image,Image在上层是不能直接使用的,必须通过VkImageView来使用,而在VkImageView里又指定了VkImage的使用方式。
在SceneWidget.h中添加void CreateImageViews(),一个Image对应一个ImageView,所以要创建多个Imageview,而不是一个。
在SceneWidget.cpp中,实现这个函数。生成的ImageView,要记录下来,等使用的时候,还能找到。所以也用一个ImageView的数组来做为成员变量记录每一个ImageView。
在SceneWidget.h中添加std::vector<VkImageView> m_swapchainImageViews;在CreateImageViews的实现函数,通过Image的数量来初始化这个ImageView数组。然后通过循环,创建出ImageView对象,并保存在数组中。
可以将创建单个ImageView的代码放到一个函数中,这样符合开发的逻辑。
在SceneWidget.h中添加函数:VkImageView CreateImageView(),参数需要传入要与ImageView绑定的Image、要使用的像素格式、这里要绑定颜色缓存(在Vulkan中,应该是VkImageAspectFlagesBit的枚举)、当前纹理的层级。声明完这个函数,要在CreateImageViews函数的循环中来调用这个函数,完成对ImageView的创建。
传实参时,第一个参数为:m_swapchainImages[i]。
第二个参数为:之前记录的像素格式m_swapchainImageFormat。
第三个参数:VK_IMAGE_ASPECT_COLOR_BIT,与颜色缓存绑定。
第四个参数,当前纹理的层数为1。
对于ImageView的创建,还是先写创建函数,然后填充需要的结构。先写vkCreateImageView函数,其参数:
第一个参数:VkDevice device,这里可以写之前创建好的逻辑设备:m_device。
第二个参数:const VkImageViewCreateInfo* pCreateInfo,现在没有这个指针,要在vkCreateImageView函数的上面写一个VkImageViewCreateInfo的结构体。
第三个参数:const VkAllocationCallbacks* pAllocator,这里不需要,写nullptr。
第四个参数:VkImageView* pView,生成的VkImageView的指针。这里可以在函数上面声明一个变量,记录生成的指针,然后通过函数的返回值,返回给调用者。
在函数上面补一个VkImageViewCreateInfo的结构,VkImageViewCreateInfo viewInfo{},在声明的时候初始化。
然后填充成员:
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;传入的参数。
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D。
viewinfo.format = format;传入的参数。
view.subresourceRange.aspectMask = aspectFlags;
view.subresourceRange.baseMipLevel = 0;
view.subresourceRange.levelCount = mipLevel;传入的参数。
view.subresourceRange.baseArrayLayer = 0;
view.subresourceRange.layerCount = 1;
这两个函数的代码:
然后在SceneWidget::Init函数中,调用一下。
在SceneWidget::UnInit函数中,清理一下资源。遍历数组依次清理,并补上清理image的资料代码,注意,清理的顺序与生成的顺序相反:
for (VkImageView imageView : m_swapchainImageViews)
{
vkDestroyImagView(m_device, imageView, nullptr);
}
for (VkImage image : m_swapchainImages)
{
vkDestroyImag (m_device, image, nullptr);
}
最后运行程序:
同样在命令输出窗口,没有输出任何信息。