#ifndef HELLOTRIANGLEAPPLICATION_H #define HELLOTRIANGLEAPPLICATION_H #ifdef NDEBUG const bool enableValidationLayers = false; #else const bool enableValidationLayers = true; #endif //#include #define VK_USE_PLATFORM_ #define GLFW_INCLUDE_VULKAN #include #define GLFW_EXPOSE_NATIVE_ #include #define GLM_FORCE_RADIANS #include #include #include #include #include #include #include // Necessary for uint32_t #include // Necessary for std::numeric_limits #include // Necessary for std::clamp #include #include const int MAX_FRAMES_IN_FLIGHT = 2; struct QueueFamilyIndices { std::optional graphicsFamily; std::optional presentFamily; bool isComplete() { return graphicsFamily.has_value() && presentFamily.has_value(); } }; struct SwapChainSupportDetails { VkSurfaceCapabilitiesKHR capabilities; std::vector formats; std::vector presentModes; }; struct Vertex { glm::vec2 pos; glm::vec3 color; static VkVertexInputBindingDescription getBindingDescription() { VkVertexInputBindingDescription bindingDescription{}; bindingDescription.binding = 0; bindingDescription.stride = sizeof(Vertex); bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; return bindingDescription; } static std::array getAttributeDescriptions() { std::array attributeDescriptions{}; attributeDescriptions[0].binding = 0; attributeDescriptions[0].location = 0; attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT; attributeDescriptions[0].offset = offsetof(Vertex, pos); attributeDescriptions[1].binding = 0; attributeDescriptions[1].location = 1; attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; attributeDescriptions[1].offset = offsetof(Vertex, color); return attributeDescriptions; } }; struct UniformBufferObject { glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; class HelloTriangleApplication { public: HelloTriangleApplication(); void run(); // Message Callback static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT /*messageSeverity*/, VkDebugUtilsMessageTypeFlagsEXT /*messageType*/,const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,void* /*pUserData*/) { std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl; return VK_FALSE; } static std::vector readFile(const std::string& filename); static void framebufferResizeCallback(GLFWwindow* window, int width, int height); private: void initWindow(); void initVulkan(); void mainLoop(); void cleanup(); void createInstance(); // Enable Validation Layers bool checkValidationLayerSupport(); // Message Callback std::vector getRequiredExtensions(); void setupDebugMessenger(); void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo); void pickPhysicalDevice(); bool isDeviceSuitable(VkPhysicalDevice device); void createLogicalDevice(); QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); void createSurface(); bool checkDeviceExtensionSupport(VkPhysicalDevice device); SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device); VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats); VkPresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes); VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities); void createSwapChain(); void createImageViews(); void createGraphicsPipeline(); VkShaderModule createShaderModule(const std::vector& code); void createRenderPass(); void createFramebuffers(); void createCommandPool(); void createCommandBuffer(); void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); void drawFrame(); void createSyncObjects(); void recreateSwapChain(); void cleanupSwapChain(); void createVertexBuffer(); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory); void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); void createIndexBuffer(); void createDescriptorSetLayout(); void createUniformBuffers(); void updateUniformBuffer(uint32_t currentImage); void createDescriptorPool(); void createDescriptorSets(); const int32_t WIDTH = 800; const int32_t HEIGHT = 600; const std::vector validationLayers = { "VK_LAYER_KHRONOS_validation" }; const std::vector deviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; const std::vector vertices = { {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, {{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}}, {{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, {{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}} }; const std::vector indices = { 0, 1, 2, 2, 3, 0 }; uint32_t currentFrame = 0; bool framebufferResized = false; GLFWwindow *_window; VkInstance _instance; VkDebugUtilsMessengerEXT _debugMessenger; VkPhysicalDevice _physicalDevice; VkDevice _device; VkQueue _graphicsQueue; VkSurfaceKHR _surface; VkQueue _presentQueue; VkSwapchainKHR _swapChain; std::vector _swapChainImages; VkFormat _swapChainImageFormat; VkExtent2D _swapChainExtent; std::vector _swapChainImageViews; VkRenderPass _renderPass; VkDescriptorSetLayout _descriptorSetLayout; VkPipelineLayout _pipelineLayout; VkPipeline _graphicsPipeline; std::vector _swapChainFramebuffers; VkCommandPool _commandPool; std::vector _commandBuffers; std::vector _imageAvailableSemaphores; std::vector _renderFinishedSemaphores; std::vector _inFlightFences; VkBuffer _vertexBuffer; VkDeviceMemory _vertexBufferMemory; VkBuffer _indexBuffer; VkDeviceMemory _indexBufferMemory; std::vector _uniformBuffers; std::vector _uniformBuffersMemory; std::vector _uniformBuffersMapped; VkDescriptorPool _descriptorPool; std::vector descriptorSets; }; #endif // HELLOTRIANGLEAPPLICATION_H