SDLWidget.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #ifndef VKW_SDL_VULKAN_WIDGET3_H
  2. #define VKW_SDL_VULKAN_WIDGET3_H
  3. #include "VKWVulkanWindow.h"
  4. #include "Adapters/SDLVulkanWindowAdapter.h"
  5. #include "VulkanApplication.h"
  6. #include "Frame.h"
  7. #include <iostream>
  8. #include <thread>
  9. namespace vkw {
  10. /**
  11. * @brief The SDLVulkanWidget struct
  12. *
  13. * The SDLVulkanWidget use an SDL_Window to provide
  14. * a drawing surface. This mimics the QtVulkanWidget
  15. * so that they can be used interchangeably without
  16. * much modification.
  17. */
  18. class SDLVulkanWidget : public VKWVulkanWindow
  19. {
  20. public:
  21. struct CreateInfo
  22. {
  23. std::string windowTitle;
  24. uint32_t width;
  25. uint32_t height;
  26. InstanceInitilizationInfo2 instanceInfo;
  27. DeviceInitilizationInfo2 deviceInfo;
  28. SurfaceInitilizationInfo2 surfaceInfo;
  29. };
  30. ~SDLVulkanWidget()
  31. {
  32. }
  33. CreateInfo m_createInfo;
  34. void create(CreateInfo const &C)
  35. {
  36. m_createInfo = C;
  37. SDLVulkanWindowAdapter * m_adapter = new SDLVulkanWindowAdapter();
  38. m_adapter->createWindow( m_createInfo.windowTitle.c_str(),
  39. SDL_WINDOWPOS_CENTERED,
  40. SDL_WINDOWPOS_CENTERED,
  41. static_cast<int>(m_createInfo.width),
  42. static_cast<int>(m_createInfo.height));
  43. setWindowAdapater(m_adapter);
  44. createVulkanInstance(m_createInfo.instanceInfo);
  45. createVulkanSurface(m_createInfo.surfaceInfo);
  46. createVulkanDevice(m_createInfo.deviceInfo);
  47. }
  48. void finalize(Application * app)
  49. {
  50. app->releaseSwapChainResources();
  51. app->releaseResources();
  52. }
  53. template<typename callable_t>
  54. void poll( Application * app, callable_t && c)
  55. {
  56. SDL_Event event;
  57. while (SDL_PollEvent(&event))
  58. {
  59. c(event);
  60. app->nativeWindowEvent(&event);
  61. }
  62. }
  63. void render( Application * app)
  64. {
  65. auto fr = acquireNextFrame();
  66. fr.beginCommandBuffer();
  67. app->m_renderNextFrame = false;
  68. app->render(fr);
  69. fr.endCommandBuffer();
  70. frameReady(fr);
  71. }
  72. void _initSwapchainVars(Application * app)
  73. {
  74. app->m_swapChainSize = getSwapchainExtent();
  75. app->m_swapChainFormat = getSwapchainFormat();
  76. app->m_swapChainDepthFormat= getDepthFormat();
  77. app->m_concurrentFrameCount= static_cast<uint32_t>(m_swapchainFrameBuffers.size());
  78. app->m_defaultRenderPass = m_renderPass;
  79. app->m_swapchainImageViews = m_swapchainImageViews;
  80. app->m_swapchainImages = m_swapchainImages;
  81. app->m_currentSwapchainIndex=0;
  82. }
  83. template<typename SDL_EVENT_CALLABLE>
  84. int exec(Application * app, SDL_EVENT_CALLABLE && callable)
  85. {
  86. return exec(app, callable, [](){});
  87. }
  88. /**
  89. * @brief exec
  90. * @return
  91. *
  92. * Similar to Qt's app.exec(). this will
  93. * loop until the the windows is closed
  94. */
  95. template<typename SDL_EVENT_CALLABLE, typename SDL_MAIN_LOOP_CALLABLE>
  96. int exec(Application * app, SDL_EVENT_CALLABLE && callable, SDL_MAIN_LOOP_CALLABLE && mainLoop)
  97. {
  98. app->m_device = getDevice();
  99. app->m_physicalDevice = getPhysicalDevice();
  100. app->m_instance = getInstance();
  101. app->m_graphicsQueue = getGraphicsQueue();
  102. app->m_presentQueue = getPresentQueue();
  103. app->m_graphicsQueueIndex = getGraphicsQueueIndex();
  104. app->m_presentQueueIndex = getPresentQueueIndex();
  105. _initSwapchainVars(app);
  106. app->initResources();
  107. app->initSwapChainResources();
  108. while( true )
  109. {
  110. bool resize=false;
  111. poll(app, [&resize,&callable](SDL_Event const &E)
  112. {
  113. if (E.type == SDL_WINDOWEVENT && E.window.event == SDL_WINDOWEVENT_RESIZED
  114. /*&& event.window.windowID == SDL_GetWindowID( window->getSDLWindow()) */ )
  115. {
  116. resize=true;
  117. }
  118. callable(E);
  119. });
  120. if( app->shouldQuit() )
  121. {
  122. break;
  123. }
  124. if(resize)
  125. {
  126. app->releaseSwapChainResources();
  127. rebuildSwapchain();
  128. _initSwapchainVars(app);
  129. app->initSwapChainResources();
  130. }
  131. mainLoop();
  132. if( app->shouldRender() )
  133. {
  134. render(app);
  135. }
  136. }
  137. app->releaseSwapChainResources();
  138. app->releaseResources();
  139. destroy();
  140. return 0;
  141. }
  142. /**
  143. * @brief frameReady
  144. *
  145. * Call this function to present the frame.
  146. */
  147. void frameReady(Frame & fr)
  148. {
  149. submitFrame(fr);
  150. presentFrame(fr);
  151. waitForPresent();
  152. }
  153. };
  154. }
  155. #endif