使用描述符集

现在修改createCommandBuffers函数为每个交换链图像绑定对应的描述符集。这需要调用cmdBindDescriptorSets函数来完成,我们在调用vkCmdDrawIndexed函数之前调用这一函数:

vkCmdBindDescriptorSets(commandBuffers[i],
VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i], 0, nullptr);
vkCmdDrawIndexed(commandBuffers[i], static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);

和顶点缓冲、索引缓冲不同,描述符集并不是图形管线所独有的,所以需要我们指定我们要绑定的是图形管线还是计算管线。管线类型之后的参数是描述符所使用的布局。接着三个参数用于指定描述符集的第一个元素索引,需要绑定的描述符集个数,以及用于绑定的描述符集数组。最后两个参数用于指定动态描述符的数组偏移。在之后的章节,我们会对它们进行更为详细地讨论。

现在编译运行程序,读者会发现窗口一片漆黑,看不到我们渲染的矩形了。这是因为之前我们设置的投影矩阵将Y轴反转,导致顶点按照顺时针绘制构成背面,从而被背面剔除。我们可以修改createGraphicsPipeline函数中VkPipelineRasterizationStateCreateInfo结构体的frontFace成员变量对于正面的设置来解决这一问题:

rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;

重新编译运行程序,就可以看到下面的画面:

image

之前的矩形,现在变成了一个正方形,这是我们设置的投影矩阵的宽高比导致的。updateUniformBuffer函数在每一帧被调用,可以响应窗口大小变化,不需要在recreateSwapChain函数中对描述符进行重建。