#ifndef _SDL_GAME_H #define _SDL_GAME_H #include #include #include #include #include #include "IMGUI/imgui_impl_vulkan.h" #include "consts.hpp" #include "vulkan-utils.hpp" #include "game-gui-sdl.hpp" using namespace std; using namespace std::chrono; #define VulkanGame NewVulkanGame #ifdef NDEBUG const bool ENABLE_VALIDATION_LAYERS = false; #else const bool ENABLE_VALIDATION_LAYERS = true; #endif // TODO: Maybe move this to a different header enum UIValueType { UIVALUE_INT, UIVALUE_DOUBLE, }; struct UIValue { UIValueType type; string label; void* value; UIValue(UIValueType _type, string _label, void* _value) : type(_type), label(_label), value(_value) {} }; class VulkanGame { public: VulkanGame(); ~VulkanGame(); void run(int width, int height, unsigned char guiFlags); private: static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); bool done; // TODO: Good place to start using smart pointers GameGui* gui; SDL_version sdlVersion; SDL_Window* window; VkInstance instance; VkDebugUtilsMessengerEXT debugMessenger; VkSurfaceKHR vulkanSurface; VkPhysicalDevice physicalDevice; VkDevice device; VkQueue graphicsQueue; VkQueue presentQueue; // TODO: Maybe make a swapchain struct for convenience VkSurfaceFormatKHR swapChainSurfaceFormat; VkPresentModeKHR swapChainPresentMode; VkExtent2D swapChainExtent; uint32_t swapChainMinImageCount; uint32_t swapChainImageCount; VkSwapchainKHR swapChain; vector swapChainImages; vector swapChainImageViews; vector swapChainFramebuffers; VkRenderPass renderPass; VkCommandPool resourceCommandPool; vector commandPools; vector commandBuffers; VulkanImage depthImage; // These are per frame vector imageAcquiredSemaphores; vector renderCompleteSemaphores; // These are per swap chain image vector inFlightFences; uint32_t imageIndex; uint32_t currentFrame; bool shouldRecreateSwapChain; // Maybe at some point create an imgui pipeline class, but I don't think it makes sense right now VkDescriptorPool imguiDescriptorPool; /*** High-level vars ***/ // TODO: Just typedef the type of this function to RenderScreenFn or something since it's used in a few places void (VulkanGame::* currentRenderScreenFn)(int width, int height); map> valueLists; int score; float fps; // TODO: Make a separate singleton Timer class time_point startTime; float fpsStartTime, curTime, prevTime, elapsedTime; int frameCount; /*** Functions ***/ bool initUI(int width, int height, unsigned char guiFlags); void initVulkan(); void renderLoop(); void cleanup(); void createVulkanInstance(const vector& validationLayers); void setupDebugMessenger(); void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo); void createVulkanSurface(); void pickPhysicalDevice(const vector& deviceExtensions); bool isDeviceSuitable(VkPhysicalDevice physicalDevice, const vector& deviceExtensions); void createLogicalDevice(const vector& validationLayers, const vector& deviceExtensions); void chooseSwapChainProperties(); void createSwapChain(); void createImageViews(); void createResourceCommandPool(); void createImageResources(); VkFormat findDepthFormat(); // TODO: Declare/define (in the cpp file) this function in some util functions section void createRenderPass(); void createCommandPools(); void createFramebuffers(); void createCommandBuffers(); void createSyncObjects(); void initImGuiOverlay(); void cleanupImGuiOverlay(); void renderFrame(ImDrawData* draw_data); void presentFrame(); void recreateSwapChain(); void cleanupSwapChain(); /*** High-level functions ***/ void renderMainScreen(int width, int height); void renderGameScreen(int width, int height); void initGuiValueLists(map>& valueLists); void renderGuiValueList(vector& values); void goToScreen(void (VulkanGame::* renderScreenFn)(int width, int height)); void quitGame(); }; #endif // _SDL_GAME_H