621 XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl = {};
622 graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
623 graphics_binding_gl.xDisplay =
nullptr;
625 s->
window.getXlibHandles(&graphics_binding_gl.xDisplay,
626 &graphics_binding_gl.glxContext,
627 &graphics_binding_gl.glxDrawable);
631 &graphics_binding_gl);
633 XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl = {};
634 graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR;
635 graphics_binding_gl.next =
nullptr;
639 graphics_binding_gl.hDC = wglGetCurrentDC();
640 graphics_binding_gl.hGLRC = wglGetCurrentContext();
644 &graphics_binding_gl);
662 std::vector<Gl_interop_swapchain> swapchains;
663 for(
const auto& view : config_views){
664 swapchains.emplace_back(session.
get(),
665 selected_swapchain_fmt,
666 view.recommendedImageRectWidth,
667 view.recommendedImageRectHeight);
670 size_t view_count = config_views.size();
671 std::vector<XrCompositionLayerProjectionView> projection_views(view_count);
674 XrCompositionLayerProjection projection_layer;
675 projection_layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
676 projection_layer.next =
nullptr;
677 projection_layer.layerFlags = 0;
678 projection_layer.space = space.
get();
679 projection_layer.viewCount = view_count;
680 projection_layer.views = projection_views.data();
682 std::vector<XrView> views(view_count);
684 for(
auto& view : views){
685 view.type = XR_TYPE_VIEW;
689 for(
unsigned i = 0; i < view_count; i++){
690 projection_views[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
691 projection_views[i].next =
nullptr;
692 projection_views[i].subImage.swapchain = swapchains[i].get();
693 projection_views[i].subImage.imageArrayIndex = 0;
694 projection_views[i].subImage.imageRect.offset.x = 0;
695 projection_views[i].subImage.imageRect.offset.y = 0;
696 projection_views[i].subImage.imageRect.extent.width =
697 config_views[i].recommendedImageRectWidth;
698 projection_views[i].subImage.imageRect.extent.height =
699 config_views[i].recommendedImageRectHeight;
704 if(selected_swapchain_fmt == GL_SRGB8_ALPHA8_EXT){
710 glEnable(GL_FRAMEBUFFER_SRGB);
713 glm::mat4 view_reset_rot = glm::mat4(1.0f);
718 XrFrameState frame_state{};
719 frame_state.type = XR_TYPE_FRAME_STATE;
720 frame_state.next =
nullptr;
722 XrFrameWaitInfo frame_wait_info{};
723 frame_wait_info.type = XR_TYPE_FRAME_WAIT_INFO;
724 frame_wait_info.next =
nullptr;
727 result = xrWaitFrame(session.
get(), &frame_wait_info, &frame_state);
728 if (!XR_SUCCEEDED(result)){
733 bool reset_view =
false;
736 while(SDL_PollEvent(&event)){
741 case SDL_WINDOWEVENT:
742 if(event.window.event == SDL_WINDOWEVENT_RESIZED){
749 switch(event.key.keysym.sym){
754 if(event.type == SDL_KEYUP){
766 XrEventDataBuffer xr_event{};
767 xr_event.type = XR_TYPE_EVENT_DATA_BUFFER;
768 xr_event.next =
nullptr;
771 if(result != XR_SUCCESS){
775 switch(xr_event.type){
776 case XR_TYPE_EVENT_DATA_EVENTS_LOST:
779 case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
783 case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
785 XrEventDataSessionStateChanged*
event = (XrEventDataSessionStateChanged*) &xr_event;
786 if(event->state >= XR_SESSION_STATE_STOPPING){
799 XrViewLocateInfo view_locate_info;
800 view_locate_info.type = XR_TYPE_VIEW_LOCATE_INFO;
801 view_locate_info.displayTime = frame_state.predictedDisplayTime;
802 view_locate_info.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
803 view_locate_info.space = space.
get();
805 XrViewState view_state;
806 view_state.type = XR_TYPE_VIEW_STATE;
807 view_state.next =
nullptr;
809 uint32_t located_views = 0;
810 result = xrLocateViews(session.
get(),
817 if (!XR_SUCCEEDED(result)){
837 XrFrameBeginInfo frame_begin_info;
838 frame_begin_info.type = XR_TYPE_FRAME_BEGIN_INFO;
839 frame_begin_info.next =
nullptr;
842 result = xrBeginFrame(session.
get(), &frame_begin_info);
843 if (!XR_SUCCEEDED(result)){
848 for(
unsigned i = 0; i < view_count; i++){
851 XrSwapchainImageAcquireInfo swapchain_image_acquire_info;
852 swapchain_image_acquire_info.type = XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO;
853 swapchain_image_acquire_info.next =
nullptr;
856 result = xrAcquireSwapchainImage(
858 &swapchain_image_acquire_info,
861 if(!XR_SUCCEEDED(result)){
866 XrSwapchainImageWaitInfo swapchain_image_wait_info;
867 swapchain_image_wait_info.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO;
868 swapchain_image_wait_info.next =
nullptr;
869 swapchain_image_wait_info.timeout = 1000;
871 result = xrWaitSwapchainImage(swapchains[i].get(), &swapchain_image_wait_info);
872 if(!XR_SUCCEEDED(result)){
877 projection_views[i].pose = views[i].pose;
878 projection_views[i].fov = views[i].fov;
879 unsigned w = config_views[i].recommendedImageRectWidth;
880 unsigned h = config_views[i].recommendedImageRectHeight;
882 glm::mat4 projMat =
get_proj_mat(views[i].fov, 0.05f, 100.f);
884 const auto& rot = views[i].pose.orientation;
885 glm::mat4 viewMat = glm::mat4_cast(glm::quat(rot.w, rot.x, rot.y, rot.z));
888 view_reset_rot = viewMat;
890 glm::mat4 pvMat = projMat * glm::inverse(viewMat) * view_reset_rot;
892 auto framebuffer = swapchains[i].get_framebuffer(buf_idx).get();
893 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
894 glClear(GL_COLOR_BUFFER_BIT);
898 glBindFramebuffer(GL_FRAMEBUFFER, 0);
911 dstY1 = dstY0 + height;
915 dstX1 = dstX0 + width;
921 glClear(GL_COLOR_BUFFER_BIT);
922 glBlitNamedFramebuffer((GLuint)framebuffer,
932 (GLbitfield)GL_COLOR_BUFFER_BIT,
942 XrSwapchainImageReleaseInfo swapchain_image_release_info;
943 swapchain_image_release_info.type = XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO;
944 swapchain_image_release_info.next =
nullptr;
946 result = xrReleaseSwapchainImage(
948 &swapchain_image_release_info);
950 if (!XR_SUCCEEDED(result)){
956 const XrCompositionLayerBaseHeader *composition_layers = (
const XrCompositionLayerBaseHeader *) &projection_layer;
957 XrFrameEndInfo frame_end_info;
958 frame_end_info.type = XR_TYPE_FRAME_END_INFO;
959 frame_end_info.displayTime = frame_state.predictedDisplayTime;
960 frame_end_info.layerCount = 1;
961 frame_end_info.layers = &composition_layers;
962 frame_end_info.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
963 frame_end_info.next =
nullptr;
966 result = xrEndFrame(session.
get(), &frame_end_info);
967 if (!XR_SUCCEEDED(result)){