Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
VulkanRenderer.hpp
Go to the documentation of this file.
1 #pragma once
3 #ifdef USING_VULKAN
12 
17 
22 
23 #include "Engine/Utility/Light.hpp"
24 
25 // Written by Koen Buitenhuis
26 
27 #define GLM_FORCE_RADIANS
28 #define GLM_FORCE_DEPTH_ZERO_TO_ONE
29 
30 #include <ThirdParty/glm/glm/glm.hpp>
31 #include <ThirdParty/glm/glm/gtc/matrix_transform.hpp>
32 #include <iostream>
33 #include <future>
34 #include <thread>
35 #include <ThirdParty/EASTL-master/include/EASTL/string.h>
36 #include <ThirdParty/EASTL-master/include/EASTL/array.h>
37 #include <ThirdParty/EASTL-master/include/EASTL/vector.h>
38 #include <ThirdParty/EASTL-master/include/EASTL/memory.h>
39 #include <ThirdParty/EASTL-master/include/EASTL/chrono.h>
40 
41 
42 namespace Engine
43 {
44 
45 #ifdef NDEBUG
46  const bool enableValidationLayers = false;
47 #else
48  const bool enableValidationLayers = true;
49 #endif
50 
54  class ENGINE_API VulkanRenderer : public Renderer {
55  private:
56 
57  friend VulkanPipeline;
58  friend class Engine;
59 
60  VulkanRenderer() noexcept;
61  VulkanRenderer(VulkanRenderer const &other) = default;
62  VulkanRenderer(VulkanRenderer &&other) noexcept = default;
63  public:
64  ~VulkanRenderer();
65  private:
66 
67  public:
72  void InitializeRenderer();
73 
79  void InitializeRenderer(eastl::weak_ptr<VulkanWindow> window);
80 
84  void Resized();
85 
90  void setClearColor(glm::vec4 color);
91 
96  VkRenderPass GetRenderPass() const;
97 
102  VkRenderPass GetGBufferRenderPass() const;
103 
108  VmaAllocator GetVmaAllocator() const;
109 
115  VkCommandPool GetGraphicsCommandPool() const;
116 
122  VkCommandPool GetComputeCommandPool() const;
123 
128  VkExtent2D GetSwapChainExtent() const;
129 
130  //Should probably add the Shader reference for vertex and fragment to this, so they can be sent to the GPU
131  //Possibly also want to add an Entity reference, so you could send it's data (mesh and texture) to the GPU as well.
132  //At least that's how it worked in OpenGL
137  virtual void RendererBegin();
143  virtual void RendererBegin(const glm::mat4x4& view, const glm::mat4x4& projection);
144 
145  //Used to render the selected Shader & Entity combination defined in RendererBegin()
149  virtual void Render();
150 
157  virtual void Render(const glm::mat4x4& modelMatrix, eastl::shared_ptr<Model> model, const glm::vec4& mainColor = glm::vec4(1.f, 1.f, 1.f, 1.f));
158 
164  virtual void RenderSprite(eastl::weak_ptr<Texture> texture, glm::mat4 modelMatrix);
165 
172  virtual void RenderLine(glm::vec3 start, glm::vec3 end, glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, 1.f));
173 
174  //Used to unbind the current selected Shader & Entity combination defined in RendererBegin()
179  virtual void RendererEnd();
180 
189  void StartSecondaryCommandBufferRecording(VkCommandBuffer buffer, VkCommandBufferUsageFlags flags, VkRenderPass renderPass, uint32_t subPass, VkFramebuffer framebuffer) const;
190 
195  void EndSecondaryCommandBufferRecording(VkCommandBuffer buffer) const;
196 
201  enum class GBufferSubPasses {
202  G_BUFFER_PASS = 0,
203  SUBPASS_COUNT
204  };
205 
210  enum class SsaoSubPasses {
211  SSAO_PASS = 0,
212  SUBPASS_COUNT
213  };
214 
219  enum class RenderSubPasses {
220  SSAO_BLUR_PASS = 0,
221  RENDER_PASS,
222  IMGUI_PASS,
223  COMPOSITE_PASS,
224  SUBPASS_COUNT
225  };
226 
242  void CreateLight(eastl::string name, LightType lightType,
243  glm::vec3 position, glm::vec3 direction, glm::vec3 color,
244  float radius, float attunuation, float coneInnerAngle, float coneOuterAngle);
245 
251  void SetLightType(eastl::string name, LightType lightType);
252 
258  LightType GetLightType(eastl::string name);
259 
265  void SetLightPosition(eastl::string name, glm::vec3 position);
266 
272  glm::vec3 GetLightPosition(eastl::string name);
273 
279  void SetLightDirection(eastl::string name, glm::vec3 direction);
280 
286  glm::vec3 GetLightDirection(eastl::string name);
287 
293  void SetLightColor(eastl::string name, glm::vec3 color);
294 
300  glm::vec3 GetLightColor(eastl::string name);
301 
307  void SetLightRadius(eastl::string name, float radius);
308 
314  float GetLightRadius(eastl::string name);
315 
321  void SetLightConeInnerAngle(eastl::string name, float angle);
322 
328  float GetLightConeInnerAngle(eastl::string name);
329 
335  void SetLightConeOuterAngle(eastl::string name, float angle);
336 
342  float GetLightConeOuterAngle(eastl::string name);
343 
348  VkDescriptorSetLayout CreateLightDescriptorSetLayout();
349 
357  VkDescriptorSet CreateLightDescriptorSet(size_t threadID, size_t pipelineID, size_t set, VkDescriptorSetLayout layout);
358 
366  VkDescriptorSet GetLightDescriptorSet(size_t threadID, size_t pipelineID, size_t set);
367 
372  VkFramebuffer GetFrameBuffer();
373 
380  VulkanDescriptorPool* GetDescriptorPool(size_t thread);
381 
387  size_t GetThreadCount();
388 
389  protected:
390  void CreateInstance();
391  void FindPhysicalDevice();
392  void CreateLogicalDevice();
393  void CreateSwapChain();
394  void GetSwapChainImages();
395  void CreateSwapChainImageViews();
396  void CreateGraphicsCommandPool();
397  void CreateComputeCommandPool();
398  void CreateVmaAllocator();
399  void CreateDepthImage();
400  void CreateAttachmentImages();
401  void CreateRenderPass();
402  void CreateFramebuffers();
403  void GenerateCommandBuffers();
404  void CreateDescriptorPool();
405  void InitImGui();
406  void CreateSemaphores();
407  void CreateCompositingPipeline();
408  void CreateGBufferRenderPipeline();
409  void CreateSsaoPipelines();
410  void CreateRenderers();
411  void AllocateThreads();
412 
413  void RecreateSwapChain();
414 
415  void DestroyInstance();
416  void DestroyLogicalDevice();
417  void DestroySwapChain();
418  void DestroySwapChainImageViews();
419  void DestroyGraphicsCommandPool();
420  void DestroyComputeCommandPool();
421  void DestroyVmaAllocator();
422  void DestroyDepthImage();
423  void DestroyAttachmentImages();
424  void DestroyRenderPass();
425  void DestroyFramebuffers();
426  void DestroyDecriptorPool();
427  void DestroyImGui() const;
428  void DestroySemaphores();
429  void DestroyCompositingPipeline();
430  void DestroyGBufferRenderPipeline();
431  void DestroySsaoPipelines();
432  void DestroyRenderers();
433  void DestroyThreads();
434 
435  VkFormat VulkanRenderer::FindSupportedDepthFormat(const eastl::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
436 
437  eastl::unique_ptr<VulkanInstance> vulkanInstance_;
438  eastl::unique_ptr<VulkanPhysicalDevice> vulkanPhysicalDevice_;
439  eastl::unique_ptr<VulkanLogicalDevice> vulkanLogicalDevice_;
440  eastl::vector<eastl::shared_ptr<VulkanDescriptorPool>> vulkanDescriptorPools_;
441 
442  /*
443  VulkanInstance* vulkanInstance;
444  VulkanPhysicalDevice* vulkanPhysicalDevice;
445  VulkanLogicalDevice* vulkanLogicalDevice;
446  VulkanDescriptorPool* vulkanDescriptorPool;*/
447 
448  VulkanDeviceFeatures_t requiredFeatures;
449 
450  eastl::weak_ptr<VulkanWindow> window;
451 
452  VkSurfaceKHR surface;
453 
454 
455 
456 #pragma region Swapchain
457 
458  VkSwapchainKHR swapChain;
459 
460  uint32_t imageCount;
461  VkFormat swapChainImageFormat;
462  VkExtent2D swapChainImageExtent;
463 
464  uint32_t currentImage;
465  uint32_t prevImage;
466 
467  VkCommandPool graphicsCommandPool;
468  VkCommandPool computeCommandPool;
469 
470  eastl::vector<VkImage> swapChainImages;
471  eastl::vector<VkImageView> swapChainImageViews;
472 
473 #pragma endregion
474 
475 #pragma region Depth image
476 
477  VkImage depthImage;
478  VkImageView depthImageView;
479  VmaAllocation depthImageAllocation;
480  VmaAllocationInfo depthImageAllocationInfo;
481 
482  VkFormat depthImageFormat;
483 
484 #pragma endregion
485 
486 #pragma region Renderpass
487 
488  enum class GBufferAttachments {
489  ALBEDO_ATTACHMENT,
490  POSITION_ATTACHMENT,
491  NORMAL_ATTACHMENT,
492  DEPTH_ATTACHMENT,
493  ATTACHMENT_COUNT
494  };
495 
496  enum class SsaoAttachments {
497  SSAO_ATTACHMENT,
498  ATTACHMENT_COUNT
499  };
500 
501  enum class RenderPassAttachments {
502  COLOR_ATTACHMENT = 0,
503  ALBEDO_ATTACHMENT,
504  POSITION_ATTACHMENT,
505  NORMAL_ATTACHMENT,
506  SSAO_BLUR_ATTACHMENT,
507  RENDER_ATTACHMENT,
508  IMGUI_ATTACHMENT,
509  DEPTH_ATTACHMENT,
510  ATTACHMENT_COUNT
511  };
512 
513 
514  eastl::vector<VkAttachmentDescription> gBufferPassAttachments;
515  eastl::vector<VkSubpassDescription> gBufferPassSubPasses;
516 
517  eastl::vector<VkAttachmentDescription> ssaoPassAttachments;
518  eastl::vector<VkSubpassDescription> ssaoPassSubPasses;
519 
520  eastl::vector<VkAttachmentDescription> renderPassAttachments;
521  eastl::vector<VkSubpassDescription> renderPassSubPasses;
522 
523  VkRenderPass gBufferPass;
524  VkRenderPass ssaoPass;
525  VkRenderPass renderPass;
526 
527 #pragma endregion
528 
529 #pragma region Attachment images
530 
531  VkImage imguiImage;
532  VkImageView imguiImageView;
533  VmaAllocation imguiImageAllocation;
534  VmaAllocationInfo imguiImageAllocationInfo;
535 
536  VkImage renderImage;
537  VkImageView renderImageView;
538  VmaAllocation renderImageAllocation;
539  VmaAllocationInfo renderImageAllocationInfo;
540 
541  VkImage albedoImage;
542  VkImageView albedoImageView;
543  VmaAllocation albedoImageAllocation;
544  VmaAllocationInfo albedoImageAllocationInfo;
545 
546  VkImage positionImage;
547  VkImageView positionImageView;
548  VmaAllocation positionImageAllocation;
549  VmaAllocationInfo positionImageAllocationInfo;
550 
551  VkImage normalImage;
552  VkImageView normalImageView;
553  VmaAllocation normalImageAllocation;
554  VmaAllocationInfo normalImageAllocationInfo;
555 
556  VkImage ssaoImage;
557  VkImageView ssaoImageView;
558  VmaAllocation ssaoImageAllocation;
559  VmaAllocationInfo ssaoImageAllocationInfo;
560 
561  VkImage ssaoBlurImage;
562  VkImageView ssaoBlurImageView;
563  VmaAllocation ssaoBlurImageAllocation;
564  VmaAllocationInfo ssaoBlurImageAllocationInfo;
565 
566  VkSampler sampler;
567 
568 #pragma endregion
569 
570 #pragma region Framebuffers
571 
572  eastl::vector<VkFramebuffer> framebuffers;
573 
574  VkFramebuffer gBufferFrameBuffer;
575  VkFramebuffer ssaoFrameBuffer;
576 
577 #pragma endregion
578 
579 #pragma region CommandBuffers
580 
581  eastl::vector<VkCommandBuffer> primaryRenderCommandBuffers_;
582  eastl::vector<VkCommandBuffer> primaryComputeCommandBuffers_;
583 
584  eastl::vector<eastl::vector<VkCommandBuffer>> staticMeshShadowCommandBuffers_;
585  eastl::vector<eastl::vector<VkCommandBuffer>> skeletalMeshShadowCommandBuffers_;
586  eastl::vector<eastl::vector<VkCommandBuffer>> gBufferShadowCommandBuffers_;
587 
588  VkCommandBuffer compositeCommandBuffer_;
589 
590  VkCommandBuffer gBufferRenderCommandBuffer_;
591 
592  eastl::vector<VkCommandBuffer> imguiCommandBuffers_;
593 
594  VkCommandBuffer currentBuffer_;
595  VkCommandBuffer currentComputeBuffer_;
596 
597  eastl::vector<VkCommandBuffer> spriteRenderCommandBuffers_;
598 
599  eastl::vector<VkCommandBuffer> debugRenderCommandBuffers_;
600 
601  eastl::vector<VkCommandBuffer> staticMeshCommandBuffers_;
602 
603  eastl::vector<VkCommandBuffer> skeletalMeshCommandBuffers_;
604 
605  eastl::vector<VkCommandBuffer> clearStencilCommandBuffers_;
606 
607  void GenerateSecondaryCommandBuffers(VkCommandBuffer *buffers, uint32_t count);
608  void DestroySecondaryCommandBuffers(VkCommandBuffer*buffers, uint32_t count);
609 
610 #pragma endregion
611 
612 #pragma region Pipelines
613 
614  eastl::unique_ptr<VulkanPipeline> compositingPipeline_;
615 
616  eastl::unique_ptr<VulkanPipeline> gBufferRenderPipeline_;
617 
618  eastl::unique_ptr<VulkanPipeline> ambientLightPipeline_;
619 
620  eastl::unique_ptr<VulkanPipeline> ssaoPipeline_;
621  eastl::unique_ptr<VulkanPipeline> ssaoBlurPipeline_;
622 
623  VkDescriptorSet gBufferAttachmentDescriptorSet_;
624 
625  VkDescriptorSet SceneInfoDescriptorSet_;
626 
627  VkDescriptorSet CompositingAttachmentDescriptorSet_;
628 
629  VkDescriptorSet ssaoSamplerDescriptor_;
630 
631  VkDescriptorSet projectionDescriptor_;
632 
633  VkBuffer vertexBuffer_;
634  VmaAllocation vertexBufferAllocation_;
635 
636  eastl::unique_ptr<VulkanBuffer> ssaoKernelBuffer_;
637  eastl::unique_ptr<VulkanBuffer> projectionBuffer_;
638 
639  glm::mat4 projection_;
640 
641 #pragma endregion
642 
643 #pragma region Renderers
644 
645  eastl::unique_ptr<VulkanSpriteRenderer> vulkanSpriteRenderer;
646  eastl::unique_ptr<VulkanDebugRenderer> vulkanDebugRenderer;
647  eastl::unique_ptr<VulkanStaticMeshRenderer> vulkanStaticMeshRenderer;
648  eastl::unique_ptr<VulkanSkeletalMeshRenderer> vulkanSkeletalMeshRenderer;
649 
650 #pragma endregion
651 
652 #pragma region Scene
653 
654  eastl::unique_ptr<VulkanBuffer> sceneDataBuffer;
655  eastl::unique_ptr<VulkanBuffer> lightBuffer;
656 
657  eastl::array<Light, 1024> lightData;
658 
659  typedef struct {
660  int lightCount;
661  glm::vec4 viewPos;
662  }SceneInfo;
663 
664  int activeLights;
665 
666  SceneInfo scene;
667 
668  typedef struct {
669  size_t lightDataIndex;
670  Light light;
671  eastl::string name;
672  LightType type;
673  bool active;
674  }LightInfo;
675 
676  eastl::map<eastl::string, LightInfo> lights;
677 
678  eastl::vector<eastl::vector<eastl::vector<VkDescriptorSet>>> lightDescriptorSets_;
679 
680  bool lightDataChanged;
681  bool lightDataRestructured;
682 
683  void RestructureLights();
684 
685  void UpdateLightData();
686 
687 #pragma endregion
688 
689 #pragma region Threads
690 
691  struct ThreadInfo {
692  std::thread thread;
693  std::packaged_task<void()> task;
694  std::future<void> future;
695  bool initialized = false;
696  size_t threadId;
697  VkCommandPool commandPool;
698  };
699 
700  eastl::vector<ThreadInfo*> threads;
701 
702  ThreadInfo* GetFreeThread();
703  void JoinAllThreads();
704  void ResetCommandPools();
705 
706 #pragma endregion
707 
708  VmaAllocator vmaAllocator_;
709 
710  eastl::vector<VkSemaphore> imageAvailableSemaphores_;
711  eastl::vector<VkSemaphore> renderFinishedSemaphores_;
712  eastl::vector<VkSemaphore> computeFinishedSemaphores_;
713 
714  eastl::vector<VkFence> drawingFinishedFences_;
715  eastl::vector<VkFence> computeFinishedFences_;
716 
717  VkClearValue clearValue;
718 
719  bool initialized;
720 
721  bool firstRender;
722 
723  bool resized;
724 
725  };
726 } // namespace Engine
727 #endif // USING_VULKAN
Definition: Light.hpp:17
#define ENGINE_API
Definition: api.hpp:25
enum ENGINE_API LightType
Enum containing the different types of lights that can be created.
Definition: Light.hpp:9
IMGUI_API void Render()
Definition: imgui.cpp:2769