创建交换链
译者注:示例代码点击此处
交换链用于在屏幕上显示图像。他是一组图像,可以由应用程序获取,然后在我们的应用程序窗口中显示。每个图像都具有相同的已定义属性集。当我们准备好所有这些参数时,意味着我们为交换链图像选择了数量,大小,格式和使用场景,并且还获取并选择了一种可用的呈现模式,我们就可以创建交换链了。
怎么做...
1.获取已创建的逻辑设备对象的句柄。将其储存在名为logical_device的VkDevice类型的变量中。
2.将创建的呈现表面的句柄分配给名为presentation_surface的VkSurfaceKHR类型变量。
3.将所需数量的交换链图像分配给名为image_count的uint32_t类型。
4.将所选图像格式和颜色空间的值储存在名为surface_format的VkSurfaceFormatKHR类型的变脸中。
5.准备所需的图像大小,并将其分配给名为image_size的VkExtent2D类型的变量。
6.为交换链图像选择所需的使用方案。将它们储存在名为image_usage的VkImageUsageFlags类型的位字段变量中。
7.选择储存在名为surface_transform的VkSurfaceTransformFlagBitsKHR类型变量中的选定曲面变换。
8.准备名为present_mode的VkPresentModeKHR类型变量,并为其分配所选的呈现模式。
9.创建名为old_swapchain的VkSwapchainKHR类型变量。如果先前创建了交换链,则在此变量中储存该交换链句柄,否则为VK_NULL_HANDLE值。
10.创建一个名为swapchain_create_info的VkSwapchainCreateInfoKHR类型变量。将一下值分配给此变量的成员:
·sType为VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
·pNext为nullptr
·flags为0
·surface为presentation_surface
·minImageCount为image_count
·imageFormat为surface_format.format
·imageColorSpace为surface_format.colorSpace
·imageExtent为image_size
·imageArrayLayers为1(如果我们想执行分层、立体渲染,则为跟多)
·imageUsage为image_usage
·imageSharingMode为VK_SHARING_MODE_EXCLUSIV
·queueFamilyIndexCount为0
·pQueueFamilyIndices为nullptr
·preTransform为surface_transform
·compositeAlpha为VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
·presentMode为present_mode
·clipped为VK_TRUE
·oldSwapchain为old_swapchain
11.创建一个名为swapchain的VkSwapchainKHR类型变量。
12.调用vkCreateSwapchainKHR( logical_device, &swapchain_create_info, nullptr, &swapchain) 。使用创建的逻辑设备句柄,swapchain_create_info变量的指针,nullptr,指向swapchain变量的指针作为函数的参数。
13.通过将返回值与VK_SUCCESS值进行比较,确保调用成功。
14.调用kDestroySwapchainKHR( logical_device, old_swapchain, nullptr )来销毁旧交换链。为其提供逻辑设备句柄,旧交换链句柄和nullptr。
这个怎么运作...
如前所述,交换链是图像的集合。它们与交换链一起自动创建。当交换链被销毁时,它们也会被销毁。虽然应用程序可以获取这些图像的句柄,但不准许创建和销毁它们。
交换链创建过程并不复杂,但我们创建交换链之前需要准备大量数据:
VkSwapchainCreateInfoKHR swapchain_create_info = {
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
nullptr,
0,
presentation_surface,
image_count, surface_format.format,
surface_format.colorSpace,
image_size,
1,
image_usage,
VK_SHARING_MODE_EXCLUSIVE,
0,
nullptr,
surface_transform,
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
present_mode,
VK_TRUE,
old_swapchain
};
VkResult result = vkCreateSwapchainKHR( logical_device, &swapchain_create_info, nullptr, &swapchain );
if( (VK_SUCCESS != result) || (VK_NULL_HANDLE == swapchain) ) {
std::cout << "Could not create a swapchain." << std::endl;
return false;
}
只有一个交换链可以与给定应用程序窗口关联。当我们创建一个新的交换链时,需要销毁之前为同一窗口创建的交换链:
if( VK_NULL_HANDLE != old_swapchain ) {
vkDestroySwapchainKHR( logical_device, old_swapchain, nullptr );
old_swapchain = VK_NULL_HANDLE;
}
当交换链贮备就绪时,我们可以获取其图像并执行适合指定使用场景的任务。不仅限于获取单个图像,就像我们习惯使用Opengl API(单个后台缓冲区)一样。图像的数量取决于与交换链一起创建图像的最小指定数量以及所选择的呈现模式和当前渲染历史(当前获取和最近呈现的图像数量)。
获取图像后,我们可以在应用程序中使用它。最常见的用法是渲染到图像中(将其用作颜色附件),但不仅限于此用法,还可以使用交换链图像执行其他任务。但是必须确保在给定平台上可以使用各自的用法,并且在交换链创建期间指定它们。并非所有平台都支持所有用法,只有颜色附件是一定支持的。
当我们完成渲染图像或执行其他任务时,我们可以通过呈现它来显示图像。此操作将图像返回到呈现引擎,该引擎根据指定的呈现模式用新的图像替换当前显示的图像。