vulkan学习笔记十八

申请VkDescriptorSet。

继续写绘制多边形的demo。

在SceneWidget.h中添加一个bool CreateDescriptorSet()函数,在SceneWidget.cpp中实现这个函数。还需要在头文件中先声明一个成员变量,来记录生成VkDescriptorSet。

由于每一帧都会有一个VkDescriptorSet与之对应,所以申请的数量应该是和缓存中的帧数一样。即m_swapchainImages.size()。所以添加成员变量:std::vector<VkDescriptorSet> m_descriptorSets。

还是老样子,从创建函数写起,VkDescriptorSet的申请函数为:

vkAllocateDescriptorSets(),申请也同样可以判断返回值。即:

VkResult result = vkAllocateDescriptorSets()

其参数:

第一个参数:m_device。

第二个参数:需要再定义一个VkDescriptorSetAllocateInfo descriptorSetInfo = {}的变量,然后传入这个变量的引用即:&descriptorSetInfo。

第三个参数:m_descriptorSets.data()。保存申请好的VkDescriptorSet对象。记得要在使用之前进行初始化,即m_descriptorSets.resize(m_swapchainImages.size());

descriptorSetInfo属性赋值:

结构体的类型,固定写法。

descriptorSetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;

保持默认

descriptorSetInfo.pNext = nullptr;

指向已创建好的m_descriptorPool

descriptorSetInfo.descriptorPool = m_descriptorPool;

下面的两个属性,一个VkDescriptorSetLayout数组的数量,一个VkDescriptorSetLayout数组的指针。具体的赋值,需要定义一个VkDescriptorSetLayout的数组,可以这样定义:

std::vector<VkDescriptorSetLayout> descriptorSetLayouts。那么下面的属性值为:

descriptorSetInfo.descriptorSetCount = descriptorSetLayouts.size();

descriptorSetInfo.pSetLayouts = descriptorSetLayouts.data();

关于descriptorSetLayouts的赋值,在开头也提到过了,每一帧都对应一个VkDescriptorSet,也就对应一个VkDescriptorSetLayout,所以descriptorSetLayouts赋值为:

descriptorSetLayouts(m_swapchainImages.size(),m_descriptorLayout),将descriptorSetLayouts初始化为m_swapchainImages.size()个m_descriptorLayout。

下面开始给每帧绑定DescriptorSet。

要在每一帧里里更新,需要循环设置每一帧,来更新描述符。

for (size_t I = 0; I < m_swapchainImages.size(); ++I)

{

    vkUpdateDescriptorSets();

}

vkUpdateDescriptorSets();的参数:

第一个参数:m_device。

第二个参数:要更新(写入)的描述符数组的数量。这里需要定义一个VkWriteDescriptorSet类型的数组变量std::vector<VkWriteDescriptorSet> writeDescriptorSets;这个值就是writeDescriptorSets.size();

第三个参数:writeDescriptorSets.data()

第四个参数:对描述符的拷贝,这里不需要。所以设置为0.

第五个参数:设置为nullptr.

先定义一个VkWriteDescriptorSet uniformDescritorSet = {};

其属性赋值:

固定写法

uniformDescritorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;

不用扩展,设为nullptr.

uniformDescritorSet.pNext = nullptr;

之前申请的对象,与每一帧对应一个。

uniformDescritorSet.dstSet = m_descriptorSets[i];

从0开始。

uniformDescritorSet.dstBinding = 0;

数据不用特殊处理,从0开始。

uniformDescritorSet.dstArrayElemnt = 0;

使用一个,并且类型为uniformBuffer的类型。

uniformDescritorSet.descriptorCount = 1;

uniformDescritorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;

这里存放的应该是具体的数据,即:mvp。所以需要VkDescriptorBufferInfo类型的变量uniformBuffer = {};

uniformDescritorSet.pBufferInfo = &uniformBuffer;

由于类型是uniform buffer类型,所以下面的这两个赋值为nullptr .

uniformDescritorSet.pImageInfo = nullptr;

uniformDescritorSet.pTexelBufferView = nullptr;

然后将

writeDescritorSets.push_back(uniformDescritorSet);

同样还需要定义一个变量VkWriteDescriptorSet imageDescritorSet = {};

其属性赋值:

固定写法

imageDescritorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;

imageDescritorSet.pNext = nullptr;

imageDescritorSet.dstSet = m_descriptorSets[i];

imageDescritorSet.dstBinding = 1;

imageDescritorSet.dstArrayElement = 0;

imageDescritorSet.descriptorCount = 1;

imageDescritorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;

imageDescritorSet.pBufferInfo = nullptr;

补充一个变量:VkDescriptorImageInfo imageInfo = {};

imageDescritorSet.pImageInfo = &imageInfo;

imageDescritorSet.pTexelBufferView = nullptr;

再看uniformBuffer属性的赋值:

对应与之前申请好的VkBuffer:m_uniformBuffers[i]

uniformBuffer.buffer = m_uniformBuffers[i];

偏移为0.

uniformBuffer.offset = 0;

buffer的大小,为整个数据的大小。

uniformBuffer.range = sizeof(UniformData);

imageInfo的赋值属性

imageInfo.sampler = m_sampler;

imageInfo.imageView = m_colorImageView;

只从shader里读取。

imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

在SceneWidget::Init函数添加调用的代码,以及在SceneWidget::Uninit中添加清理的代码。

执行代码如下:

没有报错:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值