// Minimal OpenXR bring-up for questshock's immersive Quest build. Keeps the // game's own rendering untouched (see android/engine-patches/ // 11-android-openxr-present.patch) - this module only owns the OpenXR // instance/session/swapchains and the final "submit quad layers instead of // presenting to a window" step. No stereo rendering - the game composite is // shown as a single flat quad floating in front of the viewer. #ifndef QUESTSHOCK_XR_SESSION_H #define QUESTSHOCK_XR_SESSION_H #include #include "xr_overlay.h" #ifdef __cplusplus extern "C" { #endif // Call once, right after init_opengl() (OpenGL.cc) has created and made // current the GL context SDL/gl4es already use - creates the OpenXR // instance/session sharing that same EGL display/context, plus the game // quad's own swapchain, sized to the game's logical resolution // (game_width/height, i.e. grd_cap->w/h - see Shock.c's InitSDL()). Also // creates the menu launcher and keyboard overlay quads (see xr_overlay.h) - // two independent XrOverlay instances, each with their own swapchain, // visibility, and position, retrievable via xr_session_get_menu_overlay()/ // xr_session_get_keyboard_overlay() below. Returns false if OpenXR // bring-up failed (e.g. no runtime installed) - callers should fall back // to the existing window-present path in that case. bool xr_init(int game_width, int game_height); // The menu launcher (small "Keyboard" button panel, toggled by the // controller's menu button) and keyboard (the on-screen key grid, shown/ // hidden independently via MenuOverlay's "Keyboard" button and // KeyboardOverlay's own Close button) overlay quads - used by xr_input.c // for ray/quad hit-testing and touch/cursor dispatch, and by // questshock_native.c's JNI glue (nativeShowKeyboard()/ // nativeRequestClose()). NULL if xr_init() failed before creating them. XrOverlay *xr_session_get_menu_overlay(void); XrOverlay *xr_session_get_keyboard_overlay(void); // Pumps XR session-state events. Call once per frame, before // xr_frame_begin(). Must still be called even when xr_init() returned // false (no-op in that case). void xr_poll_events(void); // True once the session has reached a state where frames are expected // (XR_SESSION_STATE_SYNCHRONIZED or later) - i.e. it's safe/required to // start calling xr_frame_begin()/xr_frame_end() each frame. bool xr_is_session_running(void); // Begins the XR frame (xrWaitFrame/xrBeginFrame) and, if the runtime wants // this frame rendered, acquires the game quad's next swapchain image and // binds its framebuffer as the current render target - ready for the // caller to draw into exactly as it would have drawn to the default // framebuffer. Returns true if the caller should draw this frame; // xr_frame_end() must be called unconditionally afterward either way (a // begun XR frame must always be ended, rendered or not). bool xr_frame_begin(void); // Releases the game quad's swapchain image (if one was acquired this // frame), then does the same acquire/render/release cycle for the menu // launcher and keyboard overlay quads via xr_overlay_render_and_build_layer() // for whichever of them is currently visible, and submits whichever of the // three quads actually rendered this frame as composition layers // positioned in front of the local reference space's origin, then ends the // XR frame. void xr_frame_end(void); void xr_shutdown(void); // Local-space geometry of the single game quad xr_frame_end() submits // (distance in front of the local space origin, half-width/half-height, // all in meters) - shared with xr_input.c's ray/quad hit-testing so the // laser pointer always matches whatever's actually visible. void xr_get_game_quad_extent(float *distance_m, float *half_width_m, float *half_height_m); // Pixel resolution of the game quad's own swapchain - i.e. game_width/ // game_height as passed to xr_init() (grd_cap->w/h, see Shock.c's // InitSDL()) - the logical coordinate space xr_input.c needs to convert a // game-quad ray hit's normalized u,v into engine mouse coordinates (see // xr_mouse.h). void xr_get_game_resolution(int *width, int *height); #ifdef __cplusplus } #endif #endif