Vulkan Tutorial 07 Window surface
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 到目前为止,我们了解到Vulkan是一个与平台特性无关联的API集合。它不能直接与窗口系统进行交互。为了将渲染结果呈现到屏幕,需要建立Vulkan与窗体系统之间的连接,我们需要使用WSI(窗体系统集成)扩展。在本小节中,我们将讨论第一个,即VK_KHR_surface。它暴露了VkSurfaceKHR,它代表surface的一个抽象类型,用以呈现渲染图像使用。我们程序中将要使用到的surface是由我们已经引入的GLFW扩展及其打开的相关窗体支持的。简单来说surface就是Vulkan与窗体系统的连接桥梁。 VK_KHR_surface扩展是一个instance级扩展,我们目前为止已经启用过它,它包含在glfwGetRequiredInstanceExtensions返回的列表中。该列表还包括将在接下来几小节中使用的一些其他WSI扩展。 需要在instance创建之后立即创建窗体surface,因为它会影响物理设备的选择。之所以在本小节将surface创建逻辑纳入讨论范围,是因为窗体surface对于渲染、呈现方式是一个比较大的课题,如果过早的在创建物理设备加入这部分内容,会混淆基本的物理设备设置工作。另外窗体surface本身对于Vulkan也是非强制的。Vulkan允许这样做,不需要同OpenGL一样必须要创建窗体surface。 Window surface creation现在开始着手创建窗体surface,在类成员debugCallback下加入成员变量surface。 VkSurfaceKHRsurface; 虽然VkSurfaceKHR对象及其用法与平台无关联,但创建过程需要依赖具体的窗体系统的细节。比如,在Windows平台中,它需要WIndows上的HWND和HMODULE句柄。因此针对特定平台提供相应的扩展,在Windows上为VK_KHR_win32_surface,它自动包含在glfwGetRequiredInstanceExtensions列表中。 我们将会演示如何使用特定平台的扩展来创建Windows上的surface桥,但是不会在教程中实际使用它。使用GLFW这样的库避免了编写没有任何意义的跨平台相关代码。GLFW实际上通过glfwCreateWindowSurface很好的处理了平台差异性。当然了,比较理想是在依赖它们帮助我们完成具体工作之前,了解一下背后的实现是有帮助的。 因为一个窗体surface是一个Vulkan对象,它需要填充VkWin32SurfaceCreateInfoKHR结构体,这里有两个比较重要的参数:hwnd和hinstance。如果熟悉windows下开发应该知道,这些是窗口和进程的句柄。 VkWin32SurfaceCreateInfoKHRcreateInfo; createInfo.sType=VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; createInfo.hwnd=glfwGetWin32Window(window); createInfo.hinstance=GetModuleHandle(nullptr); glfwGetWin32Window函数用于从GLFW窗体对象获取原始的HWND。GetModuleHandle函数返回当前进程的HINSTANCE句柄。 填充完结构体之后,可以利用vkCreateWin32SurfaceKHR创建surface桥,和之前获取创建、销毁DebugReportCallEXT一样,这里同样需要通过instance获取创建surface用到的函数。这里涉及到的参数分别为instance,surface创建的信息,自定义分配器和最终保存surface的句柄变量。 autoCreateWin32SurfaceKHR=(PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(instance,"vkCreateWin32SurfaceKHR");if(!CreateWin32SurfaceKHR||CreateWin32SurfaceKHR(instance,&createInfo,nullptr,&surface)!=VK_SUCCESS){throwstd::runtime_error("failedtocreatewindowsurface!"); } 该过程与其他平台类似,比如Linux,使用X11界面窗体系统,可以通过vkCreateXcbSurfaceKHR函数建立连接。 glfwCreateWindowSurface函数根据不同平台的差异性,在实现细节上会有所不同。我们现在将其整合到我们的程序中。从initVulkan中添加一个函数createSurface,安排在createInstnace和setupDebugCallback函数之后。 voidinitVulkan(){ createInstance(); setupDebugCallback(); createSurface(); pickPhysicalDevice(); createLogicalDevice(); }voidcreateSurface(){ } GLFW没有使用结构体,而是选择非常直接的参数传递来调用函数。 voidcreateSurface(){if(glfwCreateWindowSurface(instance,window,&surface)!=VK_SUCCESS){throwstd::runtime_error("failedtocreatewindowsurface!"); } } 参数是VkInstance,GLFW窗体的指针,自定义分配器和用于存储VkSurfaceKHR变量的指针。对于不同平台统一返回VkResult。GLFW没有提供专用的函数销毁surface,但是可以简单的通过Vulkan原始的API完成: voidcleanup(){ ... vkDestroySurfaceKHR(instance,surface,nullptr); vkDestroyInstance(instance,nullptr); ... } 最后请确保surface的清理是在instance销毁之前完成。 Querying for presentation support虽然Vulkan的实现支持窗体集成功能,但是并不意味着系统中的每一个物理设备都支持它。因此,我们需要扩展isDeviceSuitable函数,确保设备可以将图像呈现到我们创建的surface。由于presentation是一个队列的特×××,因此解决问题的方法就是找到支持presentation的队列簇,最终获取队列满足surface创建的需要。 实际情况是,支持graphics命令的的队列簇和支持presentation命令的队列簇可能不是同一个簇。因此,我们需要修改QueueFamilyIndices结构体,以支持差异化的存储。 (编辑:甘南站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- .net – 加载Azure Storage 2.0时出错 – 无法加载Microsof
- Microsoft Dynamics(Navision)vs C#.NET
- Windows下wamp php单元测试工具PHPUnit安装及生成日志文件配
- windows – 如何人为地将CPU加载到某个百分点?
- windows – 如何隐藏批量输出
- Windows Phone 7 – Windows Phone开发Visual Studio 2012
- windows-phone-8 – 启动TaskHost.exe失败,尝试运行Windows
- windows – 通过PowerShell运行.cmd文件
- 汇编 – 我的.exe程序不是我的预期
- macos – 在Windows上使用Tycho构建的Eclipse RCP应用程序的
- 飞溅屏幕 – 通用窗口10个应用程序的Splash屏幕
- PHP7安装Redis扩展教程【Linux与Windows平台】
- windows-phone-8 – 适用于Windows Phone 8的企业
- windows – 为什么没有64位版本的VS2013?
- Windows Server 2016-Win Ser 2016已删减内容
- Windows Python:为什么第一个打开的窗口未显示为
- Windows下的2017 最新版 MyEclipse启动出现:a j
- window python2.7 ImportError: No module named
- windows – 如何通过apt-cyg安装cygwin / X
- 找出占用Installer 目录空间的元凶