diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 4fcc50b012eca626d4c98f84b3b9f195a8d3e8f1..e78586d085fb85ff875fa65ec817893afb380ac2 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -6,8 +6,9 @@ #include <vulkan/vulkan.hpp> #include "vkcv/Context.hpp" +#include "vkcv/SwapChain.hpp" +#include "vkcv/Window.hpp" #include "vkcv/Handles.hpp" -#include <GLFW/glfw3.h> namespace vkcv { @@ -25,11 +26,14 @@ namespace vkcv * * @param context encapsulates various Vulkan objects */ - explicit Core(Context &&context) noexcept; + Core(Context &&context, const Window &window, SwapChain &swapChain) noexcept; // explicit destruction of default constructor Core() = delete; Context m_Context; + SwapChain& m_swapchain; + const Window& m_window; + public: /** * Destructor of #Core destroys the Vulkan objects contained in the core's context. @@ -85,7 +89,8 @@ namespace vkcv * @param[in] deviceExtensions (optional) Requested device extensions * @return New instance of #Context */ - static Core create(const char *applicationName, + static Core create(const Window &window, + const char *applicationName, uint32_t applicationVersion, uint32_t queueCount, std::vector<vk::QueueFlagBits> queueFlags = {}, @@ -98,30 +103,4 @@ namespace vkcv PipelineHandle createPipeline(const Pipeline &pipeline); }; - - /** - * initializes glfw once and increases the counter - */ - void initGLFW(); - - /** - * terminates glfw once, if it was initialized or decreases the counter - */ - void terminateGLFW(); - - /** - * gets the window width - * @param window glfwWindow - * @return int with window width - */ - [[nodiscard]] - int getWidth(GLFWwindow *window); - - /** - * gets the window height - * @param window glfwWindow - * @return int with window height - */ - [[nodiscard]] - int getHeight(GLFWwindow *window); } diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp index 35d3eb3e9ab7458dffd4e27d7984b396f9faf8a7..42e408b9e75ed20252594878feee8aa4b04c24a5 100644 --- a/include/vkcv/SwapChain.hpp +++ b/include/vkcv/SwapChain.hpp @@ -1,7 +1,7 @@ #pragma once #include "vulkan/vulkan.hpp" -#include "Core.hpp" -#include <GLFW/glfw3.h> +#include "Context.hpp" +#include "vkcv/Window.hpp" #include <iostream> @@ -13,10 +13,10 @@ namespace vkcv { private: vk::SurfaceKHR m_surface; - const vkcv::Core* m_core; + const vkcv::Context& m_context; vk::SwapchainKHR m_swapchain; - SwapChain(vk::SurfaceKHR surface, const vkcv::Core* core, vk::SwapchainKHR swapchain); + SwapChain(vk::SurfaceKHR surface, const vkcv::Context &context, vk::SwapchainKHR swapchain); public: // bin mir grade unsicher wegen der Mehrfachinstanziierung der Klasse @@ -31,7 +31,7 @@ namespace vkcv { [[nodiscard]] vk::SwapchainKHR getSwapchain(); - static SwapChain create(GLFWwindow *window, const vkcv::Core* core); + static SwapChain create(const Window &window, const Context &context); virtual ~SwapChain(); }; diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp index 43fce827bf2da863a843e933e52c3704dfdf06b6..ef5e35cc10a9983440d3d33f7d8dd93a6aef5199 100644 --- a/include/vkcv/Window.hpp +++ b/include/vkcv/Window.hpp @@ -4,10 +4,7 @@ * @file src/vkcv/Window.hpp * @brief Window class to handle a basic rendering surface and input */ - -#define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h> -#include "SwapChain.hpp" #define NOMINMAX #include <algorithm> @@ -17,13 +14,12 @@ namespace vkcv { private: GLFWwindow *m_window; - const vkcv::SwapChain* m_swapChain; /** * * @param GLFWwindow of the class */ - Window(GLFWwindow *window, const vkcv::SwapChain *swapChain); + explicit Window(GLFWwindow *window); public: /** @@ -34,7 +30,7 @@ namespace vkcv { * @param[in] resizable resize ability of the window (optional) * @return Window class */ - static Window create(const vkcv::Core& core, const char *windowTitle, int width = -1, int height = -1, bool resizable = false); + static Window create( const char *windowTitle, int width = -1, int height = -1, bool resizable = false); /** * checks if the window is still open, or the close event was called * This function should be changed/removed later on @@ -71,10 +67,25 @@ namespace vkcv { */ Window &operator=(Window &&other) = default; + /** + * gets the window width + * @param window glfwWindow + * @return int with window width + */ + [[nodiscard]] + int getWidth() const; + + /** + * gets the window height + * @param window glfwWindow + * @return int with window height + */ + [[nodiscard]] + int getHeight() const; + /** * Destructor of #Window, terminates GLFW */ virtual ~Window(); - }; } \ No newline at end of file diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index ab11172802cb8d32f49eef0dae0bf611c61314a3..0136179b3aca160a7e912702987fe7a95dcdb428 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -1,11 +1,18 @@ #include <iostream> #include <vkcv/Core.hpp> -#include <vkcv/Window.hpp> int main(int argc, const char** argv) { const char* applicationName = "First Triangle"; - + + vkcv::Window window = vkcv::Window::create( + applicationName, + 800, + 600, + false + ); + vkcv::Core core = vkcv::Core::create( + window, applicationName, VK_MAKE_VERSION(0, 0, 1), 20, @@ -18,15 +25,6 @@ int main(int argc, const char** argv) { const vk::Instance& instance = context.getInstance(); const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); const vk::Device& device = context.getDevice(); - - vkcv::Window window = vkcv::Window::create( - core, - applicationName, - 800, - 600, - false - ); - std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl; diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 9f28db42e89af1707b4cf493340aa56e070e1307..b36e2d94d9903cca4fb0c38115b9cd5b3bac1f7e 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -178,14 +178,14 @@ namespace vkcv return -1; } - Core Core::create(const char *applicationName, + Core Core::create(const Window &window, + const char *applicationName, uint32_t applicationVersion, uint32_t queueCount, std::vector<vk::QueueFlagBits> queueFlags, std::vector<const char *> instanceExtensions, std::vector<const char *> deviceExtensions) { - vkcv::initGLFW(); // check for layer support const std::vector<vk::LayerProperties>& layerProperties = vk::enumerateInstanceLayerProperties(); @@ -307,7 +307,8 @@ namespace vkcv Context context(instance, physicalDevice, device); - return Core(std::move(context)); + SwapChain swapChain = SwapChain::create(window, context); + return Core(std::move(context) , window, swapChain); } const Context &Core::getContext() const @@ -315,40 +316,9 @@ namespace vkcv return m_Context; } - Core::Core(Context &&context) noexcept : - m_Context(std::move(context)) + Core::Core(Context &&context, const Window &window , SwapChain &swapChain) noexcept : + m_Context(std::move(context)), + m_window(window), + m_swapchain(swapChain) {} - - int glfwCounter = 0; - - void initGLFW() { - - if (glfwCounter == 0) { - int glfwSuccess = glfwInit(); - - if (glfwSuccess == GLFW_FALSE) { - throw std::runtime_error("Could not initialize GLFW"); - } - } - glfwCounter++; - } - - void terminateGLFW() { - if (glfwCounter == 1) { - glfwTerminate(); - } - glfwCounter--; - } - - int getWidth(GLFWwindow *window) { - int width; - glfwGetWindowSize(window, &width, nullptr); - return width; - } - - int getHeight(GLFWwindow *window) { - int height; - glfwGetWindowSize(window, nullptr, &height); - return height; - } } diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp index bcc51de659588bad8badd95343fb3957ffb63106..6bb3d229432fa4ef75c8890c30b6ce13faff7f90 100644 --- a/src/vkcv/SwapChain.cpp +++ b/src/vkcv/SwapChain.cpp @@ -3,9 +3,9 @@ namespace vkcv { - SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Core* core, vk::SwapchainKHR swapchain) - : m_surface(surface), m_core(core), m_swapchain(swapchain) - {} + SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Context &context, vk::SwapchainKHR swapchain) + : m_surface(surface), m_context(context), m_swapchain(swapchain) + {} vk::SwapchainKHR SwapChain::getSwapchain() { return m_swapchain; @@ -22,7 +22,7 @@ namespace vkcv { vk::Bool32 surfaceSupport = false; // ToDo: hierfuer brauchen wir jetzt den queuefamiliy Index -> siehe ToDo in Context.cpp // frage: nimmt die Swapchain automatisch den 0'ten Index (Graphics Queue Family)? - if (physicalDevice.getSurfaceSupportKHR(0, surface, &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) { + if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) { throw std::runtime_error("surface is not supported by the device!"); } @@ -30,15 +30,15 @@ namespace vkcv { } - vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window){ + vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, const Window &window){ vk::SurfaceCapabilitiesKHR surfaceCapabilities; if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){ throw std::runtime_error("cannot get surface capabilities. There is an issue with the surface."); } VkExtent2D extent2D = { - static_cast<uint32_t>(vkcv::getWidth(window)), - static_cast<uint32_t>(vkcv::getHeight(window)) + static_cast<uint32_t>(window.getWidth()), + static_cast<uint32_t>(window.getHeight()) }; extent2D.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, extent2D.width)); extent2D.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, extent2D.height)); @@ -99,13 +99,12 @@ namespace vkcv { return imageCount; } - SwapChain SwapChain::create(GLFWwindow* window, const vkcv::Core* core) { + SwapChain SwapChain::create(const Window &window, const Context &context) { + const vk::Instance& instance = context.getInstance(); + const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); + const vk::Device& device = context.getDevice(); - const vk::Instance& instance = core->getContext().getInstance(); - const vk::PhysicalDevice& physicalDevice = core->getContext().getPhysicalDevice(); - const vk::Device& device = core->getContext().getDevice(); - - vk::SurfaceKHR surface = createSurface(window,instance,physicalDevice); + vk::SurfaceKHR surface = createSurface(window.getWindow(),instance,physicalDevice); vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window); vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface); @@ -133,14 +132,13 @@ namespace vkcv { vk::SwapchainKHR swapchain = device.createSwapchainKHR(swapchainCreateInfo); - return SwapChain(surface, core, swapchain); - + return SwapChain(surface, context, swapchain); } SwapChain::~SwapChain() { - m_core->getContext().getDevice().destroySwapchainKHR( m_swapchain ); - m_core->getContext().getInstance().destroySurfaceKHR( m_surface ); + m_context.getDevice().destroySwapchainKHR( m_swapchain ); + m_context.getInstance().destroySurfaceKHR( m_surface ); } } diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp index 962e8ccaa3276997dd5979235b32b9c6ae98b714..ce05d67cb216215c625b468acdb85be2fc2a8b2e 100644 --- a/src/vkcv/Window.cpp +++ b/src/vkcv/Window.cpp @@ -11,20 +11,23 @@ namespace vkcv { static uint32_t s_WindowCount = 0; - Window::Window(GLFWwindow *window, const vkcv::SwapChain *swapChain) - : m_window(window), m_swapChain(swapChain) { + Window::Window(GLFWwindow *window) + : m_window(window) { } Window::~Window() { glfwDestroyWindow(m_window); s_WindowCount--; - terminateGLFW(); + if(s_WindowCount == 0) { + glfwTerminate(); + } } - Window Window::create(const vkcv::Core& core, const char *windowTitle, int width, int height, bool resizable) { - initGLFW(); - + Window Window::create( const char *windowTitle, int width, int height, bool resizable) { + if(s_WindowCount == 0) { + glfwInit(); + } s_WindowCount++; width = std::max(width, 1); @@ -35,11 +38,7 @@ namespace vkcv { GLFWwindow *window; window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr); - const vkcv::SwapChain swapChain = vkcv::SwapChain::create( - window, - &core); - - return Window(window, &swapChain); + return Window(window); } bool Window::isWindowOpen() const { @@ -50,6 +49,18 @@ namespace vkcv { glfwPollEvents(); } + int Window::getWidth() const { + int width; + glfwGetWindowSize(m_window, &width, nullptr); + return width; + } + + int Window::getHeight() const { + int height; + glfwGetWindowSize(m_window, nullptr, &height); + return height; + } + GLFWwindow *Window::getWindow() const { return m_window; }