HoviTron Video Pipeline
WindowGLFW.cpp
1/* ----------------------
2* Copyright 2023 Université Libre de Bruxelles(ULB), Universidad Politécnica de Madrid(UPM), CREAL, Deutsches Zentrum für Luft - und Raumfahrt(DLR)
3
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at < http://www.apache.org/licenses/LICENSE-2.0>
7
8* Unless required by applicable law or agreed to in writing, software
9* distributed under the License is distributed on an "AS IS" BASIS,
10* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11* See the License for the specific language governing permissionsand
12* limitations under the License.
13---------------------- */
14
15
16
17#include"WindowGLFW.h"
20#include <iostream>
21#include <sstream>
22#include "SwapchainCommon.h"
23
25{
26 glfwInit();
27 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
28 glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
29 glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
30 glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
31
32 //auto monitor = glfwGetPrimaryMonitor();
33 window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
35
36 glfwSetWindowUserPointer(window, this);
37
38 //glfw is a C API and if we want to redirect the call to a member function some tricks have to be used
39 //fore more info check this: https://stackoverflow.com/questions/7676971/pointing-to-a-function-that-is-a-class-member-glfw-setkeycallback
40 auto func = [](GLFWwindow* w, int, int)
41 {
42 static_cast<WindowGLFW*>(glfwGetWindowUserPointer(w))->framebufferResizeCallback();
43 };
44
45 glfwSetFramebufferSizeCallback(window, func);
46
47 auto funKey = [](GLFWwindow* w, int key, int scancode, int action, int mods) {
48 static_cast<WindowGLFW*>(glfwGetWindowUserPointer(w))->inputKeyCallback(w, key, scancode, action, mods);
49 };
50 glfwSetKeyCallback(window, funKey);
51
52 currentTranslation = { 0,0,0 };
53 currentRotation = { 0,0,0 };
54 initialised = true;
55
56}
57
59{
61 swapchains.resize(1);
62 swapchains[0] = std::unique_ptr<SwapchainAbstract>(new SwapchainCommon(surface,this,wrapper));
63 renderingFinnishedSemaphore.resize(swapchains[0]->getAttachmentSize());
64 vk::SemaphoreCreateInfo semaphoreInfo;
65 for (auto& sem : renderingFinnishedSemaphore) {
66 sem = wrapper->context.device.createSemaphore(semaphoreInfo);
67 }
68}
69
71{
72 glfwDestroyWindow(window);
73 glfwTerminate();
74}
75
77{
78 for (auto& sem : renderingFinnishedSemaphore) {
79 wrapper->context.device.destroySemaphore(sem);
80 }
81 for (int i = 0; i < swapchains.size(); i++) {
82 swapchains[i]->cleanup();
83 }
84 VkInstance instance = static_cast<VkInstance>(wrapper->context.instance);
85 vkDestroySurfaceKHR(instance, surface, nullptr);
86}
87
89{
91 while (!glfwWindowShouldClose(window)) {
92
93 glfwPollEvents();
94
95#ifdef HVT_UDP_CONTROL
96 mutex.lock();
97#endif
99#ifdef HVT_UDP_CONTROL
100 mutex.unlock();
101#endif
102
103
104 for (int i = 0; i < swapchains.size(); i++) {
105 uint32_t index;
106 std::optional<vk::Semaphore> imageAvailableSemaphore;
107 try{
108 std::tie(index, imageAvailableSemaphore) = swapchains[i]->acquireImage();
109 std::tuple <int, uint32_t> idImage(i, index);
110 std::vector<vk::Semaphore> semaphores;
111 std::vector<vk::Semaphore> signalSemaphore = { renderingFinnishedSemaphore[index] };
112 if (imageAvailableSemaphore.has_value()) {
113 semaphores.push_back(imageAvailableSemaphore.value());
114 }
115 vulkanDrawing->submitDrawCall(idImage, semaphores , signalSemaphore);
116 swapchains[i]->presentImage(index, renderingFinnishedSemaphore[index]);
117 }
118 catch (vk::OutOfDateKHRError) {
119 std::cout << "test " << "ahhh" << std::endl;
121 }
122 }
123 }
124}
125
127{
128 if (glfwCreateWindowSurface(wrapper->context.instance, window, nullptr, &surface) != VK_SUCCESS) {
129 throw std::runtime_error("failed to create window surface!");
130 }
131}
132
133std::vector<const char*> WindowGLFW::getRequiredExtensions()
134{
135 uint32_t glfwExtensionCount = 0;
136 const char** glfwExtensions;
137 glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
138
139 std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
140
142 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
143 }
144 return extensions;
145}
146
147VkBool32 WindowGLFW::isDeviceSupportingSufaceKHR(VkPhysicalDevice device, int i)
148{
149 VkBool32 presentSupport = false;
150 vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
151 return presentSupport;
152}
153
155{
156 return deviceExtensions;
157}
158
160{
162 details.capabilities = device.getSurfaceCapabilitiesKHR(surface);
163 //LOGI("capabilities: width %u ,height: %u",details.capabilities.currentExtent.width,details.capabilities.currentExtent.height);
164 details.formats = device.getSurfaceFormatsKHR(surface);
165 //xrEnumerateSwapchainFormats ?
166 details.presentModes = device.getSurfacePresentModesKHR(surface);
167 return details;
168}
169
171{
172 int width = 0, height = 0;
173 glfwGetFramebufferSize(window, &width, &height);
174 while (width == 0 || height == 0) {
175 glfwGetFramebufferSize(window, &width, &height);
176 glfwWaitEvents();
177 }
178}
179
180void WindowGLFW::getFrameBufferSize(int* w, int* h, vk::PhysicalDevice& pDevice)
181{
182 glfwGetFramebufferSize(window, w, h);
183}
184
186{
187 return true;
188}
189
190
191
193{
194 PRINT("\n \n----------------------------------------------");
195 std::cout << "To navigate in the scene use:" << std::endl;
196 std::cout << "----Translation----" << std::endl;
197 std::cout << "Up: " << "Up arrow" << "\t" << "Down: " << "Down arrow" << std::endl;
198 std::cout << "Left: " << "Left arrow" << "\t" << "Right: " << "Right arrow" << std::endl;
199 std::cout << "Forward: " << "Page Up" << "\t" << "Backward:" << "Page Down" << std::endl;
200 std::cout << "----Rotation-------" << std::endl;
201 const char* upRotKey = glfwGetKeyName(GLFW_KEY_W, 0);
202 const char* downRotKey = glfwGetKeyName(GLFW_KEY_S, 0);
203 std::cout << "Pitch Up: " << upRotKey << "\t" << "Pitch Down: " << downRotKey << std::endl;
204 const char* leftRotKey = glfwGetKeyName(GLFW_KEY_A, 0);
205 const char* rightRotKey = glfwGetKeyName(GLFW_KEY_D, 0);
206 std::cout << "Yaw Left: " << leftRotKey << "\t" << "Yaw Right: " << rightRotKey << std::endl;
207 const char* rollKey = glfwGetKeyName(GLFW_KEY_Q, 0);
208 const char* rollClockKey = glfwGetKeyName(GLFW_KEY_E, 0);
209 std::cout << "Roll conterclockwise: " << rollKey << "\t" << "roll clockwise: " << rollClockKey << std::endl;
210 const char* reset = glfwGetKeyName(GLFW_KEY_0, 0);
211 PRINT("Reset the view: %s (0)", reset);
212 std::cout << "-------------\n" << std::endl;
213 std::cout << "To exit press: ESC" << std::endl;
214 std::cout << "-------------\n" << std::endl;
215 std::cout << "To enter/exit manual calibration mode: F1" << std::endl;
216 std::cout << "Save correction calibration to disk: F2" << std::endl;
217 std::cout << "Load correction calibration to disk: F3" << std::endl;
218 const char* oneCam = glfwGetKeyName(GLFW_KEY_1, 0);
219 const char* twoCam = glfwGetKeyName(GLFW_KEY_2, 0);
220 const char* threeCam = glfwGetKeyName(GLFW_KEY_3, 0);
221 PRINT("---Select a camera---\n camera 1, 2, 3 : %s (1), %s (2), %s (3) ", oneCam, twoCam, threeCam);
222 const char* refCam = glfwGetKeyName(GLFW_KEY_GRAVE_ACCENT, 0);
223 PRINT("Reference camera (camera 0): %s",refCam);
224 PRINT("--Adjust rotation--\n %s %s (roll), %s %s (yaw), %s %s (pitch)",
225 rollKey,rollClockKey,leftRotKey,rightRotKey,upRotKey,downRotKey);
226
227 const char* t1 = glfwGetKeyName(GLFW_KEY_I, 0);
228 const char* t1b = glfwGetKeyName(GLFW_KEY_K, 0);
229 const char* t2 = glfwGetKeyName(GLFW_KEY_J, 0);
230 const char* t2b = glfwGetKeyName(GLFW_KEY_L, 0);
231 const char* t3 = glfwGetKeyName(GLFW_KEY_U, 0);
232 const char* t3b = glfwGetKeyName(GLFW_KEY_O, 0);
233 PRINT("--Adjust translation--\n %s %s (left/right), %s %s (up/down), %s %s (forward/backward)", t2,t2b,t1,t1b,t3,t3b);
234
235 const char* p1 = glfwGetKeyName(GLFW_KEY_T, 0);
236 const char* p1b = glfwGetKeyName(GLFW_KEY_G, 0);
237 const char* p2 = glfwGetKeyName(GLFW_KEY_Y, 0);
238 const char* p2b = glfwGetKeyName(GLFW_KEY_H, 0);
239 PRINT("--Adjust principal pt--\n %s %s (x axis), %s %s (y axis)", p1, p1b, p2, p2b);
240
241 const char* f1 = glfwGetKeyName(GLFW_KEY_Z, 0);
242 const char* f1b = glfwGetKeyName(GLFW_KEY_X, 0);
243 const char* f2 = glfwGetKeyName(GLFW_KEY_C, 0);
244 const char* f2b = glfwGetKeyName(GLFW_KEY_V, 0);
245 PRINT("--Adjust focal--\n %s %s (x axis), %s %s (y axis)", f1, f1b, f2, f2b);
246
247
248 const char* plusStep = glfwGetKeyName(GLFW_KEY_EQUAL, 0);
249 const char* minusStep = glfwGetKeyName(GLFW_KEY_MINUS, 0);
250 PRINT("---To adjust the step---\n multiply by 2: %s \t divide by 2: %s ",plusStep,minusStep);
251 PRINT("Print current correction: space bar");
252 PRINT("Enable/Disable selected camera: F4");
253 PRINT("----------------------------------------------\n\n");
254}
255
256void WindowGLFW::inputKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mode)
257{
258 const float delta = 0.004;
259 const float deltaRot = 0.2;
260 const int inputAction = GLFW_REPEAT;
261
262 if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
263 glfwSetWindowShouldClose(window, GL_TRUE);
264 }
265
266 if (key == GLFW_KEY_F1 && action == GLFW_PRESS) {
268 if (qualibrationMode) {
269 std::cout << "Qualibration Mode is turn ON" << std::endl;
270 }
271 else {
272 std::cout << "Qualibration Mode is turn OFF" << std::endl;
273 }
274 }
275
276 if (key == GLFW_KEY_F2 && action == GLFW_PRESS) {
278 }
279 if (key == GLFW_KEY_F3 && action == GLFW_PRESS) {
281 }
282
283 if (!qualibrationMode) {
284 if (key == GLFW_KEY_LEFT && action == inputAction) {
285 //std::cout << "input Left" << std::endl;
286 currentTranslation[0] -= delta;
287 }
288 else if (key == GLFW_KEY_RIGHT && action == inputAction) {
289 //std::cout << "input Right" << std::endl;
290 currentTranslation[0] += delta;
291 }
292 else if (key == GLFW_KEY_UP && action == inputAction) {
293 //std::cout << "input Up" << std::endl;
294 currentTranslation[1] += delta;
295 }
296 else if (key == GLFW_KEY_DOWN && action == inputAction) {
297 //std::cout << "input Down" << std::endl;
298 currentTranslation[1] -= delta;
299 }
300 else if (key == GLFW_KEY_PAGE_UP && action == inputAction) {
301 //std::cout << "input Down" << std::endl;
302 currentTranslation[2] -= delta;
303 }
304 else if (key == GLFW_KEY_PAGE_DOWN && action == inputAction) {
305 //std::cout << "input Down" << std::endl;
306 currentTranslation[2] += delta;
307 }
308 else if (key == GLFW_KEY_Q && action == inputAction) {
309 //Roll
310 currentRotation[2] -= deltaRot;
311 }
312 else if (key == GLFW_KEY_E && action == inputAction) {
313 //Roll
314 currentRotation[2] += deltaRot;
315 }
316 else if (key == GLFW_KEY_W && action == inputAction) {
317 //Pitch
318 currentRotation[0] += deltaRot;
319 }
320 else if (key == GLFW_KEY_S && action == inputAction) {
321 //Pitch
322 currentRotation[0] -= deltaRot;
323 }
324 else if (key == GLFW_KEY_A && action == inputAction) {
325 //Yall
326 currentRotation[1] += deltaRot;
327 }
328 else if (key == GLFW_KEY_D && action == inputAction) {
329 //Yall
330 currentRotation[1] -= deltaRot;
331 }
332 else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
333 {
334 std::cout << "current rotation (Openxr Space): " << glm::to_string(currentRotation) << std::endl;
335 std::cout << "current translation (Openxr Space): " << glm::to_string(currentTranslation) << std::endl << std::endl;
336 }
337 else if ((key == GLFW_KEY_0 || key == GLFW_KEY_KP_0) && action == GLFW_PRESS) {
338 resetOrigin();
339 }
340 }
341
342 else {
343 glm::vec3 deltaQualR = {0,0,0};
344 glm::vec3 deltaQualT = { 0,0,0 };
345 glm::vec2 deltaQualF = { 0,0 };
346 glm::vec2 deltaQualP = { 0,0 };
347
348 if (key == GLFW_KEY_F4 && action == GLFW_PRESS) {
349 if (selectedCamera == -1) {
350 std::cout << "No camera selected" << std::endl;
351 }
352 else {
354 std::cout << "Camera " << selectedCamera << " is now " << (wrapper->getCameraActivation()[selectedCamera] ? "enabled" : "disabled") << std::endl;
355 }
356 }
357 else if (key == GLFW_KEY_GRAVE_ACCENT && action == GLFW_PRESS) {
358 std::cout << "select Camera 0" << std::endl;
359 selectedCamera = 0;
360 }
361 else if (key == GLFW_KEY_1 && action == GLFW_PRESS) {
362 std::cout << "select Camera 1" << std::endl;
363 selectedCamera = 1;
364 }
365 else if (key == GLFW_KEY_2 && action == GLFW_PRESS) {
366 std::cout << "select Camera 2" << std::endl;
367 selectedCamera = 2;
368 }
369 else if (key == GLFW_KEY_3 && action == GLFW_PRESS) {
370 std::cout << "select Camera 3" << std::endl;
371 selectedCamera = 3;
372 }
373 else if (key == GLFW_KEY_EQUAL && action == GLFW_PRESS) {
374 deltaValueCalibration *= 2;
375 }
376 else if (key == GLFW_KEY_MINUS && action == GLFW_PRESS) {
377 deltaValueCalibration /= 2;
378 }
379 else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS){
380 PRINT("Current step %f", deltaValueCalibration);
381 auto corrections = wrapper->getCorrectionVectorRotation();
382 for (int i = 0; i < corrections.size(); i++) {
383 std::cout << "Correction for camera " << i << " (OMAF space) : " << glm::to_string(corrections[i]) << std::endl;
384 }
385 std::cout << std::endl;
386 }
387 else if (action == GLFW_PRESS) {
388 switch (key) {
389 case GLFW_KEY_Q:
390 //Roll
391 deltaQualR[2] -= deltaValueCalibration;
392 break;
393 case GLFW_KEY_E:
394 //Roll
395 deltaQualR[2] += deltaValueCalibration;
396 break;
397 case GLFW_KEY_W:
398 //Pitch
399 deltaQualR[1] -= deltaValueCalibration;
400 break;
401 case GLFW_KEY_S:
402 //Pitch
403 deltaQualR[1] += deltaValueCalibration;
404 break;
405 case GLFW_KEY_A:
406 //Yall
407 deltaQualR[0] += deltaValueCalibration;
408 break;
409 case GLFW_KEY_D:
410 //Yall
411 deltaQualR[0] -= deltaValueCalibration;
412 break;
413 //Translation -------------
414 case GLFW_KEY_K:
415 //down
416 deltaQualT[2] -= 0.1 * deltaValueCalibration;
417 break;
418 case GLFW_KEY_I:
419 //up
420 deltaQualT[2] += 0.1 * deltaValueCalibration;
421 break;
422 case GLFW_KEY_J:
423 //left
424 deltaQualT[1] += 0.1 * deltaValueCalibration;
425 break;
426 case GLFW_KEY_L:
427 //right
428 deltaQualT[1] -= 0.1 * deltaValueCalibration;
429 break;
430 case GLFW_KEY_U:
431 //
432 deltaQualT[0] += 0.1 * deltaValueCalibration;
433 break;
434 case GLFW_KEY_O:
435 //
436 deltaQualT[0] -= 0.1 *deltaValueCalibration;
437 break;
438
439 //principalPt
440 case GLFW_KEY_T:
441 //x
442 deltaQualP[0] += 10 * deltaValueCalibration;
443 break;
444 case GLFW_KEY_G:
445 //x
446 deltaQualP[0] -= 10 * deltaValueCalibration;
447 break;
448 case GLFW_KEY_Y:
449 //y
450 deltaQualP[1] += 10 * deltaValueCalibration;
451 break;
452 case GLFW_KEY_H:
453 //y
454 deltaQualP[1] -= 10 * deltaValueCalibration;
455 break;
456
457 //focals
458
459 case GLFW_KEY_Z :
460 //x
461 deltaQualF[0] += 20 * deltaValueCalibration;
462 break;
463 case GLFW_KEY_X:
464 //x
465 deltaQualF[0] -= 20 * deltaValueCalibration;
466 break;
467 case GLFW_KEY_C:
468 //y
469 deltaQualF[1] += 20 * deltaValueCalibration;
470 break;
471 case GLFW_KEY_V:
472 //y
473 deltaQualF[1] -= 20 * deltaValueCalibration;
474 break;
475 }
476
477 auto acti = wrapper->getCameraActivation();
478 if (selectedCamera != -1 && selectedCamera < acti.size() && acti[selectedCamera]) {
479 if (deltaQualR.x != 0 || deltaQualR.y != 0 || deltaQualR.z != 0) {
481 }
482 else if (deltaQualT.x != 0 || deltaQualT.y != 0 || deltaQualT.z != 0) {
484 }
485 else if (deltaQualP.x != 0 || deltaQualP.y != 0 ) {
487 }
488 else if (deltaQualF.x != 0 || deltaQualF.y != 0) {
490 }
491 }
492 }
493 }
494}
495
496
497
499{
501}
502
504{
505#ifdef HVT_UDP_CONTROL
506 mutex.lock();
507#endif
508 currentTranslation = { 0,0,0 };
509 currentRotation = { 0,0,0 };
510#ifdef HVT_UDP_CONTROL
511 mutex.unlock();
512#endif
513}
514
Encapsulate the vkSwapchainKHR object and the operations linked to it. Inherit from SwapchainAbstract...
File that contain the VulkanContext class to manage Vulkan Instance, Physical device,...
file that contains the VulkanWrapper class that manages the classes related to Vulkan code and ease t...
Contains the class that represents a window created with the GLFW library.
Class that encapsulate a vkSwapchainHHR object and the methods linked to it.
vk::Instance instance
Definition: VulkanContext.h:83
vk::Device device
Definition: VulkanContext.h:87
The class that manages the drawing operation (manage and record command buffers).
Definition: VulkanDrawing.h:46
vk::Fence submitDrawCall(std::tuple< int, uint32_t > idImage, const std::vector< vk::Semaphore > &imageAvailableSemaphores, std::vector< vk::Semaphore > &signalSemaphore, uint32_t depthIndex=UINT_MAX)
void loadConfigurationsFromDisk()
void setCorrectionTranslation(int camId, glm::vec3 translationCorrection)
void recreateSwapChain()
void saveConfigurationsToDisk()
bool framebufferResized
void setCorrectionFocal(int camId, glm::vec2 focals)
void setCorrectionPrincipalPt(int camId, glm::vec2 principalPt)
VulkanContext context
const std::vector< glm::vec3 > getCorrectionVectorRotation()
void updateSpaceTransform(glm::vec3 translation, glm::vec3 rotation)
std::vector< bool > getCameraActivation()
void toggleCamera(int i)
void setCorrectionRotation(int camId, glm::vec3 rotationCorrection)
glm::vec3 currentTranslation
glm::vec3 currentRotation
bool separateFromWindowDim
std::vector< std::unique_ptr< SwapchainAbstract > > swapchains
VulkanWrapper * wrapper
const bool enableValidationLayers
The class that represents a window created with the GLFW library.
Definition: WindowGLFW.h:37
void framebufferResizeCallback()
Definition: WindowGLFW.cpp:498
void checkForCorrectSize() override
Definition: WindowGLFW.cpp:170
void getFrameBufferSize(int *w, int *h, vk::PhysicalDevice &pDevice) override
Definition: WindowGLFW.cpp:180
VkBool32 isDeviceSupportingSufaceKHR(VkPhysicalDevice device, int i) override
Definition: WindowGLFW.cpp:147
void createSurface() override
Definition: WindowGLFW.cpp:126
std::vector< const char * > getRequiredExtensions() override
Definition: WindowGLFW.cpp:133
void mainLoop(VulkanDrawing *vulkanDrawing) override
Definition: WindowGLFW.cpp:88
void inputKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mode)
Definition: WindowGLFW.cpp:256
void continueInit() override
Definition: WindowGLFW.cpp:58
void cleanUpSurface() override
Definition: WindowGLFW.cpp:76
bool isSynchroWithSemaphore() override
Definition: WindowGLFW.cpp:185
void cleanUp() override
Definition: WindowGLFW.cpp:70
std::vector< const char * > getRequiredDeviceExtensions() override
Definition: WindowGLFW.cpp:154
void printInputCommands()
Definition: WindowGLFW.cpp:192
SwapChainSupportDetails querySwapChainSupport(vk::PhysicalDevice device) override
Definition: WindowGLFW.cpp:159
void initWindow() override
Definition: WindowGLFW.cpp:24
void resetOrigin() override
Definition: WindowGLFW.cpp:503
Struct that contains the capability for the sapchain, the formats and the present mode supported.
Definition: commonVulkan.h:87
vk::SurfaceCapabilitiesKHR capabilities
Definition: commonVulkan.h:89
std::vector< vk::SurfaceFormatKHR > formats
Definition: commonVulkan.h:91
std::vector< vk::PresentModeKHR > presentModes
Definition: commonVulkan.h:93