#pragma once #include "RenderEngineBase.hpp" #include "ModelManager.hpp" #include #include #include #include #define GLM_FORCE_RADIANS #include #include class GPU_GarbageCollector; class UwURenderEngine : public RenderEngineBase { struct QueueFamilyIndices { std::optional graphics_family; std::optional present_family; std::optional transfer_family; }; struct SwapchainSupportDetails { VkSurfaceCapabilitiesKHR capabilities; std::vector formats; std::vector present_modes; }; struct UniformBufferObject { glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; const std::vector vertices_ = { {{-0.5f, -0.5f, 0.5f}, {1.0f, 0.0f, 0.0f}}, {{0.5f, -0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, {{0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, {{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}}, {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, {{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}}, {{0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}}, {{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}} }; const std::vector indices_ = { 0, 1, 2, 2, 3, 0, 2, 1, 5, 5, 6, 2, 0, 3, 7, 7, 4, 0, 3, 2, 6, 6, 7, 3, 7, 6, 5, 5, 4, 7, 4, 5, 1, 1, 0, 4 }; static const std::vector deviceExtensions; int current_frame_ = 0; CoreInstance& core_; std::shared_ptr model_manager_; std::shared_ptr garbage_collector_; VkInstance instance_ = VK_NULL_HANDLE; VkSurfaceKHR surface_ = VK_NULL_HANDLE; VkPhysicalDevice physical_device_ = VK_NULL_HANDLE; VkDevice device_ = VK_NULL_HANDLE; VkQueue graphics_queue_ = VK_NULL_HANDLE; VkQueue present_queue_ = VK_NULL_HANDLE; VkQueue transfer_queue_ = VK_NULL_HANDLE; VkSwapchainKHR swapchain_ = VK_NULL_HANDLE; std::vector swapchain_images_; VkFormat swapchain_image_format_; VkExtent2D swapchain_extent_; std::vector swapchain_image_views_; VkRenderPass render_pass_ = VK_NULL_HANDLE; VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE; VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE; std::vector descriptor_sets_; VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; VkPipeline graphics_pipeline_ = VK_NULL_HANDLE; std::vector framebuffers_; VkCommandPool command_pool_ = VK_NULL_HANDLE; std::vector command_buffers_; VkBuffer vertex_buffer_ = VK_NULL_HANDLE; VkDeviceMemory vertex_buffer_memory_ = VK_NULL_HANDLE; VkBuffer index_buffer_ = VK_NULL_HANDLE; VkDeviceMemory index_buffer_memory_ = VK_NULL_HANDLE; std::vector uniform_buffers_; std::vector uniform_buffers_memory_; std::vector uniform_buffers_mapped_; // Sync objects std::vector image_available_semaphores_, render_finished_semaphores_; std::vector in_flight_fences_; #ifdef _DEBUG VkResult enable_layer_validation(const VkDebugUtilsMessengerCreateInfoEXT* create_info); VkDebugUtilsMessengerEXT debug_messenger_; #endif SwapchainSupportDetails query_swapchain_details() const; static std::vector get_required_extensions(); static bool is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface); static bool check_device_extensions_support(VkPhysicalDevice device); static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface); static VkSurfaceFormatKHR choose_surface_format(const std::vector& surface_formats); static VkPresentModeKHR choose_present_mode(const std::vector& present_modes, VkPresentModeKHR desired_present_mode); VkShaderModule create_shader_module(const std::string& code) const; static std::vector get_unique_family_indices(const QueueFamilyIndices& indices); void create_instance(); void create_surface(); void pick_physical_device(); void create_logical_device(); void create_swapchain(); void create_image_views(); void create_render_pass(); void create_description_set_layout(); void create_uniform_buffers(); void create_descriptor_pool(); void create_descriptor_sets(); void create_graphics_pipeline(); void create_framebuffers(); void create_command_pool(); void allocate_command_buffers(); void create_sync_objects(); void allocate_vertex_buffer(); void allocate_index_buffer(); void record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index) const; void update_uniform_buffer(uint32_t current_frame); void draw_frame(); public: // Can throw the exception explicit UwURenderEngine(CoreInstance& core); ~UwURenderEngine() override; void start() override; void stop_render() const override; std::shared_ptr GetModelManager() const { return model_manager_; } };