纹理图像视图
在之前的交换链图像和帧缓冲章节,我们已经介绍过访问图像需要通过图像视图进行。对于纹理图像同样需要通过图像视图来进行访问。
添加一个类成员变量来存储纹理图像的图像视图对象,编写createTextureImageView函数来创建纹理图像的图像视图对象:
VkImageView textureImageView;
...
void initVulkan() {
...
createTextureImage();
createTextureImageView();
createVertexBuffer();
...
}
...
void createTextureImageView() {
}
createTextureImageView函数的实现可以由createImageViews函数修改得到。两者只有两处设置不同:format和image成员变量的设置。
VkImageViewCreateInfo viewInfo = {};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = textureImage;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
在这里,由于VK_COMPONENT_SWIZZLE_IDENTITY的值实际上是0,所以我们可以省略对viewInfo.components的显式初始化,将viewInfo.components的成员变量都设置为0。最后,调用vkCreateImageView函数创建图像视图对象:
if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture image view!");
}
我们可以编写一个createImageView函数来简化图像视图对象的创建:
VkImageView createImageView(VkImage image, VkFormat format) {
VkImageViewCreateInfo viewInfo = {};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = format;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
VkImageView imageView;
if (vkCreateImageView(device, &viewInfo, nullptr, &imageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture image view!");
}
return imageView;
}
现在我们可以使用createImageView函数来简化createTextureImageView的函数实现:
void createTextureImageView() {
textureImageView = createImageView(textureImage, VK_FORMAT_R8G8B8A8_UNORM);
}
createImageViews的函数实现可以被简化为:
void createImageViews() {
swapChainImageViews.resize(swapChainImages.size());
for (uint32_t i = 0; i < swapChainImages.size(); i++) {
swapChainImageViews[i] = createImageView(swapChainImages[i],
swapChainImageFormat);
}
}
应用程序结束前,我们需要在清除图像对象之前清除与之关联的图像视图对象:
void cleanup() {
cleanupSwapChain();
vkDestroyImageView(device, textureImageView, nullptr);
vkDestroyImage(device, textureImage, nullptr);
vkFreeMemory(device, textureImageMemory, nullptr);