vulkan学习笔记十一

根据多重采样值,设置颜色和深度的多重采样。

在SceneWidget.h中添加两个函数:

void CreateColorResources();

void CreateDepthResources();

分别处理颜色和深度的多重采样,然后在SceneWidget.cpp中实现这两个函数。

先在CreateColorResources函数中,需要生成相应的VkImage再生成相应的VkImageView,由于颜色和深度,都需要生成这些,所以可以将生成VkImage和VkImageView的操作,写成一个函数。先写生成Image的函数,再写生成ImageView的函数。

生成VkImage时,需要用到Image的宽、高、纹理的层级、平铺方式、内存布局等信息,才能生成VkImage。

void CreateImage(uint32_t width, uint32_t height, uint32_t mipLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory);

VkImageView的生成可以使用现有的CreateImageView的函数即可。

所以需要在SceneWidget.h中添加函数声明,并且添加成员变:

VkImage m_colorImgae = VK_NULL_HANDLE;和 VkImageView m_colorImageView = VK_NULL_HANDLE;

VkImage m_depthImage = VK_NULL_HANDLE;和VkImageView m_depthImageView = VK_NULL_HANDLE;

先实现CreateImage函数,要生成一个VkImage对象,可以调用vkCreateImage函数。同样,返回一个VkResult的值,并判断这个值是否有效。

VkResult result = vkCreateImage();其参数:

第一个参数:m_device,基本上在逻辑设备上生成的都是这个值。

第二个参数:是生成VkImage所需要的信息,所以在这个函数上面添加一个VkImageCreateInfo imageCreateInfo = {};在这里传入&imageCreateInfo。

第三个参数:记录申请的地址,这里不需要,传入nullptr。

第四个参数:传出生成的VkImage对象,所以传入入参image的引用。

imageCreateInfo的属性赋值如下:

这个数据结构的类型。

imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;

这里的image类型为2维的,除特殊指定外,一般都是2维。

imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;

图像的宽和高,一般与视口大小一致。

imageCreateInfo.extent.width = width;

imageCreateInfo.extent.height = height;

深度一般默认为1。

imageCreateInfo.extent.depth = 1;

mipmap的层级。

imageCreateInfo.mipLevels = mipLevels;

图像的层级,有的图像会有多个层级。

imageCreateInfo.arrayLayers = 1;

图像的像素格式。

imageCreateInfo.format = format;

图像的平铺方式。

imageCreateInfo.tiling = tiling;

布局

imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

使用方式。

imageCreateInfo.usage = usage;

采样数

imageCreateInfo.samples = numSamples;

缓冲在设备的多缓冲队列中的共享方式。

imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

其它的字段保持默认。

写到这个地方,本来以为这个函数算是写完了,但是看教程时,发现创建完VkImage后,还有操作。

获取图像对象的内存需求:vkGetImageMemoryRequirements(),其参数:

第一个参数:m_device。

第二个参数:image生成的VkImage对象。

第三个参数:VkMemoryRequirements结构指针,返回图像对象对内存的要求。

补充一个数据结构:

VkMemoryRequirements memoryRequirements = {};传入:&memoryRequirements。由于是传出参数,所以不需要对这个结构的属性赋值

申请内存,通过vkAllocateMemory函数,申请内存,并验证返回值是否为VK_SUCCESS。其参数:

第一个参数:m_device。

第二个参数:需要定义一个VkMemoryAllocateInfo memoryAllocateInfo = {}。传入&memoryAllocateInfo。

第三个参数:nullptr。

第四个参数:&imageMemory,函数的调用者传入的参数。申请的内存就放在imageMemory里。

给memoryAllocateInfo结构的成员赋值:

memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;

memoryAllocateInfo.pNext = nullptr;

memoryAllocateInfo.allocationSize = memRequirements.size;

memoryAllocateInfo.memoryTypeIndex;这个值需要查询一下:

可以通过vkGetPhysicalDeviceMemoryProperties函数,查询一下输入参数:

第一个参数:物理设备,m_physicalDevice,之前查询到的。

第二个参数:是VkPhysicalDeviceMemoryProperties的类型的数据结构memProperties输入引用。

然后通过遍历memProperties,找出包含输入的properties的特性的索引。

最后,调用vkBindImageMemory将分配的内存与VkImage对象绑定在一起。参数:

第一个参数:m_device。

第二个参数:要绑的image对象。

第三个参数:imageMemory。

第四个参数:内存的偏移,这里不用偏移,所以为0。

这里可以看出imageMemory是申请出来的,最后也是要清理的,所以在这里需要再添加成员变量,由于是color和depth两个都各有一个,所以一共要再添加两个成员变量VkDeviceMemory  m_colorMemory和VkDeviceMemory m_depthMemory。

在CreateColorResources函数中调用CreateImage函数,其参数依次为:apabilities.currentExtent的宽高、层级为1、采样使用msaa、像素格式为m_swapchainImageFormat、使用平铺最佳的方式、使用动态绑定且绑定颜色附件方式、使用显存、要生成的image对象和momory对象。

在CreateDepthResources函数中,与CreateColorResources一样,只是CreateImage的参数略区别:

apabilities.currentExtent的宽高、层级为1、采样使用msaa、像素格式为VK_FORMAT_D32_SFLOAT、使用平铺最佳的方式、使用深度模板附件方式、使用显存、要生成的image对象和momory对象。

在生成完Image后,还要生成一下对应的imageView。

在最后,清理资源,先清理color的mmemory,再清理colorImage,最后清理colorImageView。depth也是这个清理顺序。

运行一下程序:

后台的输出,没有输出报错信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值