QtVulkanWidget.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #ifndef VKW_QT_VULKAN_WIDGET_H
  2. #define VKW_QT_VULKAN_WIDGET_H
  3. #include <QVulkanWindow>
  4. #include <QWidget>
  5. #include <QKeyEvent>
  6. #include <QMouseEvent>
  7. #include <QTimer>
  8. #include <iostream>
  9. #include "VulkanApplication.h"
  10. #include "base_widget.h"
  11. namespace vkw {
  12. /**
  13. * @brief The QTRenderer struct
  14. *
  15. * This is how Qt would like to use
  16. * Vulkan within their windowing system
  17. */
  18. class QTRenderer : public QVulkanWindowRenderer
  19. {
  20. public:
  21. QTRenderer(QVulkanWindow * w, bool msaa) : m_window(w)
  22. {
  23. msaa= false;
  24. if (msaa) {
  25. const QVector<int> counts = w->supportedSampleCounts();
  26. qDebug() << "Supported sample counts:" << counts;
  27. for (int s = 16; s >= 4; s /= 2) {
  28. if (counts.contains(s)) {
  29. qDebug("Requesting sample count %d", s);
  30. m_window->setSampleCount(s);
  31. break;
  32. }
  33. }
  34. }
  35. }
  36. ~QTRenderer()
  37. {
  38. }
  39. /**
  40. * @brief startNextFrame
  41. *
  42. * Override the QVulkanWindowRenderer::startNextFrame to call the
  43. * render() method instead.
  44. */
  45. virtual void startNextFrame() override
  46. {
  47. auto i = m_window->currentSwapChainImageIndex();
  48. Frame _frame;
  49. m_application->m_currentSwapchainIndex = static_cast<uint32_t>(m_window->currentSwapChainImageIndex() );
  50. QSize sz = m_window->swapChainImageSize();
  51. _frame.renderPass = m_application->m_defaultRenderPass;
  52. _frame.swapchainSize.width = static_cast<uint32_t>(sz.width() );
  53. _frame.swapchainSize.height = static_cast<uint32_t>(sz.height());
  54. _frame.swapchainIndex = static_cast<uint32_t>(m_window->currentSwapChainImageIndex() );
  55. _frame.swapchainFormat = m_window->colorFormat();
  56. _frame.swapchainImage = m_window->swapChainImage(i);
  57. _frame.swapchainImageView = m_window->swapChainImageView(i);
  58. _frame.depthImage = m_window->depthStencilImage();
  59. _frame.depthImageView = m_window->depthStencilImageView();
  60. _frame.depthFormat = m_window->depthStencilFormat();
  61. _frame.framebuffer = m_window->currentFramebuffer();
  62. _frame.commandPool = m_window->graphicsCommandPool();
  63. _frame.commandBuffer = m_window->currentCommandBuffer();
  64. _frame.clearColor.float32[0] = 1.0f;
  65. _frame.clearColor.float32[1] = 1.0f;
  66. _frame.clearColor.float32[2] = 1.0f;
  67. _frame.clearColor.float32[3] = 1.0f;
  68. _frame.clearDepth.depth = 1.0f;
  69. _frame.clearDepth.stencil = 0;
  70. m_application->m_renderNextFrame = false;
  71. m_application->render(_frame);
  72. m_window->frameReady();
  73. if( m_application->shouldRender())
  74. {
  75. m_window->requestUpdate();
  76. }
  77. }
  78. void initResources() override
  79. {
  80. m_application->m_concurrentFrameCount = static_cast<uint32_t>( m_window->concurrentFrameCount() );
  81. m_application->m_defaultRenderPass = m_window->defaultRenderPass();
  82. m_application->m_device = m_window->device();
  83. m_application->m_physicalDevice = m_window->physicalDevice();
  84. m_application->m_instance = m_window->vulkanInstance()->vkInstance();
  85. m_application->m_graphicsQueue = m_window->graphicsQueue();
  86. m_application->m_graphicsQueueIndex = static_cast<int32_t>(m_window->graphicsQueueFamilyIndex());
  87. //m_application->m_presentQueue = m_window->presentQ();
  88. //m_application->m_presentQueueIndex = getPresentQueueIndex();
  89. m_application->initResources();
  90. }
  91. void initSwapChainResources() override
  92. {
  93. auto s = m_window->swapChainImageSize();
  94. m_application->m_concurrentFrameCount = static_cast<uint32_t>( m_window->concurrentFrameCount() );
  95. m_application->m_swapChainSize = VkExtent2D{ static_cast<uint32_t>(s.width()), static_cast<uint32_t>(s.height()) };
  96. m_application->m_swapChainFormat = m_window->colorFormat();
  97. m_application->m_swapChainDepthFormat = m_window->depthStencilFormat();
  98. m_application->m_swapchainImages.clear();
  99. m_application->m_swapchainImageViews.clear();
  100. for(int i=0;i<m_window->swapChainImageCount();i++)
  101. {
  102. m_application->m_swapchainImages.push_back( m_window->swapChainImage(i));
  103. m_application->m_swapchainImageViews.push_back( m_window->swapChainImageView(i));
  104. }
  105. m_application->initSwapChainResources();
  106. }
  107. void releaseSwapChainResources() override
  108. {
  109. m_application->releaseSwapChainResources();
  110. }
  111. void releaseResources() override
  112. {
  113. m_application->releaseResources();
  114. }
  115. protected:
  116. QVulkanWindow *m_window;
  117. vkw::Application *m_application = nullptr;
  118. bool m_SystemCreated=false;
  119. friend class QtVulkanWidget;
  120. };
  121. /**
  122. * @brief The VulkanWidget class
  123. *
  124. * This simple class just needs to override the createRenderer() method
  125. * and return the the TriangleRenderer*
  126. *
  127. * If you do not want to use the VKA event methods, You can
  128. * make a copy of this class and replace the qt events
  129. *
  130. *
  131. */
  132. class QtVulkanWidget : public QVulkanWindow,
  133. public BaseWidget
  134. {
  135. // Q_OBJECT
  136. public:
  137. void init(Application * app)
  138. {
  139. this->setFlags( QVulkanWindow::PersistentResources);
  140. m_application = app;
  141. }
  142. //=========================================================
  143. // These two functions are needed to interact with
  144. // Qt.
  145. //=========================================================
  146. QVulkanWindowRenderer* createRenderer() override
  147. {
  148. auto * t = new QTRenderer(this, true);
  149. assert(m_application != nullptr);
  150. t->m_application = m_application;
  151. return t;
  152. }
  153. //=========================================================
  154. Application* getApplication()
  155. {
  156. return m_application;
  157. }
  158. protected:
  159. Application * m_application = nullptr;
  160. };
  161. }
  162. #endif