Hubris Engine Dev
A Project to learn and get into Game Engine developement.
 
Loading...
Searching...
No Matches
vkWindow.cpp
Go to the documentation of this file.
1#include "pch.h"
3#define VOLK_IMPLEMENTATION
5// #include "GLFW/glfw3.h"
6
12 GLFWwindow* Window;
13 VkSurfaceKHR surface;
14};
15
17 VkSurfaceCapabilitiesKHR capabilities;
18 std::vector<VkSurfaceFormatKHR> formats;
19 std::vector<VkPresentModeKHR> presentModes;
20};
21
22//TODO: Make the user able to choose for their game.
23VkSurfaceFormatKHR ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats) noexcept
24{
25 for (const auto& availableFormat : availableFormats) {
26 if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
27 return availableFormat;
28 }
29 }
30
31 return availableFormats[0];
32}
33
34VkPresentModeKHR ChooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) {
35 for (const auto& availablePresentMode : availablePresentModes) {
36 if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
37 return availablePresentMode;
38 }
39 }
40
41 return VK_PRESENT_MODE_FIFO_KHR;
42}
43
44
45VkExtent2D ChooseSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities) {
46 if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
47 return capabilities.currentExtent;
48 } else {
49 int width, height;
50 glfwGetFramebufferSize(window, &width, &height);
51
52 VkExtent2D actualExtent = {
53 static_cast<uint32_t>(width),
54 static_cast<uint32_t>(height)
55 };
56
57 actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
58 actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
59
60 return actualExtent;
61 }
62}
63
64void Hubris::Graphics::Vulkan::vkWindow::InitGLFW()
65{
66 if(glfwInit() == GLFW_FALSE){
67 Logger::Log("Failed to initialize GLFW");
68 return;
69 }
70
71 glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
72 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
73}
74
76{
77 GLFWwindow* win;
78 win = glfwCreateWindow(Width, Height, title.c_str(), nullptr, nullptr);
79 if(!win){
80 const char* error;
81 int n = glfwGetError(&error);
82 Logger::Fatal("Error Creating Window: {}", error);
83 }
84 glfwShowWindow(win);
85 VkSurfaceKHR surface;
86 if (glfwCreateWindowSurface(vkBackend::GetInstance(), win, nullptr, &surface) != VK_SUCCESS) {
87 Logger::Fatal("Failed to create a window surface.");
88 const char* desc;
89 glfwGetError(&desc);
90 Logger::Fatal("GLFW: {}", desc);
91 return nullptr;
92 }
93 vkWindow* vkwindow = new vkWindow();
94 vkwindow->details = new Details();
95 vkwindow->details->Window = win;
96 vkwindow->details->surface = surface;
97 glfwSetWindowUserPointer(win, vkwindow->details);
98 vkBackend::Init(vkwindow->details->surface);
99
100 VkPhysicalDevice pdevice = vkBackend::GetPhysicalDevice();
101 //Creating the swapchain.
102 SwapChainSupportDetails swapDetails;
103 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdevice, surface, &swapDetails.capabilities);
104 uint32_t formatCount;
105 vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice, surface, &formatCount, nullptr);
106 if (formatCount != 0) {
107 swapDetails.formats.resize(formatCount);
108 vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice, surface, &formatCount, swapDetails.formats.data());
109 }
110 uint32_t presentModeCount;
111 vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice, surface, &presentModeCount, nullptr);
112
113 if (presentModeCount != 0) {
114 swapDetails.presentModes.resize(presentModeCount);
115 vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice, surface, &presentModeCount, swapDetails.presentModes.data());
116 }
117
118 bool swapChainAdequate = !swapDetails.formats.empty() && !swapDetails.presentModes.empty();
119
120 if(!swapChainAdequate){
121 Logger::Fatal("No adequate Swapchain found.");
122 vkwindow->Close();
123 delete vkwindow;
124 return nullptr;
125 }
126
127
128 VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapDetails.formats);
129 VkPresentModeKHR presentMode = ChooseSwapPresentMode(swapDetails.presentModes);
130 VkExtent2D extent = ChooseSwapExtent(win, swapDetails.capabilities);
131
132 uint32_t imageCount = swapDetails.capabilities.minImageCount + 1;
133
134 if (swapDetails.capabilities.maxImageCount > 0 && imageCount > swapDetails.capabilities.maxImageCount) {
135 imageCount = swapDetails.capabilities.maxImageCount;
136 }
137
138 VkSwapchainCreateInfoKHR createInfo{};
139 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
140 createInfo.surface = surface;
141
142 createInfo.minImageCount = imageCount;
143 createInfo.imageFormat = surfaceFormat.format;
144 createInfo.imageColorSpace = surfaceFormat.colorSpace;
145 createInfo.imageExtent = extent;
146 createInfo.imageArrayLayers = 1;
147 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
148 createInfo.preTransform = swapDetails.capabilities.currentTransform;
149 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
150 createInfo.presentMode = presentMode;
151 createInfo.clipped = VK_TRUE;
152
154 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
155 createInfo.queueFamilyIndexCount = 2;
156 static uint32_t queueFamilyIndices[] = { vkRenderer::GetGraphicsQueueIndex(), vkRenderer::GetPresentQueueIndex() };
157 createInfo.pQueueFamilyIndices = queueFamilyIndices;
158 } else {
159 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
160 createInfo.queueFamilyIndexCount = 0; // Optional
161 createInfo.pQueueFamilyIndices = nullptr; // Optional
162 }
163
164 VkSwapchainKHR swapchain;
165
166 if (vkCreateSwapchainKHR(vkBackend::GetDevice(), &createInfo, nullptr, &swapchain) != VK_SUCCESS) {
167 Logger::Fatal("failed to create swap chain!");
168 throw std::runtime_error("failed to create swap chain!");
169 }
170
171 //Get the count from vulkan now.
172 vkwindow->swapchain = vkSwapchain(swapchain, surfaceFormat.format, extent);
173
174
175 return vkwindow;
176}
177
179{
180 Close();
181 delete details;
182}
183
185{
186 //TODO: add Hooks to the window.
187
188}
189
191{
192 while (!glfwWindowShouldClose(details->Window)) {
193 glfwPollEvents();
194 }
195}
196
198{
199 glfwSetWindowShouldClose(details->Window, true);
200 vkDestroySurfaceKHR(vkBackend::GetInstance(), details->surface, nullptr);
201 swapchain.Destroy();
202}
203
208
210{
211 return glfwWindowShouldClose(details->Window);
212}
213
215{
216 return !glfwWindowShouldClose(details->Window);
217}
218
220{
221 return (void*)details->Window;
222}
223
225{
226 return (void*)details->surface;
227}
228
static VkInstance GetInstance() noexcept
Definition vkBackend.h:251
static VkPhysicalDevice GetPhysicalDevice() noexcept
Definition vkBackend.h:253
static ErrorCode Init(VkSurfaceKHR surface) noexcept
Initializes the Vulkan backend. This is the first step to use any vulkan api.
Definition vkBackend.h:260
static VkDevice GetDevice() noexcept
Definition vkBackend.h:252
static VkQueue GetPresentQueue() noexcept
Definition vkRenderer.h:19
static VkQueue GetGraphicsQueue() noexcept
Definition vkRenderer.h:17
static uint32_t GetPresentQueueIndex() noexcept
Definition vkRenderer.h:20
static uint32_t GetGraphicsQueueIndex() noexcept
Definition vkRenderer.h:18
Vulkan specific Windowing implementation.
Definition vkWindow.h:11
Swapchain * GetSwapchain() const noexcept
Definition vkWindow.cpp:229
bool IsValid() const noexcept override
Definition vkWindow.cpp:209
Viewport GetViewport() const noexcept override
Gets the window dimension.
Definition vkWindow.cpp:204
void Init() override
Intializes the rendering backend and creates the Window.
Definition vkWindow.cpp:184
void * GetNative() const noexcept override
Get the Native object.
Definition vkWindow.cpp:219
bool IsRunning() const noexcept override
Definition vkWindow.cpp:214
static vkWindow * Create(int Width, int Height, const std::string &title)
Definition vkWindow.cpp:75
void Close() noexcept override
Closes the Window and frees resources.
Definition vkWindow.cpp:197
void Update() noexcept override
Poll events.
Definition vkWindow.cpp:190
void * GetSurface() const noexcept
Definition vkWindow.cpp:224
static void Log(const char *message)
Definition Logger.h:104
static void Fatal(fmt::format_string< Args... > message, Args &&... args)
Definition Logger.h:147
Screen-space Dimensions. The Depth Values are used by the pipelines.
Definition Window.h:16
std::vector< VkSurfaceFormatKHR > formats
Definition vkWindow.cpp:18
VkSurfaceCapabilitiesKHR capabilities
Definition vkWindow.cpp:17
std::vector< VkPresentModeKHR > presentModes
Definition vkWindow.cpp:19
VkSurfaceFormatKHR ChooseSwapSurfaceFormat(const std::vector< VkSurfaceFormatKHR > &availableFormats) noexcept
Definition vkWindow.cpp:23
VkExtent2D ChooseSwapExtent(GLFWwindow *window, const VkSurfaceCapabilitiesKHR &capabilities)
Definition vkWindow.cpp:45
VkPresentModeKHR ChooseSwapPresentMode(const std::vector< VkPresentModeKHR > &availablePresentModes)
Definition vkWindow.cpp:34