diff --git a/HelloTriangleApplication.h b/HelloTriangleApplication.h new file mode 100644 index 0000000..355e71e --- /dev/null +++ b/HelloTriangleApplication.h @@ -0,0 +1,166 @@ +#ifndef HelloTriangleApplication_H_ +#define HelloTriangleApplication_H_ + + +#define GLFW_INCLUDE_VULKAN +#include + +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NDEBUG +const bool enableValidationLayers = false; +#else +const bool enableValidationLayers = true; +#endif + +const int MAX_FRAMES_IN_FLIGHT = 2; + +const uint32_t WIDTH = 800; +const uint32_t HEIGHT = 600; + +const std::vector validationLayers = { + "VK_LAYER_KHRONOS_validation" +}; + +const std::vector deviceExtensions = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME +}; + + +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; +}; + +class HelloTriangleApplication { +public: + void run() { + initWindow(); + initVulkan(); + mainLoop(); + cleanup(); + } + +private: + GLFWwindow* window; + VkInstance instance; + VkDebugUtilsMessengerEXT debugMessenger; + VkSurfaceKHR surface; + + VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; + VkDevice device; + + VkQueue graphicsQueue; + VkQueue presentQueue; + + VkSwapchainKHR swapChain; + std::vector swapChainImages; + VkFormat swapChainImageFormat; + VkExtent2D swapChainExtent; + std::vector swapChainImageViews; + std::vector swapChainFramebuffers; + + VkRenderPass renderPass; + VkPipelineLayout pipelineLayout; + VkPipeline graphicsPipeline; + + VkCommandPool commandPool; + std::vector commandBuffers; + + std::vector imageAvailableSemaphores; + std::vector renderFinishedSemaphores; + std::vector inFlightFences; + std::vector imagesInFlight; + size_t currentFrame = 0; + + bool framebufferResized = false; + void initWindow(); + void initVulkan(); + void mainLoop(); + + static void framebufferResizeCallback(GLFWwindow* window, int width, int height) { + auto app = reinterpret_cast(glfwGetWindowUserPointer(window)); + app->framebufferResized = true; + } + + void cleanupSwapChain(); + void cleanup(); + void recreateSwapChain(); + void createInstance(); + void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo); + void setupDebugMessenger(); + + void createSurface() { + if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) { + throw std::runtime_error("failed to create window surface!"); + } + } + + void pickPhysicalDevice(); + + void createLogicalDevice(); + + void createSwapChain(); + + void createImageViews(); + + void createRenderPass(); + + void createGraphicsPipeline(); + + void createFramebuffers(); + + void createCommandPool(); + + void createCommandBuffers(); + + void createSyncObjects(); + + void drawFrame(); + + VkShaderModule createShaderModule(const std::vector& code); + + VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats); + + VkPresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes); + + VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities); + + SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device); + + bool isDeviceSuitable(VkPhysicalDevice device); + + bool checkDeviceExtensionSupport(VkPhysicalDevice device); + QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); + + std::vector getRequiredExtensions(); + + bool checkValidationLayerSupport(); + static std::vector readFile(const std::string& filename); + + static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); +}; +#endif \ No newline at end of file