QVulkanWindowRenderer Class
QVulkanWindowRenderer 类用于实现QVulkanWindow 的特定于应用程序的渲染逻辑。更多内容...
| 头文件: | #include <QVulkanWindowRenderer> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Gui) target_link_libraries(mytarget PRIVATE Qt6::Gui) |
| qmake: | QT += gui |
公共函数
| virtual | ~QVulkanWindowRenderer() |
| virtual void | initResources() |
| virtual void | initSwapChainResources() |
| virtual void | logicalDeviceLost() |
| virtual void | physicalDeviceLost() |
| virtual void | preInitResources() |
| virtual void | releaseResources() |
| virtual void | releaseSwapChainResources() |
| virtual void | startNextFrame() = 0 |
详细说明
应用程序通常会同时继承QVulkanWindow 和QVulkanWindowRenderer的子类。前者用于处理事件(例如输入),而后者用于实现构成应用程序渲染过程的Vulkan资源管理和命令缓冲区构建。
除了事件处理外,QVulkanWindow 的子类还负责为QVulkanWindow::createRenderer()提供实现。此处正是窗口与渲染器建立连接的地方。典型的实现方式只是创建一个QVulkanWindowRenderer子类的全新实例。
成员函数文档
[virtual noexcept] QVulkanWindowRenderer::~QVulkanWindowRenderer()
虚拟析构函数。
[virtual] void QVulkanWindowRenderer::initResources()
当需要创建渲染器的图形资源时,会调用此虚拟函数。
根据QVulkanWindow::PersistentResources 标志、设备丢失等情况,在QVulkanWindow 的生命周期内,此函数可能会被调用多次。但是,后续的调用之前总会先调用releaseResources()。
诸如 device()、graphicsQueue() 和 graphicsCommandPool() 等访问器,仅保证在此函数内部及之后(直至调用releaseResources() 之前)返回有效值。
默认实现为空。
[virtual] void QVulkanWindowRenderer::initSwapChainResources()
当可以执行与交换链、帧缓冲区或渲染通道相关的初始化操作时,会调用此虚拟函数。在响应窗口调整大小事件时,交换链及相关资源会被重置并重新创建,因此两次对 `initResources()` 和 `releaseResources()` 的调用之间,可能会夹杂多次对 `initSwapChainResources()` 和 `releaseSwapChainResources()` 的调用。
像QVulkanWindow::swapChainImageSize() 这样的访问器,仅保证在此函数内部及之后(直至调用releaseSwapChainResources() 之前)返回有效值。
由于该函数实际上会在每次调整大小时被调用,因此这也是进行与大小相关的计算(例如投影矩阵)的地方。
默认实现为空。
[virtual] void QVulkanWindowRenderer::logicalDeviceLost()
当逻辑设备(VkDevice)丢失时,会调用此虚拟函数,这意味着VK_ERROR_DEVICE_LOST 的某些操作失败了。
默认实现为空。
通常无需在此函数中执行任何特殊操作。QVulkanWindow 会自动释放所有资源(必要时调用releaseSwapChainResources()和releaseResources()),并尝试重新初始化以获取一个新设备。当物理设备也丢失时,此重新初始化尝试可能会导致physicalDeviceLost()。
另请参阅 physicalDeviceLost()。
[virtual] void QVulkanWindowRenderer::physicalDeviceLost()
当物理设备丢失时,会调用此虚拟函数,这意味着逻辑设备的创建失败,并返回错误代码VK_ERROR_DEVICE_LOST 。
默认实现为空。
通常无需在此函数中执行任何特殊操作,因为QVulkanWindow 会在一段时间后自动重试初始化。
另请参阅 logicalDeviceLost()。
[virtual] void QVulkanWindowRenderer::preInitResources()
该虚拟函数在图形初始化开始之前被调用,此时initResources() 即将被调用。
通常无需重写此函数。但在某些情况下,需要根据物理设备和绘制表面共同做出决策。由于在此阶段无法获取 Vulkan 绘制表面,因此这些操作通常无法在使 `QVulkanWindow ` 可见之前完成。
因此,应用程序可以重写此函数。此时,QVulkanWindow::physicalDevice() 和QVulkanInstance::surfaceForWindow() 均可正常工作,但尚未进行进一步的逻辑设备初始化。
默认实现为空。
[virtual] void QVulkanWindowRenderer::releaseResources()
当必须释放渲染器的图形资源时,会调用此虚拟函数。
实现时必须做好准备,以应对调用此函数后,稍后可能还会调用initResources()的情况。
QVulkanWindow 负责在调用此函数之前和之后等待设备进入空闲状态。
默认实现为空。
[virtual] void QVulkanWindowRenderer::releaseSwapChainResources()
当必须释放与交换链、帧缓冲区或渲染通道相关的资源时,会调用此虚拟函数。
实现必须做好准备,以应对调用此函数后,稍后可能再次调用initSwapChainResources()的情况。
QVulkanWindow 负责在调用此函数之前和之后等待设备处于空闲状态。
默认实现为空。
注意:这是在 `QVulkanWindow ` 开始释放所有图形资源之前,能够完整操作这些资源的最后一个位置。因此,对于采用异步、可能为多线程的 `startNextFrame()` 的实现而言,如果存在待处理的帧提交,则必须在此函数返回之前执行阻塞等待并调用 `QVulkanWindow::frameReady()`。
[pure virtual] void QVulkanWindowRenderer::startNextFrame()
当需要将下一帧的绘制调用添加到命令缓冲区时,会调用此虚拟函数。
每次调用此函数后,必须紧接着调用QVulkanWindow::frameReady()。若未执行此操作,将导致渲染循环停滞。该调用也可在稍后时间进行,即在本函数返回之后。这意味着可以启动异步任务,并在任务完成后再更新命令缓冲区并通知QVulkanWindow 。
调用此函数时,所有 Vulkan 资源均已初始化并准备就绪。可通过QVulkanWindow::currentFramebuffer() 和QVulkanWindow::currentCommandBuffer() 获取当前帧缓冲区和主命令缓冲区。可通过QVulkanWindow::device() 和QVulkanWindow::graphicsQueue() 获取逻辑设备和活动图形队列。实现可以从QVulkanWindow::graphicsCommandPool() 返回的池中创建额外的命令缓冲区。 为方便起见,主机可见内存和设备本地内存类型的索引分别通过QVulkanWindow::hostVisibleMemoryIndex() 和QVulkanWindow::deviceLocalMemoryIndex() 提供。所有这些访问器均可安全地从任何线程调用。
另请参阅 QVulkanWindow::frameReady() 和QVulkanWindow 。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.