33#define _USE_MATH_DEFINES
52std::chrono::milliseconds totalChrono{0};
56static const char* kTAG =
"window";
58 ((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
60 ((void)__android_log_print(ANDROID_LOG_WARN, kTAG, __VA_ARGS__))
62 ((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__))
64void handle_cmd_w(android_app* app, int32_t cmd) {
66 case APP_CMD_INIT_WINDOW:
71 case APP_CMD_TERM_WINDOW:
76 case APP_CMD_WINDOW_RESIZED:
80 case APP_CMD_INPUT_CHANGED:
81 LOGI(
"Got an input !");
87OpenXRWindow::OpenXRWindow(android_app* appAndroid)
89 this->appAndroid = appAndroid;
94glm::mat3x3 rotMatFromEuler(glm::vec3 & r) {
105 glm::mat3x3 res = { cos(r[1])+cos(r[2]),sin(r[2]),-sin(r[1]) , -sin(r[2]),cos(r[0]) + cos(r[2]),sin(r[0]) , sin(r[1]),-sin(r[0]),cos(r[0]) + cos(r[1]) };
118 if (mirrorActivated) {
120 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
121 glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
122 glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
123 glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
124 window = glfwCreateWindow(width, height,
"Mirror",
nullptr,
nullptr);
125 glfwSetWindowUserPointer(window,
this);
126 auto funKey = [](GLFWwindow* w,
int key,
int scancode,
int action,
int mods) {
127 static_cast<WindowOpenXR*
>(glfwGetWindowUserPointer(w))->inputKeyCallback(w, key, scancode, action, mods);
129 glfwSetKeyCallback(window, funKey);
139 graphicsBinding =
wrapper->getGraphicsBinding();
140 XrSessionCreateInfo createInfoSession{ XR_TYPE_SESSION_CREATE_INFO };
141 createInfoSession.next = &graphicsBinding;
142 createInfoSession.systemId = systemId;
144 PRINT(
"Before session creation");
145 CHECK_XRCMD(xrCreateSession(xrInstance, &createInfoSession, &xrSession));
146 PRINT(
"Session created !");
148 LogReferenceSpaces();
155 PRINT(
"Space created!");
160 if (mirrorActivated) {
161 createMirrorSwapchain();
182 for (XrSpace visualizedSpace : xrVisualizedSpaces) {
183 xrDestroySpace(visualizedSpace);
186 if (refSpace != XR_NULL_HANDLE) {
187 xrDestroySpace(refSpace);
190 xrDestroySession(xrSession);
194 xrDestroyInstance(xrInstance);
197 appAndroid->activity->vm->DetachCurrentThread();
200 if (mirrorActivated) {
201 glfwDestroyWindow(window);
207void WindowOpenXR::cleanUpMirrorSwapchain() {
208 if (mirrorActivated) {
209 for (
auto sem : mirrorAvailableSemaphore) {
212 for (
auto sem : mirrorFinnishedSemaphore) {
215 mirrorImages.clear();
216 mirrorAvailableSemaphore.clear();
217 mirrorFinnishedSemaphore.clear();
223void WindowOpenXR::recreateMirror() {
224 int width = 0, height = 0;
225 glfwGetFramebufferSize(window, &width, &height);
226 if (! (width == 0 || height == 0)) {
228 cleanUpMirrorSwapchain();
229 createMirrorSwapchain();
235 if (mirrorActivated) {
236 cleanUpMirrorSwapchain();
238 vkDestroySurfaceKHR(instance, surface,
nullptr);
247 bool requestRestart =
false;
248 while (!requestRestart) {
250 if (mirrorActivated) {
252 if (glfwWindowShouldClose(window)) {
253 xrRequestExitSession(xrSession);
257 bool exitRenderLoop =
false;
259 if (exitRenderLoop) {
263 if (pauseRendering) {
264 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
265 pauseRendering =
false;
268 renderFrame(vulkanDrawing);
273 std::this_thread::sleep_for(std::chrono::milliseconds(250));
284 if (mirrorActivated) {
285 if (
auto res = glfwCreateWindowSurface(
wrapper->
context.
instance, window,
nullptr, &surface); res != VK_SUCCESS) {
286 throw std::runtime_error(
"failed to create window surface! (" + std::to_string(res) +
")");
294 auto extensions = instanceExtensions;
297 PFN_xrGetVulkanInstanceExtensionsKHR pfnGetVulkanInstanceExtensionsKHR =
nullptr;
298 CHECK_XRCMD(xrGetInstanceProcAddr(xrInstance,
"xrGetVulkanInstanceExtensionsKHR",
299 reinterpret_cast<PFN_xrVoidFunction*
>(&pfnGetVulkanInstanceExtensionsKHR)));
301 uint32_t extensionNamesSize = 0;
302 CHECK_XRCMD(pfnGetVulkanInstanceExtensionsKHR(xrInstance, systemId, 0, &extensionNamesSize,
nullptr));
304 extensionNames = std::vector<char>(extensionNamesSize);
305 CHECK_XRCMD(pfnGetVulkanInstanceExtensionsKHR(xrInstance, systemId, extensionNamesSize, &extensionNamesSize,
306 &extensionNames[0]));
309 std::vector<const char*> requestedExt;
311 for (
int i = 0; i < extensionNames.size(); i++) {
312 extensions.push_back(&extensionNames[i]);
313 while (i < extensionNames.size()) {
314 if (extensionNames[i] ==
' ') {
315 extensionNames[i] =
'\0';
323 if (mirrorActivated) {
324 uint32_t glfwExtensionCount = 0;
325 const char** glfwExtensions;
326 glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
327 std::vector<const char*> mirrorExtensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
329 for (
auto glfwext : mirrorExtensions) {
331 for (
auto ext : extensions) {
332 if (std::strcmp(glfwext, ext) == 0) {
338 extensions.push_back(glfwext);
344 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
347 extensions.push_back(
"VK_EXT_debug_report");
348 extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
355 if (!mirrorActivated) {
359 VkBool32 presentSupport =
false;
360 vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
361 return presentSupport;
368 PFN_xrGetVulkanDeviceExtensionsKHR pfnGetVulkanDeviceExtensionsKHR =
nullptr;
369 CHECK_XRCMD(xrGetInstanceProcAddr(xrInstance,
"xrGetVulkanDeviceExtensionsKHR",
370 reinterpret_cast<PFN_xrVoidFunction*
>(&pfnGetVulkanDeviceExtensionsKHR)));
372 uint32_t deviceExtensionNamesSize = 0;
373 CHECK_XRCMD(pfnGetVulkanDeviceExtensionsKHR(xrInstance, systemId, 0, &deviceExtensionNamesSize,
nullptr));
374 deviceExtension = std::vector<char>(deviceExtensionNamesSize);
375 CHECK_XRCMD(pfnGetVulkanDeviceExtensionsKHR(xrInstance, systemId, deviceExtensionNamesSize,
376 &deviceExtensionNamesSize, &deviceExtension[0]));
378 std::vector<const char*> extensions = additionalDeviceExtensions;
379 for (
int i = 0; i < deviceExtension.size(); i++) {
380 extensions.push_back(&deviceExtension[i]);
381 while (i < deviceExtension.size()) {
382 if (deviceExtension[i] ==
' ') {
383 deviceExtension[i] =
'\0';
403 throw std::runtime_error(
"not autorised with open xr implementation");
432 auto res = std::vector<vk::Image>();
433 if (mirrorActivated && view == 0 && elem < mirrorSwapchainSize && mirrorShouldRender) {
434 res.push_back(mirrorImages[elem]);
441 auto res = std::vector<vk::Extent2D>();
442 if (mirrorActivated && view == 0 && elem < mirrorSwapchainSize && mirrorShouldRender) {
443 res.push_back(vk::Extent2D{ width,height });
450 auto res = std::vector<vk::Semaphore>();
451 if (mirrorActivated && view == 0 && elem < mirrorSwapchainSize) {
452 res.push_back(mirrorAvailableSemaphore[elem]);
459 auto res = std::vector<vk::Semaphore>();
460 if (mirrorActivated && view == 0 && elem < mirrorSwapchainSize) {
461 res.push_back(mirrorFinnishedSemaphore[elem]);
466 void WindowOpenXR::initOpenXR() {
468 PFN_xrInitializeLoaderKHR initializeLoader =
nullptr;
470 xrGetInstanceProcAddr(XR_NULL_HANDLE,
"xrInitializeLoaderKHR", (PFN_xrVoidFunction*)(&initializeLoader)))) {
471 XrLoaderInitInfoAndroidKHR loaderInitInfoAndroid;
472 memset(&loaderInitInfoAndroid, 0,
sizeof(loaderInitInfoAndroid));
473 loaderInitInfoAndroid.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR;
474 loaderInitInfoAndroid.next = NULL;
475 loaderInitInfoAndroid.applicationVM = appAndroid->activity->vm;
476 loaderInitInfoAndroid.applicationContext = appAndroid->activity->clazz;
477 initializeLoader((
const XrLoaderInitInfoBaseHeaderKHR*)&loaderInitInfoAndroid);
481 LOGI(
"This is a failure");
487 XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid = { XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR };
488 instanceCreateInfoAndroid.applicationVM = appAndroid->activity->vm;
489 instanceCreateInfoAndroid.applicationActivity = appAndroid->activity->clazz;
491 XrInstanceCreateInfo createInfo{ XR_TYPE_INSTANCE_CREATE_INFO };
492 std::vector<const char*> extensions = { XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME, XR_KHR_VULKAN_ENABLE_EXTENSION_NAME };
495 XrInstanceCreateInfo createInfo{ XR_TYPE_INSTANCE_CREATE_INFO };
496 std::vector<const char*> extensions = { XR_KHR_VULKAN_ENABLE_EXTENSION_NAME };
497 if (depthExtensionAvailable) {
498 PRINT(
"Depth extension is now activated !\n");
499 extensions.push_back(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME);
501 if (quadViewExtensionAvailable) {
502 PRINT(
"VARJO quad view extension is now activated !\n");
503 extensions.push_back(XR_VARJO_QUAD_VIEWS_EXTENSION_NAME);
509 createInfo.next = (XrBaseInStructure*)&instanceCreateInfoAndroid;
511 createInfo.next =
nullptr;
514 createInfo.enabledExtensionCount = (uint32_t)extensions.size();
515 createInfo.enabledExtensionNames = extensions.data();
516 strcpy(createInfo.applicationInfo.applicationName,
"RVSVulkan_OpenXR");
517 createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
519 std::vector<const char*> layers = {};
521 layers.push_back(
"XR_LUNARG_core_validation");
524 createInfo.enabledApiLayerCount = (uint32_t)layers.size();
525 createInfo.enabledApiLayerNames = layers.data();
526 if (XR_SUCCEEDED(xrCreateInstance(&createInfo, &xrInstance))) {
530 PRINT(
"Error Instance");
533 XrSystemGetInfo systemInfo{ XR_TYPE_SYSTEM_GET_INFO };
534 systemInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
535 CHECK_XRCMD(xrGetSystem(xrInstance, &systemInfo, &systemId));
536 PRINT(
"%s", Fmt(
"Using system %d for form factor %s", systemId, to_string(systemInfo.formFactor)).c_str());
537 CHECK(xrInstance != XR_NULL_HANDLE);
538 CHECK(systemId != XR_NULL_SYSTEM_ID);
541 selectViewConfiguration();
543 logViewConfiguration(xrInstance, systemId);
545 XrGraphicsRequirementsVulkan2KHR graphicsRequirements{ XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR };
546 CHECK_XRCMD(GetVulkanGraphicsRequirements2KHR(xrInstance, systemId, &graphicsRequirements));
549 vkEnumerateInstanceLayerProperties(&layerCount,
nullptr);
559 void WindowOpenXR::LogReferenceSpaces() {
560 CHECK(xrSession != XR_NULL_HANDLE);
563 CHECK_XRCMD(xrEnumerateReferenceSpaces(xrSession, 0, &spaceCount,
nullptr));
564 std::vector<XrReferenceSpaceType> spaces(spaceCount);
565 CHECK_XRCMD(xrEnumerateReferenceSpaces(xrSession, spaceCount, &spaceCount, spaces.data()));
567 PRINT(
"%s", Fmt(
"Available reference spaces: %d", spaceCount).c_str());
568 for (XrReferenceSpaceType space : spaces) {
569 PRINT(
"%s", Fmt(
" Name: %s", to_string(space)).c_str());
574 void WindowOpenXR::CreateSpaces() {
577 CHECK(xrSession != XR_NULL_HANDLE);
583 XrReferenceSpaceCreateInfo referenceSpaceCreateInfo{ XR_TYPE_REFERENCE_SPACE_CREATE_INFO };
585 identity.orientation.w = 1;
586 referenceSpaceCreateInfo.poseInReferenceSpace = identity;
587 referenceSpaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
590 XrResult res = xrCreateReferenceSpace(xrSession, &referenceSpaceCreateInfo, &space);
591 if (XR_SUCCEEDED(res)) {
592 xrVisualizedSpaces.push_back(space);
595 PRINT(
"%s", Fmt(
"Failed to create reference space %s with error %d",
"Local", res).c_str());
599 XrResult res2 = xrCreateReferenceSpace(xrSession, &referenceSpaceCreateInfo, &refSpace);
600 if (!XR_SUCCEEDED(res2)) {
601 PRINT(
"%s", Fmt(
"Failed to create reference space %s with error %d",
"Local", res2).c_str());
606 void WindowOpenXR::logViewConfiguration(XrInstance & xrInstance, XrSystemId & systemId) {
607 uint32_t viewConfigTypeCount;
608 CHECK_XRCMD(xrEnumerateViewConfigurations(xrInstance, systemId, 0, &viewConfigTypeCount,
nullptr));
609 std::vector<XrViewConfigurationType> viewConfigTypes(viewConfigTypeCount);
610 CHECK_XRCMD(xrEnumerateViewConfigurations(xrInstance, systemId, viewConfigTypeCount,
611 &viewConfigTypeCount,
612 viewConfigTypes.data()));
613 CHECK((uint32_t)viewConfigTypes.size() == viewConfigTypeCount);
614 PRINT(
"%s", Fmt(
"Available View Configuration Types: (%d)", viewConfigTypeCount).c_str());
615 for (XrViewConfigurationType viewConfigType : viewConfigTypes) {
616 PRINT(
"%s", Fmt(
" View Configuration Type: %s %s", to_string(viewConfigType),
617 viewConfigType == xrViewConfType ?
"(Selected)" :
"").c_str());
619 XrViewConfigurationProperties viewConfigProperties{ XR_TYPE_VIEW_CONFIGURATION_PROPERTIES };
620 CHECK_XRCMD(xrGetViewConfigurationProperties(xrInstance, systemId, viewConfigType,
621 &viewConfigProperties));
624 Fmt(
" View configuration FovMutable=%s",
625 viewConfigProperties.fovMutable == XR_TRUE ?
"True" :
"False").c_str());
629 xrEnumerateViewConfigurationViews(xrInstance, systemId, viewConfigType, 0, &viewCount,
632 std::vector<XrViewConfigurationView> views(viewCount, { XR_TYPE_VIEW_CONFIGURATION_VIEW });
634 xrEnumerateViewConfigurationViews(xrInstance, systemId, viewConfigType, viewCount,
635 &viewCount, views.data()));
637 for (uint32_t i = 0; i < views.size(); i++) {
638 const XrViewConfigurationView& view = views[i];
640 PRINT(
"%s", Fmt(
" View [%d]: Recommended Width=%d Height=%d SampleCount=%d", i,
641 view.recommendedImageRectWidth, view.recommendedImageRectHeight,
642 view.recommendedSwapchainSampleCount).c_str());
644 Fmt(
" View [%d]: Maximum Width=%d Height=%d SampleCount=%d", i,
645 view.maxImageRectWidth,
646 view.maxImageRectHeight, view.maxSwapchainSampleCount).c_str());
650 PRINT(
"%s", Fmt(
"Empty view configuration type").c_str());
654 CHECK_XRCMD(xrEnumerateEnvironmentBlendModes(xrInstance, systemId, viewConfigType, 0, &count,
nullptr));
657 PRINT(
"%s", Fmt(
"Available Environment Blend Mode count : (%d)", count).c_str());
659 std::vector<XrEnvironmentBlendMode> blendModes(count);
660 CHECK_XRCMD(xrEnumerateEnvironmentBlendModes(xrInstance, systemId, viewConfigType, count, &count, blendModes.data()));
662 bool blendModeFound =
false;
663 for (XrEnvironmentBlendMode mode : blendModes) {
664 const bool blendModeMatch = (mode == xrBlendMode);
665 PRINT(
"%s", Fmt(
"Environment Blend Mode (%s) : %s", to_string(mode), blendModeMatch ?
"(Selected)" :
"").c_str());
666 blendModeFound |= blendModeMatch;
668 CHECK(blendModeFound);
674 XrResult WindowOpenXR::GetVulkanGraphicsRequirements2KHR(XrInstance instance, XrSystemId systemId,
675 XrGraphicsRequirementsVulkan2KHR * graphicsRequirements) {
676 PFN_xrGetVulkanGraphicsRequirementsKHR pfnGetVulkanGraphicsRequirementsKHR =
nullptr;
677 CHECK_XRCMD(xrGetInstanceProcAddr(instance,
"xrGetVulkanGraphicsRequirementsKHR",
678 reinterpret_cast<PFN_xrVoidFunction*
>(&pfnGetVulkanGraphicsRequirementsKHR)));
680 XrGraphicsRequirementsVulkanKHR legacyRequirements{ XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR };
681 CHECK_XRCMD(pfnGetVulkanGraphicsRequirementsKHR(instance, systemId, &legacyRequirements));
683 graphicsRequirements->maxApiVersionSupported = legacyRequirements.maxApiVersionSupported;
684 graphicsRequirements->minApiVersionSupported = legacyRequirements.minApiVersionSupported;
689 XrResult GetVulkanGraphicsDevice2KHR(XrInstance instance,
const XrVulkanGraphicsDeviceGetInfoKHR * getInfo,
690 VkPhysicalDevice * vulkanPhysicalDevice) {
691 PFN_xrGetVulkanGraphicsDeviceKHR pfnGetVulkanGraphicsDeviceKHR =
nullptr;
692 CHECK_XRCMD(xrGetInstanceProcAddr(instance,
"xrGetVulkanGraphicsDeviceKHR",
693 reinterpret_cast<PFN_xrVoidFunction*
>(&pfnGetVulkanGraphicsDeviceKHR)));
695 if (getInfo->next !=
nullptr) {
696 return XR_ERROR_FEATURE_UNSUPPORTED;
699 CHECK_XRCMD(pfnGetVulkanGraphicsDeviceKHR(instance, getInfo->systemId, getInfo->vulkanInstance, vulkanPhysicalDevice));
706 XrVulkanGraphicsDeviceGetInfoKHR deviceGetInfo{ XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR };
707 deviceGetInfo.systemId = systemId;
708 deviceGetInfo.vulkanInstance = vkInstance;
709 CHECK_XRCMD(GetVulkanGraphicsDevice2KHR(xrInstance, &deviceGetInfo, physicalDevice));
712 XrResult CreateVulkanDeviceKHR(XrInstance instance,
const XrVulkanDeviceCreateInfoKHR * createInfo,
713 VkDevice * vulkanDevice, VkResult * vulkanResult) {
714 PFN_xrCreateVulkanDeviceKHR pfnCreateVulkanDeviceKHR =
nullptr;
715 CHECK_XRCMD(xrGetInstanceProcAddr(instance,
"xrCreateVulkanDeviceKHR",
716 reinterpret_cast<PFN_xrVoidFunction*
>(&pfnCreateVulkanDeviceKHR)));
718 return pfnCreateVulkanDeviceKHR(instance, createInfo, vulkanDevice, vulkanResult);
722 XrVulkanDeviceCreateInfoKHR deviceCreateInfo{ XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR };
723 deviceCreateInfo.systemId = systemId;
724 deviceCreateInfo.pfnGetInstanceProcAddr =
reinterpret_cast<PFN_vkGetInstanceProcAddr
>(&vkGetInstanceProcAddr);
725 deviceCreateInfo.vulkanCreateInfo = &info;
726 deviceCreateInfo.vulkanPhysicalDevice = physicalDevice;
727 deviceCreateInfo.vulkanAllocator =
nullptr;
729 CHECK_XRCMD(CreateVulkanDeviceKHR(xrInstance, &deviceCreateInfo, device, &err));
730 if (err != VK_SUCCESS) {
731 throw std::runtime_error(
"Error creating the device");
734 int64_t SelectColorSwapchainFormat(
const std::vector<int64_t>&runtimeFormats) {
736 constexpr int64_t SupportedColorSwapchainFormats[] = { VK_FORMAT_R8G8B8A8_UNORM };
739 auto swapchainFormatIt =
740 std::find_first_of(runtimeFormats.begin(), runtimeFormats.end(), std::begin(SupportedColorSwapchainFormats),
741 std::end(SupportedColorSwapchainFormats));
742 if (swapchainFormatIt == runtimeFormats.end()) {
743 THROW(
"No runtime swapchain format supported for color swapchain");
746 return *swapchainFormatIt;
748 int64_t SelectDepthSwapchainFormat(
const std::vector<int64_t>& runtimeFormats,
const std::vector<vk::Format>& supportedFormats) {
749 for(
auto f : supportedFormats) {
750 auto it = std::find_if(runtimeFormats.begin(), runtimeFormats.end(), [&](int64_t format){
751 return format == (int64_t)f;
753 if(it != runtimeFormats.end()){
757 THROW(
"No runtime swapchain format supported for depth swapchain");
759 void WindowOpenXR::CreateSwapChain() {
762 XrSystemProperties systemProperties{ XR_TYPE_SYSTEM_PROPERTIES };
763 CHECK_XRCMD(xrGetSystemProperties(xrInstance, systemId, &systemProperties));
766 PRINT(
"%s", Fmt(
"System Properties: Name=%s VendorId=%d", systemProperties.systemName, systemProperties.vendorId).c_str());
767 PRINT(
"%s", Fmt(
"System Graphics Properties: MaxWidth=%d MaxHeight=%d MaxLayers=%d",
768 systemProperties.graphicsProperties.maxSwapchainImageWidth,
769 systemProperties.graphicsProperties.maxSwapchainImageHeight,
770 systemProperties.graphicsProperties.maxLayerCount).c_str());
771 PRINT(
"%s", Fmt(
"System Tracking Properties: OrientationTracking=%s PositionTracking=%s",
772 systemProperties.trackingProperties.orientationTracking == XR_TRUE ?
"True" :
"False",
773 systemProperties.trackingProperties.positionTracking == XR_TRUE ?
"True" :
"False").c_str());
777 CHECK_XRCMD(xrEnumerateViewConfigurationViews(xrInstance, systemId, xrViewConfType, 0, &viewCount,
nullptr));
778 xrConfViews.resize(viewCount, { XR_TYPE_VIEW_CONFIGURATION_VIEW });
779 CHECK_XRCMD(xrEnumerateViewConfigurationViews(xrInstance, systemId, xrViewConfType, viewCount, &viewCount,
780 xrConfViews.data()));
784 xrViews.resize(viewCount, { XR_TYPE_VIEW });
789 uint32_t swapchainFormatCount;
790 CHECK_XRCMD(xrEnumerateSwapchainFormats(xrSession, 0, &swapchainFormatCount,
nullptr));
791 std::vector<int64_t> swapchainFormats(swapchainFormatCount);
792 CHECK_XRCMD(xrEnumerateSwapchainFormats(xrSession, (uint32_t)swapchainFormats.size(), &swapchainFormatCount,
793 swapchainFormats.data()));
794 CHECK(swapchainFormatCount == swapchainFormats.size());
795 colorSwapchainFormat = SelectColorSwapchainFormat(swapchainFormats);
796 if (depthExtensionAvailable) {
801 std::string swapchainFormatsString;
802 for (int64_t format : swapchainFormats) {
803 const bool selected = format == colorSwapchainFormat;
804 swapchainFormatsString +=
" ";
806 swapchainFormatsString +=
"[";
808 swapchainFormatsString += std::to_string(format);
810 swapchainFormatsString +=
"]";
813 PRINT(
"%s", Fmt(
"Swapchain Formats: %s", swapchainFormatsString.c_str()).c_str());
818 translationsOMAF.resize(viewCount);
819 translationsOpenXR.resize(viewCount);
821 if (depthExtensionAvailable) {
824 for (uint32_t i = 0; i < viewCount; i++) {
826 if (depthExtensionAvailable) {
832void WindowOpenXR::createMirrorSwapchain()
834 vk::SwapchainCreateInfoKHR mirrorCreateInfo{};
837 auto colorFormat = availableFormats[0];
838 for (
auto form : availableFormats) {
839 if (form.format == vk::Format::eR8G8B8Unorm) {
843 vk::PresentModeKHR presentMode = vk::PresentModeKHR::eMailbox;
846 glfwGetFramebufferSize(window, &width, &height);
847 vk::Extent2D extent{ (uint32_t) width, (uint32_t) height};
850 this->height = height;
855 int queueFamilyIndexCount = 0;
856 auto imageSharingMode = vk::SharingMode::eExclusive;
858 imageSharingMode = vk::SharingMode::eConcurrent;
859 queueFamilyIndexCount = 2;
862 vk::SwapchainCreateInfoKHR swapChainCreateInfo(
863 vk::SwapchainCreateFlagsKHR(),
864 static_cast<vk::SurfaceKHR
>(surface),
867 colorFormat.colorSpace,
870 vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eInputAttachment | vk::ImageUsageFlagBits::eTransferDst,
871 vk::SharingMode::eExclusive,
872 queueFamilyIndexCount,
873 queueFamilyIndexCount > 0 ? queueFamilyIndices :
nullptr,
874 vk::SurfaceTransformFlagBitsKHR::eIdentity,
875 vk::CompositeAlphaFlagBitsKHR::eOpaque,
882 vk::SemaphoreCreateInfo semaphoreInfo;
883 for (
int i = 0; i < mirrorSwapchainSize; i++) {
889const XrEventDataBaseHeader* WindowOpenXR::TryReadNextEvent() {
892 XrEventDataBaseHeader* baseHeader =
reinterpret_cast<XrEventDataBaseHeader*
>(&eventDataBuffer);
893 *baseHeader = {XR_TYPE_EVENT_DATA_BUFFER};
894 const XrResult xr = xrPollEvent(xrInstance, &eventDataBuffer);
895 if (xr == XR_SUCCESS) {
896 if (baseHeader->type == XR_TYPE_EVENT_DATA_EVENTS_LOST) {
897 const XrEventDataEventsLost*
const eventsLost =
reinterpret_cast<const XrEventDataEventsLost*
>(baseHeader);
898 PRINT(
"%s", Fmt(
"%d events lost", eventsLost).c_str());
903 if (xr == XR_EVENT_UNAVAILABLE) {
906 THROW_XR(xr,
"xrPollEvent");
912 throw std::runtime_error(
"Not supported when the headset is in standalone mode");
914 this->mirrorActivated = mirrorActivated;
919 if (depthExtensionAvailable) {
929 *exitRenderLoop = *requestRestart =
false;
932 while (
const XrEventDataBaseHeader* event = TryReadNextEvent()) {
933 switch (event->type) {
934 case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
935 const auto& instanceLossPending = *
reinterpret_cast<const XrEventDataInstanceLossPending*
>(event);
936 PRINT(
"%s", Fmt(
"XrEventDataInstanceLossPending by %lld", instanceLossPending.lossTime).c_str());
937 *exitRenderLoop =
true;
938 *requestRestart =
true;
941 case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
942 auto sessionStateChangedEvent = *
reinterpret_cast<const XrEventDataSessionStateChanged*
>(event);
943 PRINT(
"sesion state change");
944 HandleSessionStateChangedEvent(sessionStateChangedEvent, exitRenderLoop, requestRestart);
948 case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
951 case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING:
953 PRINT(
"%s", Fmt(
"Ignoring event type %d", event->type).c_str());
959void WindowOpenXR::HandleSessionStateChangedEvent(
const XrEventDataSessionStateChanged& stateChangedEvent,
bool* exitRenderLoop,
960 bool* requestRestart) {
961 const XrSessionState oldState = xrSessionState;
962 xrSessionState = stateChangedEvent.state;
964 PRINT(
"%s", Fmt(
"XrEventDataSessionStateChanged: state %s->%s session=%lld time=%lld", to_string(oldState),
965 to_string(xrSessionState), stateChangedEvent.session, stateChangedEvent.time).c_str());
967 if ((stateChangedEvent.session != XR_NULL_HANDLE) && (stateChangedEvent.session != xrSession)) {
968 PRINT(
"%s",
"XrEventDataSessionStateChanged for unknown session");
972 switch (xrSessionState) {
973 case XR_SESSION_STATE_READY: {
974 CHECK(xrSession != XR_NULL_HANDLE);
975 XrSessionBeginInfo sessionBeginInfo{XR_TYPE_SESSION_BEGIN_INFO};
976 sessionBeginInfo.primaryViewConfigurationType = xrViewConfType;
977 CHECK_XRCMD(xrBeginSession(xrSession, &sessionBeginInfo));
978 runningSession =
true;
981 case XR_SESSION_STATE_STOPPING: {
982 CHECK(xrSession != XR_NULL_HANDLE);
983 runningSession =
false;
984 CHECK_XRCMD(xrEndSession(xrSession))
987 case XR_SESSION_STATE_EXITING: {
988 *exitRenderLoop =
true;
990 *requestRestart =
false;
993 case XR_SESSION_STATE_LOSS_PENDING: {
994 *exitRenderLoop =
true;
996 *requestRestart =
true;
1004void WindowOpenXR::selectViewConfiguration()
1006 uint32_t viewConfigTypeCount;
1007 CHECK_XRCMD(xrEnumerateViewConfigurations(xrInstance, systemId, 0, &viewConfigTypeCount,
nullptr));
1008 std::vector<XrViewConfigurationType> viewConfigTypes(viewConfigTypeCount);
1009 CHECK_XRCMD(xrEnumerateViewConfigurations(xrInstance, systemId, viewConfigTypeCount,
1010 &viewConfigTypeCount,
1011 viewConfigTypes.data()));
1012 CHECK((uint32_t)viewConfigTypes.size() == viewConfigTypeCount);
1013 bool foundConfigurationType =
false;
1014 for (
auto supportedConf : supportedViewConfigurations) {
1015 for (XrViewConfigurationType viewConfigType : viewConfigTypes) {
1016 if (supportedConf == viewConfigType && !((viewConfigType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_QUAD_VARJO) && !quadViewExtensionAvailable )) {
1018 xrViewConfType = supportedConf;
1024void WindowOpenXR::selectBlendMode()
1033 bool blendModeFound =
false;
1036 CHECK_XRCMD(xrEnumerateEnvironmentBlendModes(xrInstance, systemId, xrViewConfType, 0, &count,
nullptr));
1038 std::vector<XrEnvironmentBlendMode> blendModes(count);
1039 CHECK_XRCMD(xrEnumerateEnvironmentBlendModes(xrInstance, systemId, xrViewConfType, count, &count, blendModes.data()));
1042 for (XrEnvironmentBlendMode mode : blendModes) {
1043 for (
auto supportedBlend : this->supportedBlendModes) {
1044 if (supportedBlend == mode && !blendModeFound) {
1046 blendModeFound =
true;
1051 CHECK(blendModeFound);
1055void WindowOpenXR::checkExtensions()
1057 PRINT(
"\n Check for Openxr Extensions:");
1058 uint32_t instanceExtensionCount;
1059 CHECK_XRCMD(xrEnumerateInstanceExtensionProperties(
nullptr, 0, &instanceExtensionCount,
nullptr));
1061 std::vector<XrExtensionProperties> extensions(instanceExtensionCount);
1062 for (XrExtensionProperties& extension : extensions) {
1063 extension.type = XR_TYPE_EXTENSION_PROPERTIES;
1066 CHECK_XRCMD(xrEnumerateInstanceExtensionProperties(
nullptr, (uint32_t)extensions.size(), &instanceExtensionCount,
1067 extensions.data()));
1069 for (
auto& ext : extensions) {
1070 if (strcmp(ext.extensionName , XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME) == 0) {
1071 depthExtensionAvailable =
true;
1072 PRINT(
"Depth extension available !");
1074 if (strcmp(ext.extensionName , XR_VARJO_QUAD_VIEWS_EXTENSION_NAME) == 0) {
1075 quadViewExtensionAvailable =
true;
1076 PRINT(
"Varjo quad view extension available !" );
1078 D(PRINT(
"found extension: %s", ext.extensionName));
1084void WindowOpenXR::inputKeyCallback(GLFWwindow* window,
int key,
int scancode,
int action,
int mode)
1086 const int inputAction = GLFW_PRESS;
1087 if (key == GLFW_KEY_SPACE && action == inputAction)
1091 else if ((key == GLFW_KEY_0 || key == GLFW_KEY_KP_0) && action == inputAction) {
1094 else if (key == GLFW_KEY_ESCAPE) {
1095 xrRequestExitSession(xrSession);
1097 else if (key == GLFW_KEY_F3) {
1100 else if (key == GLFW_KEY_F9) {
1101 this->pauseRendering =
true;
1102 PRINT(
"pause rendering for test");
1107void WindowOpenXR::renderFrame(
VulkanDrawing* vulkanDrawing) {
1108 XrFrameWaitInfo frameWaitInfo{XR_TYPE_FRAME_WAIT_INFO};
1109 XrFrameState frameState{XR_TYPE_FRAME_STATE};
1110 CHECK_XRCMD(xrWaitFrame(xrSession, &frameWaitInfo, &frameState));
1112 XrFrameBeginInfo frameBeginInfo{XR_TYPE_FRAME_BEGIN_INFO};
1113 CHECK_XRCMD(xrBeginFrame(xrSession, &frameBeginInfo));
1117 std::vector<XrCompositionLayerProjectionView> projectionLayerViews;
1118 std::vector<XrCompositionLayerDepthInfoKHR> depthProjectionLayerViews;
1119 std::vector<XrCompositionLayerBaseHeader*> layers;
1120 XrCompositionLayerProjection layer{ XR_TYPE_COMPOSITION_LAYER_PROJECTION };
1122 if (!mirrorActivated) {
1126 if (frameState.shouldRender == XR_TRUE) {
1130 bool renderOk =
true;
1132 XrViewState viewState{XR_TYPE_VIEW_STATE};
1133 uint32_t viewCapacityInput = (uint32_t)xrViews.size();
1134 uint32_t viewCountOutput;
1136 XrViewLocateInfo viewLocateInfo{XR_TYPE_VIEW_LOCATE_INFO};
1137 viewLocateInfo.viewConfigurationType = xrViewConfType;
1138 viewLocateInfo.displayTime = frameState.predictedDisplayTime;
1139 viewLocateInfo.space = refSpace;
1141 res = xrLocateViews(xrSession, &viewLocateInfo, &viewState, viewCapacityInput, &viewCountOutput, xrViews.data());
1142 if (!((viewState.viewStateFlags & XR_VIEW_STATE_POSITION_VALID_BIT) == 0 ||
1143 (viewState.viewStateFlags & XR_VIEW_STATE_ORIENTATION_VALID_BIT) == 0)) {
1147 auto startTime = std::chrono::high_resolution_clock::now();
1150 CHECK(viewCountOutput == viewCapacityInput);
1151 CHECK(viewCountOutput == xrConfViews.size());
1153 if (depthExtensionAvailable) {
1157 projectionLayerViews.resize(viewCountOutput);
1158 if (depthExtensionAvailable) {
1159 depthProjectionLayerViews.resize(viewCountOutput);
1162 std::vector<vk::Fence> fences;
1163 std::vector<uint32_t> indexesSwap;
1164 std::vector<uint32_t> indexesSwapDepth;
1167 for (uint32_t i = 0; i < viewCountOutput; i++) {
1169 auto viewSwapchainHandle =
swapchains[i]->handle;
1173 uint32_t swapchainImageIndex;
1174 std::optional<vk::Semaphore> semaphore;
1175 std::tie(swapchainImageIndex, semaphore) =
swapchains[i]->acquireImage();
1176 indexesSwap.push_back(swapchainImageIndex);
1177 std::vector<vk::Semaphore> semaphoresList;
1178 if (semaphore.has_value()) {
1179 semaphoresList.push_back(semaphore.value());
1181 projectionLayerViews[i] = { XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW };
1182 projectionLayerViews[i].pose = xrViews[i].pose;
1183 projectionLayerViews[i].fov = xrViews[i].fov;
1184 projectionLayerViews[i].subImage.swapchain = std::get<XrSwapchain>(viewSwapchainHandle);
1185 projectionLayerViews[i].subImage.imageRect.offset = { 0, 0 };
1186 projectionLayerViews[i].subImage.imageRect.extent.width =
swapchains[i]->swapchainExtent.width;
1187 projectionLayerViews[i].subImage.imageRect.extent.height =
swapchains[i]->swapchainExtent.height;
1189 uint32_t depthSwapchainImageIndex = UINT_MAX;
1190 if (depthExtensionAvailable) {
1191 std::optional<vk::Semaphore> dSemaphore;
1192 std::tie(depthSwapchainImageIndex, dSemaphore) =
depthSwapchains[i]->acquireImage();
1193 indexesSwapDepth.push_back(depthSwapchainImageIndex);
1194 if (dSemaphore.has_value()) {
1195 semaphoresList.push_back(dSemaphore.value());
1197 assert(depthSwapchainImageIndex == swapchainImageIndex);
1198 depthProjectionLayerViews[i] = {XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR};
1199 depthProjectionLayerViews[i].minDepth = 1;
1200 depthProjectionLayerViews[i].maxDepth = 0;
1205 depthProjectionLayerViews[i].subImage.swapchain = std::get<XrSwapchain>(
depthSwapchains[i]->handle);
1206 depthProjectionLayerViews[i].subImage.imageArrayIndex = 0;
1207 depthProjectionLayerViews[i].subImage.imageRect.offset = { 0,0 };
1208 depthProjectionLayerViews[i].subImage.imageRect.extent = { (int)
depthSwapchains[i]->swapchainExtent.width, (
int)
depthSwapchains[i]->swapchainExtent.height };
1209 projectionLayerViews[i].next = &(depthProjectionLayerViews[i]);
1212 projectionLayerViews[i].next =
nullptr;
1215 translationsOpenXR[i] = { xrViews[i].pose.position.x ,xrViews[i].pose.position.y,xrViews[i].pose.position.z };
1216 translationsOMAF[i] = conversionMat * translationsOpenXR[i];
1218#ifdef HVT_UDP_CONTROL
1223#ifdef HVT_UDP_CONTROL
1227 auto rot = XrQuaternionToGLMQuat(xrViews[i].pose.orientation);
1229 glm::vec4 fov(xrViews[i].fov.angleLeft, xrViews[i].fov.angleRight, xrViews[i].fov.angleUp,xrViews[i].fov.angleDown);
1232 uint32_t mirrorIndex = 0;
1233 mirrorShouldRender =
true;
1234 if (mirrorActivated && i == 0 && swapchainImageIndex == currentMirror) {
1236 int width = 0, height = 0;
1237 glfwGetFramebufferSize(window, &width, &height);
1239 if (width == 0 || height == 0) {
1240 mirrorShouldRender =
false;
1243 vk::Result acquireResult;
1244 std::tie(acquireResult, mirrorIndex) =
wrapper->
getContext()->
device.acquireNextImageKHR(mirrorSwapchain, std::numeric_limits<uint64_t>::max(), mirrorAvailableSemaphore[currentMirror],
nullptr);
1246 if (acquireResult != vk::Result::eSuccess && acquireResult != vk::Result::eSuboptimalKHR) {
1247 throw std::runtime_error(
"failed to acquire swap chain image!");
1250 catch (vk::OutOfDateKHRError e) {
1253 mirrorShouldRender =
false;
1256 if (mirrorShouldRender) {
1257 semaphoresList.push_back(mirrorAvailableSemaphore[currentMirror]);
1262 std::tuple<int, uint32_t> idImage = std::make_pair(i,swapchainImageIndex);
1263 vk::Fence renderfinnished;
1264 std::vector<vk::Semaphore> sem;
1265 if (mirrorActivated && i == 0 && swapchainImageIndex == currentMirror && mirrorShouldRender) {
1266 sem.push_back(mirrorFinnishedSemaphore[currentMirror]);
1269 if (depthExtensionAvailable) {
1270 renderfinnished = vulkanDrawing->
submitDrawCall(idImage, semaphoresList, sem ,depthSwapchainImageIndex);
1273 renderfinnished = vulkanDrawing->
submitDrawCall(idImage, semaphoresList, sem);
1276 fences.push_back(renderfinnished);
1278 if (mirrorActivated && i == 0 && swapchainImageIndex == currentMirror && mirrorShouldRender) {
1279 vk::PresentInfoKHR presentInfo{ 1,
1280 &mirrorFinnishedSemaphore[currentMirror],
1288 if (resultPresent == vk::Result::eSuboptimalKHR) {
1291 else if (resultPresent != vk::Result::eSuccess) {
1292 throw std::runtime_error(
"failed to present swap chain image!");
1295 catch (vk::OutOfDateKHRError) {
1299 currentMirror = (currentMirror + 1) % mirrorSwapchainSize;
1305 for (uint32_t i = 0; i < viewCountOutput; i++) {
1306 assert(fences.size() == viewCountOutput);
1307 assert(indexesSwap.size() == viewCountOutput);
1309 swapchains[i]->presentImage(indexesSwap[i], fences[i]);
1310 if (depthExtensionAvailable) {
1311 assert(indexesSwapDepth.size() == viewCountOutput);
1316 layer.space = refSpace;
1317 layer.viewCount = (uint32_t)projectionLayerViews.size();
1318 layer.views = projectionLayerViews.data();
1320 layers.push_back(
reinterpret_cast<XrCompositionLayerBaseHeader*
>(&layer));
1322 auto end = std::chrono::high_resolution_clock::now();
1323 auto t = std::chrono::duration_cast<std::chrono::milliseconds>(end - startTime);
1326 auto res = totalChrono / (count);
1327 std::cout << res.count() << std::endl;
1328 totalChrono = std::chrono::milliseconds( 0 );
1336 XrFrameEndInfo frameEndInfo{XR_TYPE_FRAME_END_INFO};
1337 frameEndInfo.displayTime = frameState.predictedDisplayTime;
1338 frameEndInfo.environmentBlendMode = xrBlendMode;
1339 frameEndInfo.layerCount = (uint32_t)layers.size();
1340 frameEndInfo.layers = layers.data();
1341 CHECK_XRCMD(xrEndFrame(xrSession, &frameEndInfo));
1343 depthProjectionLayerViews.clear();
1344 projectionLayerViews.clear();
1350 return runningSession;
1359 assert(quaternionsList.size() == rotationsOMAF.size());
1360 assert(quaternionsList.size() == rotationsOpenXR.size());
1361 if (quaternionsList.size() !=
swapchains.size()) {
1363 quaternionsList.resize(s);
1364 rotationsOMAF.resize(s);
1365 rotationsOpenXR.resize(s);
1368 quaternionsList[view] = qR;
1370#ifdef HVT_UDP_CONTROL
1373 auto q = deltaQuat * qR;
1375#ifdef HVT_UDP_CONTROL
1380 double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
1381 double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
1382 rotationsOMAF[view][0] = -1 * std::atan2(siny_cosp, cosy_cosp) * (180.0 / M_PI);
1383 rotationsOpenXR[view][2] = std::atan2(siny_cosp, cosy_cosp) * (180.0 / M_PI);
1386 double sinp = 2 * (q.w * q.y - q.z * q.x);
1387 if (std::abs(sinp) >= 1) {
1388 rotationsOMAF[view][2] = std::copysign(M_PI / 2, sinp) * (180.0 / M_PI);
1389 rotationsOpenXR[view][1] = std::copysign(M_PI / 2, sinp) * (180.0 / M_PI);
1392 rotationsOMAF[view][2] = std::asin(sinp) * (180.0 / M_PI);
1393 rotationsOpenXR[view][1] = std::asin(sinp) * (180.0 / M_PI);
1397 double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
1398 double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
1399 rotationsOMAF[view][1] = -1 * std::atan2(sinr_cosp, cosr_cosp) * (180.0 / M_PI);
1400 rotationsOpenXR[view][0] = std::atan2(sinr_cosp, cosr_cosp) * (180.0 / M_PI);
1411 return swapchains[view]->getSwapchainImage(index);
1415void WindowOpenXR::checkKeyboard() {
1418 SHORT keyState0 = GetAsyncKeyState(
'0');
1419 bool isToggled0 = keyState0 & 1;
1420 bool isDown0 = keyState0 & 0x8000;
1422 SHORT keyStateNum0 = GetAsyncKeyState(VK_NUMPAD0);
1423 auto isToggledNum0 = keyStateNum0 & 1;
1424 bool isDownNum0 = keyStateNum0 & 0x8000;
1426 SHORT keyStateSpace = GetAsyncKeyState(VK_SPACE);
1427 bool isToggledSpace = keyStateSpace & 1;
1428 bool isDownSpace = keyStateSpace & 0x8000;
1430 SHORT keyStateEscape = GetAsyncKeyState(VK_ESCAPE);
1431 bool isToggledEscape = keyStateEscape & 1;
1433 SHORT keyStateF2 = GetAsyncKeyState(VK_F2);
1434 bool isToggledF2 = keyStateF2 & 1;
1436 SHORT keyStateF3 = GetAsyncKeyState(VK_F3);
1437 bool isToggledF3 = keyStateF3 & 1;
1441 bool isToggled0 =
false;
1442 bool isToggledSpace =
false;
1443 bool isDown0 =
false;
1444 bool isDownSpace =
false;
1445 bool isToggledNum0 =
false;
1446 bool isDownNum0 =
false;
1447 bool isToggledEscape =
false;
1448 bool isToggledF2 =
false;
1449 bool isToggledF3 =
false;
1469 if ((isDown0 && isToggled0) || (isDownNum0 && isToggledNum0)) {
1473 if (isDownSpace && isToggledSpace) {
1477 if (isToggledEscape) {
1478 xrRequestExitSession(xrSession);
1493 glm::vec3 averagePos = { 0,0,0 };
1494 for (
int i = 0; i < translationsOpenXR.size(); i++) {
1495 averagePos += translationsOpenXR[i];
1497 averagePos /= translationsOpenXR.size();
1498 glm::quat q = quaternionsList[quaternionsList.size() - 1];
1500#ifdef HVT_UDP_CONTROL
1504 deltaPos = -1.0f * averagePos;
1505 deltaQuat = glm::inverse(q);
1507#ifdef HVT_UDP_CONTROL
1513void WindowOpenXR::printCoordinates()
1515 std::cout <<
"--------------" << std::endl;
1516 for (
int i = 0; i < 2; i++) {
1517 std::cout <<
"View: " << i << std::endl;
1518 std::cout <<
"Translation OpenXR: " << glm::to_string(translationsOpenXR[i]) <<
"Rotation OpenXR : " << glm::to_string(rotationsOpenXR[i]) << std::endl;
1519 std::cout <<
"Translation OMAF: " << glm::to_string(translationsOMAF[i]) <<
"Rotation OMAF : " << glm::to_string(rotationsOMAF[i]) << std::endl;
1520 std::cout <<
"Test: " << glm::to_string(conversionMat * rotationsOMAF[i]) << std::endl;
File that contains the SwapchainOpenXR class.
File that contain the VulkanContext class to manage Vulkan Instance, Physical device,...
Contains the class that manage the drawing process (manage and record command buffer,...
Class that contains helper functions for Vulkan.
file that contains the VulkanWrapper class that manages the classes related to Vulkan code and ease t...
Class that take care of the tasks linked to OpenXR (input and display), is used when HMD support is r...
Class that encapsulate an OpenXR Swapchain and functions associated to it.
vk::PhysicalDevice physicalDevice
QueueFamilyIndices findQueueFamilies(vk::PhysicalDevice device)
The class that manages the drawing operation (manage and record command buffers).
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()
std::vector< vk::Format > getRenderPassSupportedDepthFormats() const
void updateSpaceTransform(glm::vec3 translation, glm::vec3 rotation)
RenderingParameters params
VulkanContext * getContext()
glm::vec3 currentTranslation
std::vector< std::unique_ptr< SwapchainAbstract > > depthSwapchains
glm::vec3 currentRotation
bool separateFromWindowDim
std::vector< std::unique_ptr< SwapchainAbstract > > swapchains
const bool enableValidationLayers
Class that take care of the tasks linked to OpenXR (input and display), is used when HMD support is r...
std::vector< vk::Extent2D > getBlitExtentDestinations(int view, int elem) override
void checkForCorrectSize()
void setMirror(bool mirrorActivated)
virtual std::vector< vk::Semaphore > getSemaphoreWait(int view, int elem) override
void createVulkanDevice(VkPhysicalDevice &physicalDevice, VkDeviceCreateInfo &info, VkDevice *device)
virtual std::vector< vk::Semaphore > getSemaphoreSignal(int view, int elem) override
void getVulkanPhysicalDevice(VkInstance &vkInstance, VkPhysicalDevice *physicalDevice)
void cleanUpSurface() override
void continueInit() override
void initWindow() override
bool isDepthRecquired() override
std::vector< const char * > getRequiredDeviceExtensions() override
vk::Image getSwapchainImage(int view, int index) override
void mainLoop(VulkanDrawing *vulkanDrawing) override
std::vector< vk::Image > getBlitDestinations(int view, int elem) override
void setRotation(glm::quat &q, int view)
void createSurface() override
void framebufferResizeCallback()
const bool useOpenXR() override
VkBool32 isDeviceSupportingSufaceKHR(VkPhysicalDevice device, int i) override
void getFrameBufferSize(int *w, int *h, vk::PhysicalDevice &pDevice) override
bool isSynchroWithSemaphore() override
void resetOrigin() override
std::vector< const char * > getRequiredExtensions() override
SwapChainSupportDetails querySwapChainSupport(vk::PhysicalDevice device) override
void pollEvents(bool *exitRenderLoop, bool *requestRestart)
file that contains the common include for the Vulkan part
Some useful functions from the openXR sample (hello_xr)
Struct to encapsulate the indice of the queues families.
std::optional< uint32_t > graphicsFamily
std::optional< uint32_t > presentFamily
Struct that contains the capability for the sapchain, the formats and the present mode supported.