581af95e7b
build / build (push) Successful in 1m44s
The game quad's laser beam was purely visual - aiming at the game's own UI (inventory, menus, dialogs) had no way to interact with it. Add a real mouse pointer: absolute cursor position plus a single left click, mirroring a plain point-and-click mouse (no mouselook, no right-click, no drag). New xr_mouse.c/h bridges the aim-ray hit-test to the vendored engine's own public mouse API - mouse_put_xy() for position, a synthetic SDL_MOUSEBUTTONDOWN/UP (SDL_BUTTON_LEFT) via SDL_PushEvent for clicks, the same technique nativeSendPrintableChar() already uses for synthetic keyboard input. No engine patch needed. Deliberately bypasses SDLActivity.onNativeMouse()/SDL_MOUSEMOTION/SetMouseXY(), whose physical-window-size scaling is unreliable in this headless immersive build. xr_input_try_game_quad() now reports the hit u,v; a new g_game_touch_active[] tracks a held click on the game quad so it survives the ray straying onto the keyboard/menu before release, gating those overlays' claims the same way pending overlay touches already do.
89 lines
4.1 KiB
C
89 lines
4.1 KiB
C
// 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 <stdbool.h>
|
|
|
|
#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
|