diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..f243ded --- /dev/null +++ b/.clang-format @@ -0,0 +1,50 @@ +StatementMacros: ['UPROPERTY', 'UFUNCTION', 'UCLASS', 'USTRUCT', 'UENUM', 'UINTERFACE', 'GENERATED_BODY'] +Language: Cpp +BasedOnStyle: LLVM + +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Left +AlignOperands: DontAlign +AlignTrailingComments: true +AllowShortBlocksOnASingleLine: Empty +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortLambdasOnASingleLine: All +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +BreakInheritanceList: AfterColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakStringLiterals: false +ColumnLimit: 0 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +Cpp11BracedListStyle: false +EmptyLineBeforeAccessModifier: LogicalBlock +IndentCaseBlocks: false +IndentCaseLabels: true +IndentPPDirectives: BeforeHash +IndentWidth: 4 +NamespaceIndentation: All +PointerAlignment: Left +SortIncludes: false +SpaceBeforeCaseColon: false +TabWidth: 4 +UseTab: Always diff --git a/Learning Vulkan.cpp b/Learning Vulkan.cpp index 555c7c2..2ee0a45 100644 --- a/Learning Vulkan.cpp +++ b/Learning Vulkan.cpp @@ -4,59 +4,258 @@ #include #include #include +#include +#include +#include +#include + +#include "Logger.h" const uint32_t WIDTH = 800; const uint32_t HEIGHT = 600; -class HelloTriangleApplication { - -private: - GLFWwindow* window; - -public: - void run() { - initWindow(); - initVulkan(); - mainLoop(); - cleanup(); - } - -private: - void initWindow() { - glfwInit(); - - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - - window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr); - } - void initVulkan() { - - } - - void mainLoop() { - while (!glfwWindowShouldClose(window)) { - glfwPollEvents(); - } - } - - void cleanup() { - glfwDestroyWindow(window); - - glfwTerminate(); - } +const std::vector validationLayers = { + "VK_LAYER_KHRONOS_validation" }; -int main() { - HelloTriangleApplication app; +#ifdef NDEBUG +const bool enableValidationLayers = false; +#else +const bool enableValidationLayers = true; +#endif - try { - app.run(); - } - catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - return EXIT_FAILURE; - } +class HelloTriangleApplication +{ - return EXIT_SUCCESS; +private: + 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; + } + +private: + GLFWwindow* window; + + VkInstance instance; + + std::vector GetRequiredExtensions() + { + uint32_t glfwExtensionCount = 0; + const char** glfwExtensions; + glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + + std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount); + + if (enableValidationLayers) + { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } + + return extensions; + } + + bool CheckValidationLayerSupport() + { + uint32_t layerCount; + vkEnumerateInstanceLayerProperties(&layerCount, nullptr); + + std::vector availableLayers(layerCount); + vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); + + for (const char* layerName : validationLayers) + { + bool layerFound = false; + + for (const auto& layerProperties : availableLayers) + { + if (strcmp(layerName, layerProperties.layerName) == 0) + { + layerFound = true; + break; + } + } + + if (!layerFound) + { + return false; + } + } + + return true; + } + + // VkResult vkCreateInstance( + // const VkInstanceCreateInfo* pCreateInfo, + // const VkAllocationCallbacks* pAllocator, + // VkInstance* instance) + //{ + // if (pCreateInfo == nullptr || instance == nullptr) { + // log("Null pointer passed to required parameter!"); + // return VK_ERROR_INITIALIZATION_FAILED; + // } + + // return vkCreateInstance(pCreateInfo, pAllocator, instance); + //} + +public: + void Run() + { + InitWindow(); + InitVulkan(); + MainLoop(); + Cleanup(); + } + +private: + void CheckExtensions(const char* requiredExtensions[], uint32_t requiredExtensionsCount) + { + uint32_t extensionCount = 0; + vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); + + std::vector extensions(extensionCount); + vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data()); + + std::string required; + std::string available; + + required += "Required extensions:\n"; + + bool found = false; + for (uint32_t i = 0; i < requiredExtensionsCount; i++) + { + std::string requiredExtension = requiredExtensions[i]; + + for (const auto& extension : extensions) + { + found = strcmp(extension.extensionName, requiredExtensions[i]); + if (found) + { + break; + } + } + + std::string status = found ? "FOUND" : "NOT FOUND"; + required += "\t" + requiredExtension + " : " + status + "\n"; + } + + available += "available extensions:\n"; + + for (const auto& extension : extensions) + { + std::string extensionName = extension.extensionName; + available += "\t" + extensionName + "\n"; + } + + log(INFO, required); + log(INFO, available); + } + + void CreateInstance() + { + log(INFO, "Creating Vulkan instance"); + + if (enableValidationLayers && !CheckValidationLayerSupport()) + { + throw std::runtime_error("validation layers requested, but not available!"); + } + + VkApplicationInfo appInfo{}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = "Hello Triangle"; + appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.pEngineName = "No Engine"; + appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.apiVersion = VK_API_VERSION_1_0; + + VkInstanceCreateInfo createInfo{}; + + createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + createInfo.pApplicationInfo = &appInfo; + + uint32_t glfwExtensionCount = 0; + const char** glfwExtensions; + glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + + createInfo.enabledExtensionCount = glfwExtensionCount; + createInfo.ppEnabledExtensionNames = glfwExtensions; + + if (enableValidationLayers) + { + createInfo.enabledLayerCount = static_cast(validationLayers.size()); + createInfo.ppEnabledLayerNames = validationLayers.data(); + } + else + { + createInfo.enabledLayerCount = 0; + } + + if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) + { + throw std::runtime_error("failed to create instance!"); + } + + CheckExtensions(glfwExtensions, glfwExtensionCount); + + auto extensions = GetRequiredExtensions(); + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + } + + void InitWindow() + { + log(INFO, "Initializing GLFW window..."); + + glfwInit(); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + + window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr); + } + + void InitVulkan() + { + log(INFO, "Initializing Vulkan..."); + CreateInstance(); + } + + void MainLoop() + { + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + } + } + + void Cleanup() + { + vkDestroyInstance(instance, nullptr); + + glfwDestroyWindow(window); + + glfwTerminate(); + } +}; + +int main() +{ + HelloTriangleApplication app; + + try + { + app.Run(); + } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Learning Vulkan.vcxproj b/Learning Vulkan.vcxproj index 127cf10..e1255ec 100644 --- a/Learning Vulkan.vcxproj +++ b/Learning Vulkan.vcxproj @@ -102,13 +102,13 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\OpenGL\glm-0.9.9.7\glm\glm;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Include;%(AdditionalIncludeDirectories) + C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Include;%(AdditionalIncludeDirectories) stdcpp17 Console true - C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Lib;%(AdditionalLibraryDirectories) + C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Lib;%(AdditionalLibraryDirectories) vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) @@ -120,19 +120,25 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\OpenGL\glm-0.9.9.7\glm\glm;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Include;%(AdditionalIncludeDirectories) + C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Include;%(AdditionalIncludeDirectories) stdcpp17 Console true - C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Lib;%(AdditionalLibraryDirectories) + C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Lib;%(AdditionalLibraryDirectories) vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + + + + + + diff --git a/Learning Vulkan.vcxproj.filters b/Learning Vulkan.vcxproj.filters index 6cb893e..7727e76 100644 --- a/Learning Vulkan.vcxproj.filters +++ b/Learning Vulkan.vcxproj.filters @@ -19,4 +19,12 @@ Source Files + + + Header Files + + + + + \ No newline at end of file diff --git a/Logger.cpp b/Logger.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Logger.h b/Logger.h new file mode 100644 index 0000000..076a529 --- /dev/null +++ b/Logger.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +enum LogLevel { + INFO, + WARNING, + ERROR +}; + +void log(LogLevel level, const std::string& message) { + std::string levelStr; + + switch(level) { + case INFO: + levelStr = "[INFO]"; + break; + case WARNING: + levelStr = "[WARNING]"; + break; + case ERROR: + levelStr = "[ERROR]"; + break; + default: + levelStr = "[UNKNOWN]"; + break; + } + std::cout << levelStr << " : " << message << std::endl; +}