34 XrViewConfigurationType
view_type = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
77 oxr_->swapchains.clear();
78 oxr_->action_sets.clear();
80 if (oxr_->reference_space != XR_NULL_HANDLE) {
83 if (oxr_->view_space != XR_NULL_HANDLE) {
86 if (oxr_->combined_eye_space != XR_NULL_HANDLE) {
89 if (oxr_->session != XR_NULL_HANDLE) {
93 oxr_->session = XR_NULL_HANDLE;
94 oxr_->session_state = XR_SESSION_STATE_UNKNOWN;
96 oxr_->passthrough_supported =
false;
97 oxr_->passthrough_layer.layerHandle = XR_NULL_HANDLE;
99 context_->getCustomFuncs().session_exit_fn(context_->getCustomFuncs().session_exit_customdata);
106void GHOST_XrSession::initSystem()
109 assert(oxr_->system_id == XR_NULL_SYSTEM_ID);
111 XrSystemGetInfo system_info = {};
112 system_info.type = XR_TYPE_SYSTEM_GET_INFO;
113 system_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
115 CHECK_XR(xrGetSystem(context_->getInstance(), &system_info, &oxr_->system_id),
116 "Failed to get device information. Is a device plugged in?");
126 const GHOST_XrPose &base_pose,
129 XrReferenceSpaceCreateInfo create_info = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
130 create_info.poseInReferenceSpace.orientation.w = 1.0f;
132 create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
145 create_info.poseInReferenceSpace.position.x = base_pose->position[0];
146 create_info.poseInReferenceSpace.position.y = base_pose->position[1];
147 create_info.poseInReferenceSpace.position.z = base_pose->position[2];
148 create_info.poseInReferenceSpace.orientation.x = base_pose->orientation_quat[1];
149 create_info.poseInReferenceSpace.orientation.y = base_pose->orientation_quat[2];
150 create_info.poseInReferenceSpace.orientation.z = base_pose->orientation_quat[3];
151 create_info.poseInReferenceSpace.orientation.w = base_pose->orientation_quat[0];
162 if (
result == XR_ERROR_REFERENCE_SPACE_UNSUPPORTED) {
165 "Warning: XR runtime does not support stage reference space, falling back to local "
166 "reference space.\n");
168 create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
170 "Failed to create local reference space.");
180 CHECK_XR(xrGetReferenceSpaceBoundsRect(oxr.
session, XR_REFERENCE_SPACE_TYPE_STAGE, &extents),
181 "Failed to get stage reference space bounds.");
182 if (extents.width == 0.0f || extents.height == 0.0f) {
185 "Warning: Invalid stage reference space bounds, falling back to local reference "
186 "space. To use the stage reference space, please define a tracking space via the XR "
194 create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
196 "Failed to create local reference space.");
200 create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
202 "Failed to create view reference space.");
206 create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO;
208 "Failed to create combined eye reference space.");
214 assert(context_->getInstance() != XR_NULL_HANDLE);
215 assert(oxr_->session == XR_NULL_HANDLE);
216 if (context_->getCustomFuncs().gpu_ctx_bind_fn ==
nullptr) {
218 "Invalid API usage: No way to bind graphics context to the XR session. Call "
219 "GHOST_XrGraphicsContextBindFuncs() with valid parameters before starting the "
220 "session (through GHOST_XrSessionStart()).");
225 bindGraphicsContext();
226 if (gpu_ctx_ ==
nullptr) {
228 "Invalid API usage: No graphics context returned through the callback set with "
229 "GHOST_XrGraphicsContextBindFuncs(). This is required for session starting (through "
230 "GHOST_XrSessionStart()).");
233 std::string requirement_str;
236 if (!gpu_binding_->checkVersionRequirements(
237 *gpu_ctx_, context_->getInstance(), oxr_->system_id, &requirement_str))
239 std::ostringstream strstream;
240 strstream <<
"Available graphics context version does not meet the following requirements: "
244 gpu_binding_->initFromGhostContext(*gpu_ctx_, context_->getInstance(), oxr_->system_id);
246 XrSessionCreateInfo create_info = {};
247 create_info.type = XR_TYPE_SESSION_CREATE_INFO;
248 create_info.systemId = oxr_->system_id;
249 create_info.next = &gpu_binding_->oxr_binding;
251 CHECK_XR(xrCreateSession(context_->getInstance(), &create_info, &oxr_->session),
252 "Failed to create VR session. The OpenXR runtime may have additional requirements for "
253 "the graphics driver that are not met. Other causes are possible too however.\nTip: "
254 "The --debug-xr command line option for Blender might allow the runtime to output "
255 "detailed error information to the command line.");
261 context_->getCustomFuncs().session_create_fn();
266 xrRequestExitSession(oxr_->session);
269void GHOST_XrSession::beginSession()
271 XrSessionBeginInfo begin_info = {XR_TYPE_SESSION_BEGIN_INFO};
272 begin_info.primaryViewConfigurationType = oxr_->view_type;
273 CHECK_XR(xrBeginSession(oxr_->session, &begin_info),
"Failed to cleanly begin the VR session.");
276void GHOST_XrSession::endSession()
278 assert(oxr_->session != XR_NULL_HANDLE);
279 CHECK_XR(xrEndSession(oxr_->session),
"Failed to cleanly end the VR session.");
283 const XrEventDataSessionStateChanged &lifecycle)
285 oxr_->session_state = lifecycle.state;
289 assert(oxr_->session == XR_NULL_HANDLE || oxr_->session == lifecycle.session);
291 switch (lifecycle.state) {
292 case XR_SESSION_STATE_READY:
295 case XR_SESSION_STATE_STOPPING:
298 case XR_SESSION_STATE_EXITING:
299 case XR_SESSION_STATE_LOSS_PENDING:
314void GHOST_XrSession::prepareDrawing()
318 std::vector<XrViewConfigurationView> view_configs;
323 oxr_->view_type = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_QUAD_VARJO;
326 oxr_->foveation_supported = context_->isExtensionEnabled(
327 XR_VARJO_FOVEATED_RENDERING_EXTENSION_NAME);
329 CHECK_XR(xrEnumerateViewConfigurationViews(
330 context_->getInstance(), oxr_->system_id, oxr_->view_type, 0, &view_count,
nullptr),
331 "Failed to get count of view configurations.");
332 view_configs.resize(view_count, {XR_TYPE_VIEW_CONFIGURATION_VIEW});
333 CHECK_XR(xrEnumerateViewConfigurationViews(context_->getInstance(),
338 view_configs.data()),
339 "Failed to get view configurations.");
342 if (oxr_->foveation_supported) {
343 std::vector<XrFoveatedViewConfigurationViewVARJO> request_foveated_config{
344 view_count, {XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO,
nullptr, XR_TRUE}};
346 auto foveated_views = std::vector<XrViewConfigurationView>(view_count,
347 {XR_TYPE_VIEW_CONFIGURATION_VIEW});
349 for (uint32_t
i = 0;
i < view_count;
i++) {
350 foveated_views[
i].next = &request_foveated_config[
i];
352 CHECK_XR(xrEnumerateViewConfigurationViews(context_->getInstance(),
357 foveated_views.data()),
358 "Failed to get foveated view configurations.");
361 for (uint32_t
i = 0;
i < view_count;
i++) {
362 view_configs[
i].recommendedImageRectWidth = std::max(
363 view_configs[
i].recommendedImageRectWidth, foveated_views[
i].recommendedImageRectWidth);
364 view_configs[
i].recommendedImageRectHeight = std::max(
365 view_configs[
i].recommendedImageRectHeight,
366 foveated_views[
i].recommendedImageRectHeight);
370 for (
const XrViewConfigurationView &view_config : view_configs) {
371 oxr_->swapchains.emplace_back(*gpu_binding_, oxr_->session, view_config);
374 oxr_->views.resize(view_count, {XR_TYPE_VIEW});
376 draw_info_ = std::make_unique<GHOST_XrDrawInfo>();
379void GHOST_XrSession::beginFrameDrawing()
381 XrFrameWaitInfo wait_info = {XR_TYPE_FRAME_WAIT_INFO};
382 XrFrameBeginInfo begin_info = {XR_TYPE_FRAME_BEGIN_INFO};
383 XrFrameState frame_state = {XR_TYPE_FRAME_STATE};
386 CHECK_XR(xrWaitFrame(oxr_->session, &wait_info, &frame_state),
387 "Failed to synchronize frame rates between Blender and the device.");
390 draw_info_->foveation_active =
false;
391 if (oxr_->foveation_supported) {
392 XrSpaceLocation render_gaze_location{XR_TYPE_SPACE_LOCATION};
393 CHECK_XR(xrLocateSpace(oxr_->combined_eye_space,
395 frame_state.predictedDisplayTime,
396 &render_gaze_location),
397 "Failed to locate combined eye space.");
399 draw_info_->foveation_active = (render_gaze_location.locationFlags &
400 XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT) != 0;
403 CHECK_XR(xrBeginFrame(oxr_->session, &begin_info),
404 "Failed to submit frame rendering start state.");
406 draw_info_->frame_state = frame_state;
408 if (context_->isDebugTimeMode()) {
409 draw_info_->frame_begin_time = std::chrono::high_resolution_clock::now();
416 std::chrono::duration<double, std::milli> duration = std::chrono::high_resolution_clock::now() -
418 const double duration_ms = duration.count();
419 const int avg_frame_count = 8;
420 double avg_ms_tot = 0.0;
428 avg_ms_tot += ms_iter;
431 printf(
"VR frame render time: %.0fms - %.2f FPS (%.2f FPS 8 frames average)\n",
433 1000.0 / duration_ms,
437void GHOST_XrSession::endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> &layers)
439 XrFrameEndInfo end_info = {XR_TYPE_FRAME_END_INFO};
441 end_info.displayTime = draw_info_->frame_state.predictedDisplayTime;
442 end_info.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
443 end_info.layerCount = layers.size();
444 end_info.layers = layers.data();
446 CHECK_XR(xrEndFrame(oxr_->session, &end_info),
"Failed to submit rendered frame.");
448 if (context_->isDebugTimeMode()) {
455 std::vector<XrCompositionLayerProjectionView>
456 projection_layer_views;
457 XrCompositionLayerProjection proj_layer;
458 std::vector<XrCompositionLayerBaseHeader *> layers;
462 if (context_->getCustomFuncs().passthrough_enabled_fn(draw_customdata)) {
464 if (oxr_->passthrough_supported) {
465 layers.push_back((XrCompositionLayerBaseHeader *)&oxr_->passthrough_layer);
468 context_->getCustomFuncs().disable_passthrough_fn(draw_customdata);
472 if (draw_info_->frame_state.shouldRender) {
473 proj_layer = drawLayer(projection_layer_views, draw_customdata);
474 if (layers.size() > 0) {
475 proj_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
477 layers.push_back(
reinterpret_cast<XrCompositionLayerBaseHeader *
>(&proj_layer));
480 endFrameDrawing(layers);
488 r_info.fov.angle_left =
view.fov.angleLeft;
489 r_info.fov.angle_right =
view.fov.angleRight;
490 r_info.fov.angle_up =
view.fov.angleUp;
491 r_info.fov.angle_down =
view.fov.angleDown;
495 XrSwapchainImageBaseHeader &swapchain_image,
496 XrCompositionLayerProjectionView &r_proj_layer_view,
497 const XrSpaceLocation &view_location,
500 void *draw_customdata)
502 r_proj_layer_view.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
503 r_proj_layer_view.pose =
view.pose;
504 r_proj_layer_view.fov =
view.fov;
508 GHOST_XrDrawViewInfo draw_view_info = {};
509 draw_view_info.view_idx = char(view_idx);
510 draw_view_info.swapchain_format = swapchain.
getFormat();
511 draw_view_info.expects_srgb_buffer = swapchain.
isBufferSRGB();
512 draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
513 draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
514 draw_view_info.width = r_proj_layer_view.subImage.imageRect.extent.width;
515 draw_view_info.height = r_proj_layer_view.subImage.imageRect.extent.height;
520 context_->getCustomFuncs().draw_view_fn(&draw_view_info, draw_customdata);
521 gpu_binding_->submitToSwapchainImage(swapchain_image, draw_view_info);
524XrCompositionLayerProjection GHOST_XrSession::drawLayer(
525 std::vector<XrCompositionLayerProjectionView> &r_proj_layer_views,
void *draw_customdata)
527 XrViewLocateInfo viewloc_info = {XR_TYPE_VIEW_LOCATE_INFO};
528 XrViewLocateFoveatedRenderingVARJO foveated_info{
529 XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO,
nullptr,
true};
530 XrViewState view_state = {XR_TYPE_VIEW_STATE};
531 XrCompositionLayerProjection layer = {XR_TYPE_COMPOSITION_LAYER_PROJECTION};
532 XrSpaceLocation view_location{XR_TYPE_SPACE_LOCATION};
535 viewloc_info.viewConfigurationType = oxr_->view_type;
536 viewloc_info.displayTime = draw_info_->frame_state.predictedDisplayTime;
537 viewloc_info.space = oxr_->reference_space;
539 if (draw_info_->foveation_active) {
540 viewloc_info.next = &foveated_info;
543 CHECK_XR(xrLocateViews(oxr_->session,
549 "Failed to query frame view and projection state.");
551 assert(oxr_->swapchains.size() == view_count);
554 oxr_->view_space, oxr_->reference_space, viewloc_info.displayTime, &view_location),
555 "Failed to query frame view space");
557 r_proj_layer_views.resize(view_count);
558 std::vector<XrSwapchainImageBaseHeader *> swapchain_images;
559 swapchain_images.resize(view_count);
561 for (uint32_t view_idx = 0; view_idx < view_count; view_idx++) {
562 GHOST_XrSwapchain &swapchain = oxr_->swapchains[view_idx];
566 gpu_binding_->submitToSwapchainBegin();
567 for (uint32_t view_idx = 0; view_idx < view_count; view_idx++) {
568 GHOST_XrSwapchain &swapchain = oxr_->swapchains[view_idx];
569 XrSwapchainImageBaseHeader &swapchain_image = *swapchain_images[view_idx];
572 r_proj_layer_views[view_idx],
574 oxr_->views[view_idx],
578 gpu_binding_->submitToSwapchainEnd();
580 for (uint32_t view_idx = 0; view_idx < view_count; view_idx++) {
581 GHOST_XrSwapchain &swapchain = oxr_->swapchains[view_idx];
583 swapchain_images[view_idx] =
nullptr;
586 layer.space = oxr_->reference_space;
587 layer.viewCount = r_proj_layer_views.size();
588 layer.views = r_proj_layer_views.data();
595 return gpu_binding_ && gpu_binding_->needsUpsideDownDrawing(*gpu_ctx_);
606 if (oxr_->session == XR_NULL_HANDLE) {
609 switch (oxr_->session_state) {
610 case XR_SESSION_STATE_READY:
611 case XR_SESSION_STATE_SYNCHRONIZED:
612 case XR_SESSION_STATE_VISIBLE:
613 case XR_SESSION_STATE_FOCUSED:
632void GHOST_XrSession::bindGraphicsContext()
657 std::map<std::string, GHOST_XrActionSet>::iterator it = oxr->
action_sets.find(action_set_name);
666 std::map<std::string, GHOST_XrActionSet> &action_sets = oxr_->action_sets;
667 if (action_sets.find(info.name) != action_sets.end()) {
671 XrInstance instance = context_->getInstance();
674 std::piecewise_construct, std::make_tuple(info.name), std::make_tuple(instance, info));
681 std::map<std::string, GHOST_XrActionSet> &action_sets = oxr_->action_sets;
683 action_sets.erase(action_set_name);
688 const GHOST_XrActionInfo *infos)
691 if (action_set ==
nullptr) {
695 XrInstance instance = context_->getInstance();
697 for (uint32_t
i = 0;
i <
count; ++
i) {
708 const char *
const *action_names)
711 if (action_set ==
nullptr) {
715 for (uint32_t
i = 0;
i <
count; ++
i) {
722 const GHOST_XrActionProfileInfo *infos)
725 if (action_set ==
nullptr) {
729 XrInstance instance = context_->getInstance();
730 XrSession session = oxr_->session;
732 for (uint32_t profile_idx = 0; profile_idx <
count; ++profile_idx) {
733 const GHOST_XrActionProfileInfo &info = infos[profile_idx];
736 if (action ==
nullptr) {
748 const char *
const *action_names,
749 const char *
const *profile_paths)
752 if (action_set ==
nullptr) {
756 for (uint32_t
i = 0;
i <
count; ++
i) {
758 if (action ==
nullptr) {
769 std::map<XrPath, std::vector<XrActionSuggestedBinding>> profile_bindings;
770 for (
auto &[
name, action_set] : oxr_->action_sets) {
771 action_set.getBindings(profile_bindings);
774 if (profile_bindings.size() < 1) {
778 XrInteractionProfileSuggestedBinding bindings_info{
779 XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING};
780 XrInstance instance = context_->getInstance();
782 for (
auto &[profile, bindings] : profile_bindings) {
783 bindings_info.interactionProfile = profile;
784 bindings_info.countSuggestedBindings = uint32_t(bindings.size());
785 bindings_info.suggestedBindings = bindings.data();
787 CHECK_XR(xrSuggestInteractionProfileBindings(instance, &bindings_info),
788 "Failed to suggest interaction profile bindings.");
792 XrSessionActionSetsAttachInfo attach_info{XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO};
793 attach_info.countActionSets = uint32_t(oxr_->action_sets.size());
796 std::vector<XrActionSet> action_sets(attach_info.countActionSets);
798 for (
auto &[
name, action_set] : oxr_->action_sets) {
799 action_sets[
i++] = action_set.getActionSet();
801 attach_info.actionSets = action_sets.data();
803 CHECK_XR(xrAttachSessionActionSets(oxr_->session, &attach_info),
804 "Failed to attach XR action sets.");
811 std::map<std::string, GHOST_XrActionSet> &action_sets = oxr_->action_sets;
813 XrActionsSyncInfo sync_info{XR_TYPE_ACTIONS_SYNC_INFO};
814 sync_info.countActiveActionSets = (action_set_name !=
nullptr) ? 1 :
815 uint32_t(action_sets.size());
816 if (sync_info.countActiveActionSets < 1) {
820 std::vector<XrActiveActionSet> active_action_sets(sync_info.countActiveActionSets);
823 if (action_set_name !=
nullptr) {
825 if (action_set ==
nullptr) {
829 XrActiveActionSet &active_action_set = active_action_sets[0];
830 active_action_set.actionSet = action_set->
getActionSet();
831 active_action_set.subactionPath = XR_NULL_PATH;
835 for (
auto &[
name, action_set] : action_sets) {
836 XrActiveActionSet &active_action_set = active_action_sets[
i++];
837 active_action_set.actionSet = action_set.
getActionSet();
838 active_action_set.subactionPath = XR_NULL_PATH;
841 sync_info.activeActionSets = active_action_sets.data();
843 CHECK_XR(xrSyncActions(oxr_->session, &sync_info),
"Failed to synchronize XR actions.");
846 XrSession session = oxr_->session;
847 XrSpace reference_space = oxr_->reference_space;
848 const XrTime &predicted_display_time = draw_info_->frame_state.predictedDisplayTime;
850 if (action_set !=
nullptr) {
851 action_set->
updateStates(session, reference_space, predicted_display_time);
854 for (
auto &[
name, action_set] : action_sets) {
855 action_set.
updateStates(session, reference_space, predicted_display_time);
863 const char *action_name,
864 const char *subaction_path,
866 const float &frequency,
867 const float &litude)
870 if (action_set ==
nullptr) {
875 if (action ==
nullptr) {
880 oxr_->session, action_name, subaction_path, duration, frequency, amplitude);
886 const char *action_name,
887 const char *subaction_path)
890 if (action_set ==
nullptr) {
895 if (action ==
nullptr) {
905 if (action_set ==
nullptr) {
915 if (action_set ==
nullptr) {
920 if (action ==
nullptr) {
930 if (action_set ==
nullptr) {
938 void **r_customdata_array)
941 if (action_set ==
nullptr) {
957 if (!context_->isExtensionEnabled(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME)) {
961 XrSession session = oxr_->session;
962 std::map<std::string, GHOST_XrControllerModel> &controller_models = oxr_->controller_models;
963 std::map<std::string, GHOST_XrControllerModel>::iterator it = controller_models.find(
966 if (it == controller_models.end()) {
967 XrInstance instance = context_->getInstance();
968 it = controller_models
969 .emplace(std::piecewise_construct,
970 std::make_tuple(subaction_path),
971 std::make_tuple(instance, subaction_path))
975 it->second.load(session);
982 std::map<std::string, GHOST_XrControllerModel> &controller_models = oxr_->controller_models;
984 controller_models.erase(subaction_path);
989 XrSession session = oxr_->session;
990 std::map<std::string, GHOST_XrControllerModel>::iterator it = oxr_->controller_models.find(
992 if (it == oxr_->controller_models.end()) {
996 it->second.updateComponents(session);
1002 GHOST_XrControllerModelData &r_data)
1004 std::map<std::string, GHOST_XrControllerModel>::iterator it = oxr_->controller_models.find(
1006 if (it == oxr_->controller_models.end()) {
1010 it->second.getData(r_data);
1043void GHOST_XrSession::enablePassthrough()
1045 if (!context_->isExtensionEnabled(XR_FB_PASSTHROUGH_EXTENSION_NAME)) {
1046 oxr_->passthrough_supported =
false;
1050 if (oxr_->passthrough_layer.layerHandle != XR_NULL_HANDLE) {
1058 XrPassthroughCreateInfoFB passthrough_create_info = {};
1059 passthrough_create_info.type = XR_TYPE_PASSTHROUGH_CREATE_INFO_FB;
1060 passthrough_create_info.next =
nullptr;
1061 passthrough_create_info.flags |= XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB;
1063 XrPassthroughFB passthrough_handle;
1066 XrPassthroughLayerCreateInfoFB passthrough_layer_create_info;
1067 passthrough_layer_create_info.type = XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB;
1068 passthrough_layer_create_info.next =
nullptr;
1069 passthrough_layer_create_info.passthrough = passthrough_handle;
1070 passthrough_layer_create_info.flags |= XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB;
1071 passthrough_layer_create_info.purpose = XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB;
1073 XrPassthroughLayerFB passthrough_layer_handle;
1075 oxr_->session, &passthrough_layer_create_info, &passthrough_layer_handle);
1080 oxr_->passthrough_layer.type = XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB;
1081 oxr_->passthrough_layer.next =
nullptr;
1082 oxr_->passthrough_layer.flags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
1083 oxr_->passthrough_layer.space =
nullptr;
1084 oxr_->passthrough_layer.layerHandle = passthrough_layer_handle;
1086 oxr_->passthrough_supported = (
result == XR_SUCCESS);
GHOST C-API function and type declarations.
std::unique_ptr< GHOST_IXrGraphicsBinding > GHOST_XrGraphicsBindingCreateFromType(GHOST_TXrGraphicsBinding type, GHOST_Context &context)
static void init_passthrough_extension_functions(XrInstance instance)
static void create_reference_spaces(OpenXRSessionData &oxr, const GHOST_XrPose &base_pose, bool isDebugMode)
static void print_debug_timings(GHOST_XrDrawInfo &draw_info)
static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawViewInfo &r_info)
static PFN_xrCreatePassthroughLayerFB g_xrCreatePassthroughLayerFB
static PFN_xrPassthroughLayerResumeFB g_xrPassthroughLayerResumeFB
static PFN_xrCreatePassthroughFB g_xrCreatePassthroughFB
static PFN_xrPassthroughStartFB g_xrPassthroughStartFB
static GHOST_XrActionSet * find_action_set(OpenXRSessionData *oxr, const char *action_set_name)
void copy_openxr_pose_to_ghost_pose(const XrPosef &oxr_pose, GHOST_XrPose &r_ghost_pose)
#define INIT_EXTENSION_FUNCTION(name)
#define CHECK_XR_ASSERT(call)
#define CHECK_XR(call, error_msg)
void updateStates(XrSession session, XrSpace reference_space, const XrTime &predicted_display_time)
GHOST_XrAction * findAction(const char *action_name)
bool createAction(XrInstance instance, const GHOST_XrActionInfo &info)
XrActionSet getActionSet() const
void getActionCustomdataArray(void **r_customdata_array)
uint32_t getActionCount() const
void destroyAction(const char *action_name)
bool createBinding(XrInstance instance, XrSession session, const GHOST_XrActionProfileInfo &info)
void destroyBinding(const char *profile_path)
void applyHapticFeedback(XrSession session, const char *action_name, const char *subaction_path_str, const int64_t &duration, const float &frequency, const float &litude)
void stopHapticFeedback(XrSession session, const char *action_name, const char *subaction_path_str)
Main GHOST container to manage OpenXR through.
XrInstance getInstance() const
const GHOST_XrCustomFuncs & getCustomFuncs() const
bool isExtensionEnabled(const char *ext) const
void destroyActionBindings(const char *action_set_name, uint32_t count, const char *const *action_names, const char *const *profile_paths)
void destroyActionSet(const char *action_set_name)
void draw(void *draw_customdata)
bool createActionSet(const GHOST_XrActionSetInfo &info)
void * getActionCustomdata(const char *action_set_name, const char *action_name)
void unloadControllerModel(const char *subaction_path)
void * getActionSetCustomdata(const char *action_set_name)
bool updateControllerModelComponents(const char *subaction_path)
bool createActionBindings(const char *action_set_name, uint32_t count, const GHOST_XrActionProfileInfo *infos)
GHOST_XrSession(GHOST_XrContext &xr_context)
void stopHapticAction(const char *action_set_name, const char *action_name, const char *subaction_path)
LifeExpectancy handleStateChangeEvent(const XrEventDataSessionStateChanged &lifecycle)
void getActionCustomdataArray(const char *action_set_name, void **r_customdata_array)
bool loadControllerModel(const char *subaction_path)
bool syncActions(const char *action_set_name=nullptr)
bool needsUpsideDownDrawing() const
void start(const GHOST_XrSessionBeginInfo *begin_info)
void destroyActions(const char *action_set_name, uint32_t count, const char *const *action_names)
void unbindGraphicsContext()
bool applyHapticAction(const char *action_set_name, const char *action_name, const char *subaction_path, const int64_t &duration, const float &frequency, const float &litude)
uint32_t getActionCount(const char *action_set_name)
bool getControllerModelData(const char *subaction_path, GHOST_XrControllerModelData &r_data)
bool createActions(const char *action_set_name, uint32_t count, const GHOST_XrActionInfo *infos)
GHOST_TXrSwapchainFormat getFormat() const
void updateCompositionLayerProjectViewSubImage(XrSwapchainSubImage &r_sub_image)
bool isBufferSRGB() const
XrSwapchainImageBaseHeader * acquireDrawableSwapchainImage()
#define assert(assertion)
GHOST_XrGraphicsContextUnbindFn gpu_ctx_unbind_fn
GHOST_XrGraphicsContextBindFn gpu_ctx_bind_fn
std::chrono::high_resolution_clock::time_point frame_begin_time
std::list< double > last_frame_times
XrSpace combined_eye_space
XrCompositionLayerPassthroughFB passthrough_layer
std::map< std::string, GHOST_XrControllerModel > controller_models
bool passthrough_supported
XrViewConfigurationType view_type
std::map< std::string, GHOST_XrActionSet > action_sets
XrSessionState session_state
std::vector< GHOST_XrSwapchain > swapchains
std::vector< XrView > views