From 986a08b7247e0a1f10ffe585a3dc0656975fc4c5 Mon Sep 17 00:00:00 2001 From: uvos Date: Tue, 15 Apr 2025 21:13:31 +0200 Subject: [PATCH] inital commit --- CMakeLists.txt | 10 +++ main.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 main.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..be96bdd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.20) + +project(xrexpirament) + +find_package(OpenXR REQUIRED) + +add_executable(${PROJECT_NAME} main.c) +target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${OpenXR_INCLUDE_DIR}) +target_link_libraries(${PROJECT_NAME} OpenXR::openxr_loader) + diff --git a/main.c b/main.c new file mode 100644 index 0000000..0e1f668 --- /dev/null +++ b/main.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +sig_atomic_t stop = false; + +void handler(int sig) +{ + stop = true; +} + +#define HEADLESS_EXT "XR_MND_headless" + +static const char* xr_strerror(XrInstance instance, XrResult err) +{ + static char buffer[XR_MAX_RESULT_STRING_SIZE]; + xrResultToString(instance, err, buffer); + return buffer; +} + +void clear() +{ + puts("\033[H\033[J"); +} + +int main(int argc, char** argv) +{ + XrInstance instance; + XrApplicationInfo applicationInfo = { + .applicationName = "OpenXR Example", + .engineName = "Example Engine", + .apiVersion = XR_API_VERSION_1_0, + }; + + uint32_t extentionPropCount; + xrEnumerateInstanceExtensionProperties(NULL, 0, &extentionPropCount, NULL); + XrExtensionProperties *proparties = calloc(extentionPropCount, sizeof(*proparties)); + for (uint32_t i = 0; i < extentionPropCount; ++i) + proparties[i].type = XR_TYPE_EXTENSION_PROPERTIES; + XrResult result = xrEnumerateInstanceExtensionProperties(NULL, extentionPropCount, &extentionPropCount, proparties); + if (!XR_SUCCEEDED(result)) { + printf("Failed to query OpenXR extensions: %d\n", result); + return 1; + } + printf("OpenXR extensions: %d\n", extentionPropCount); + bool foundHeadless = false; + for (uint32_t i = 0; i < extentionPropCount; ++i) { + printf("\t%s\n", proparties[i].extensionName); + if (strcmp(HEADLESS_EXT, proparties[i].extensionName) == 0) + foundHeadless = true; + } + if (!foundHeadless) { + puts("Runtime dose not support " HEADLESS_EXT); + return 1; + } + + const char *enabledExtensionNames[] = {HEADLESS_EXT, NULL}; + + XrInstanceCreateInfo createInfo = { + .type = XR_TYPE_INSTANCE_CREATE_INFO, + .next = NULL, + .createFlags = 0, + .applicationInfo = applicationInfo, + .enabledExtensionNames = enabledExtensionNames, + .enabledExtensionCount = 1 + }; + + XrSystemGetInfo getInfo = { + .type = XR_TYPE_SYSTEM_GET_INFO, + .formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY + }; + + result = xrCreateInstance(&createInfo, &instance); + if (XR_SUCCEEDED(result)) { + printf("OpenXR instance created successfully.\n"); + } else { + printf("Failed to create OpenXR instance: %d\n", result); + return 1; + } + + XrSystemId systemId; + result = xrGetSystem(instance, &getInfo, &systemId); + if (!XR_SUCCEEDED(result)) { + printf("Failed to get OpenXR system: %s\n", xr_strerror(instance, result)); + return 1; + } + + uint32_t viewCount; + result = xrEnumerateViewConfigurationViews(instance, systemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, 0, &viewCount, NULL); + XrViewConfigurationView* viewConfigs = calloc(viewCount, sizeof(XrViewConfigurationView)); + for (size_t i = 0; i < viewCount; ++i) + viewConfigs[i].type = XR_TYPE_VIEW_CONFIGURATION_VIEW; + if (XR_SUCCEEDED(result)) { + result = xrEnumerateViewConfigurationViews(instance, systemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, viewCount, &viewCount, viewConfigs); + if (!XR_SUCCEEDED(result)) { + printf("Failed to enumerate viewConfigs: %d\n", result); + return 1; + } + } + + XrSession session; + XrSessionCreateInfo createSessionInfo = { + .type = XR_TYPE_SESSION_CREATE_INFO, + .systemId = systemId + }; + result = xrCreateSession(instance, &createSessionInfo, &session); + if (!XR_SUCCEEDED(result)) { + printf("Failed to create session: %s\n", xr_strerror(instance, result)); + return 1; + } + XrSessionBeginInfo beginInfo = {.type = XR_TYPE_SESSION_BEGIN_INFO, .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO}; + result = xrBeginSession(session, &beginInfo); + + XrSpace stageSpace; + XrReferenceSpaceCreateInfo spaceCreateInfo = { + .type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO, + .referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE + }; + spaceCreateInfo.poseInReferenceSpace.orientation.x = 1; + result = xrCreateReferenceSpace(session, &spaceCreateInfo, &stageSpace); + if (!XR_SUCCEEDED(result)) { + printf("Failed to create referance space: %s\n", xr_strerror(instance, result)); + return 1; + } + + struct timespec duration = {.tv_sec = 1}; + nanosleep(&duration, NULL); + + XrView *views = calloc(viewCount, sizeof(*views)); + for (size_t i = 0; i < viewCount; ++i) + views[i].type = XR_TYPE_VIEW; + XrViewState state = {.type = XR_TYPE_VIEW_STATE}; + + signal(SIGTERM, handler); + signal(SIGHUP, handler); + signal(SIGINT, handler); + + while(!stop) { + XrFrameWaitInfo waitInfo = {.type = XR_TYPE_FRAME_WAIT_INFO}; + XrFrameState frameState = {.type = XR_TYPE_FRAME_STATE}; + result = xrWaitFrame(session, &waitInfo, &frameState); + if (!XR_SUCCEEDED(result)) { + printf("Failed to wait for frame: %s\n", xr_strerror(instance, result)); + return 1; + } else { + printf("waited for frame time: %lu\n", frameState.predictedDisplayPeriod); + } + + XrViewLocateInfo locateInfo = { + .type = XR_TYPE_VIEW_LOCATE_INFO, + .viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, + .space = stageSpace, + .displayTime = frameState.predictedDisplayTime+1 + }; + uint32_t locatedViews; + result = xrLocateViews(session, &locateInfo, &state, viewCount, &locatedViews, views); + if (!XR_SUCCEEDED(result)) { + printf("Failed to locate views: %s\n", xr_strerror(instance, result)); + struct timespec duration = {.tv_nsec = 1000*100}; + nanosleep(&duration, NULL); + continue; + } else if (locatedViews != viewCount) { + printf("Failed to locate all views"); + struct timespec duration = {.tv_nsec = 1000*100}; + nanosleep(&duration, NULL); + continue; + } + + clear(); + for (size_t i = 0; i < viewCount; ++i) { + printf("View %zu:\n", i); + printf("\tRecommended Size: %d x %d\n", viewConfigs[i].recommendedImageRectWidth, viewConfigs[i].recommendedImageRectHeight); + printf("\tFOV:\n\t\tUP: %f\n\t\tDOWN: %f\n\t\tLEFT: %f\n\t\tRIGHT: %f\n", views[i].fov.angleUp, views[i].fov.angleDown, views[i].fov.angleLeft, views[i].fov.angleRight); + printf("\tPOS:\n\t\tX: %f\n\t\tY: %f\n\t\tZ: %f\n", views[i].pose.position.x, views[i].pose.position.y, views[i].pose.position.z); + } + + struct timespec duration = {.tv_nsec = 1000*100}; + nanosleep(&duration, NULL); + } + + xrEndSession(session); + free(views); + free(viewConfigs); + xrDestroySpace(stageSpace); + xrDestroySession(session); + xrDestroyInstance(instance); + + return 0; +}