#ifndef _VULKAN_GAME_H #define _VULKAN_GAME_H #include #include #include "game-gui-sdl.hpp" #include "graphics-pipeline_vulkan.hpp" #include "vulkan-utils.hpp" using namespace glm; #ifdef NDEBUG const bool ENABLE_VALIDATION_LAYERS = false; #else const bool ENABLE_VALIDATION_LAYERS = true; #endif struct ModelVertex { vec3 pos; vec3 color; vec2 texCoord; }; struct OverlayVertex { vec3 pos; vec2 texCoord; }; struct ShipVertex { vec3 pos; vec3 color; vec3 normal; }; struct UBO_VP_mats { alignas(16) mat4 view; alignas(16) mat4 proj; }; struct SBO_SceneObject { alignas(16) mat4 model; }; class VulkanGame { public: VulkanGame(int maxFramesInFlight); ~VulkanGame(); void run(int width, int height, unsigned char guiFlags); private: const int MAX_FRAMES_IN_FLIGHT; const float NEAR_CLIP = 0.1f; const float FAR_CLIP = 100.0f; const float FOV_ANGLE = 67.0f; vec3 cam_pos; UBO_VP_mats object_VP_mats; SBO_SceneObject so_Object; UBO_VP_mats ship_VP_mats; SBO_SceneObject so_Ship; GameGui* gui; GraphicsPipeline_Vulkan modelPipeline; GraphicsPipeline_Vulkan overlayPipeline; GraphicsPipeline_Vulkan shipPipeline; SDL_version sdlVersion; SDL_Window* window = nullptr; SDL_Renderer* renderer = nullptr; SDL_Texture* uiOverlay = nullptr; VkInstance instance; VkDebugUtilsMessengerEXT debugMessenger; VkSurfaceKHR surface; // TODO: Change the variable name to vulkanSurface VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; VkDevice device; VkQueue graphicsQueue; VkQueue presentQueue; VkSwapchainKHR swapChain; vector swapChainImages; VkFormat swapChainImageFormat; VkExtent2D swapChainExtent; vector swapChainImageViews; vector swapChainFramebuffers; VkRenderPass renderPass; VkCommandPool commandPool; vector commandBuffers; VulkanImage depthImage; VkSampler textureSampler; // TODO: I should probably rename the uniformBuffer* and storageBuffer* // variables to better reflect the data they hold vector uniformBuffers_scenePipeline; vector uniformBuffersMemory_scenePipeline; vector uniformBufferInfoList_scenePipeline; vector storageBuffers_scenePipeline; vector storageBuffersMemory_scenePipeline; vector storageBufferInfoList_scenePipeline; vector uniformBuffers_shipPipeline; vector uniformBuffersMemory_shipPipeline; vector uniformBufferInfoList_shipPipeline; vector storageBuffers_shipPipeline; vector storageBuffersMemory_shipPipeline; vector storageBufferInfoList_shipPipeline; VulkanImage floorTextureImage; VkDescriptorImageInfo floorTextureImageDescriptor; VulkanImage sdlOverlayImage; VkDescriptorImageInfo sdlOverlayImageDescriptor; TTF_Font* font; SDL_Texture* fontSDLTexture; SDL_Texture* imageSDLTexture; vector imageAvailableSemaphores; vector renderFinishedSemaphores; vector inFlightFences; size_t currentFrame; bool framebufferResized; bool initWindow(int width, int height, unsigned char guiFlags); void initVulkan(); void initGraphicsPipelines(); void initMatrices(); void mainLoop(); void updateScene(uint32_t currentImage); void renderUI(); void renderScene(); 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 createSwapChain(); void createImageViews(); void createRenderPass(); VkFormat findDepthFormat(); void createCommandPool(); void createImageResources(); void createTextureSampler(); void createFramebuffers(); void createCommandBuffers(); void createSyncObjects(); template vector addVertexNormals(vector vertices); void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, vector& buffers, vector& buffersMemory, vector& bufferInfoList); void recreateSwapChain(); void cleanupSwapChain(); static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); }; template vector VulkanGame::addVertexNormals(vector vertices) { for (unsigned int i = 0; i < vertices.size(); i += 3) { vec3 p1 = vertices[i].pos; vec3 p2 = vertices[i+1].pos; vec3 p3 = vertices[i+2].pos; vec3 normal = normalize(cross(p2 - p1, p3 - p1)); normal.z = -normal.z; // Add the same normal for all 3 vertices vertices[i].normal = normal; vertices[i+1].normal = normal; vertices[i+2].normal = normal; } return vertices; } #endif // _VULKAN_GAME_H