Split the keyboard onto its own translucent OpenXR quad
build / build (push) Successful in 1m52s

Expand the on-screen keyboard to a full US layout (letters, digits,
punctuation, Shift layer, Tab, arrows, F1-F12, one-shot Ctrl/Alt
modifiers), make it a persistent, movable, closeable panel via a
title-bar drag handle, and lower its opacity.

Previously the keyboard was just a second panel swapped into the same
quad as the menu launcher, which made the launcher translucent too and
made the keyboard and menu mutually exclusive. Extract the shared
swapchain/JNI/touch-dispatch plumbing into two generic, reusable
modules - xr_swapchain.c (swapchain + per-image FBO setup) and
xr_overlay.c (an off-screen Android View rendered into its own OpenXR
quad, hit-tested via a laser pointer) - and make the menu launcher and
keyboard two independent XrOverlay instances instead of one. The
controller's menu button now only opens/closes the launcher; the
launcher's "Keyboard" button only opens the keyboard - so the keyboard
can stay up while picking something from the menu, and only the
keyboard's own Close button hides it.

xr_menu.c/.h are gone, fully absorbed into xr_overlay.c. On the Java
side, OverlayPanel.java carries the shared off-screen-render/touch/
cursor plumbing that MenuOverlay and the new KeyboardOverlay both
subclass.
This commit is contained in:
ml
2026-08-14 06:43:44 +02:00
parent 2d8fb49bf5
commit 3be310ade6
16 changed files with 1897 additions and 1102 deletions
+55
View File
@@ -0,0 +1,55 @@
// Generic OpenXR swapchain + per-image GL framebuffer helper, shared by
// every quad this app submits - the game quad (xr_session.c) and every
// xr_overlay.c instance (menu launcher, keyboard) - since they all need
// exactly the same setup, just at their own size/format.
#ifndef QUESTSHOCK_XR_SWAPCHAIN_H
#define QUESTSHOCK_XR_SWAPCHAIN_H
#include <stdbool.h>
#include <stdint.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <jni.h>
#define XR_USE_PLATFORM_ANDROID 1
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
// Up to this many swapchain images/FBOs - real runtimes report small counts
// (2-4); this is just a fixed upper bound for the cache arrays below.
#define XR_SWAPCHAIN_MAX_IMAGES 8
typedef struct {
XrSwapchain swapchain;
GLuint fbos[XR_SWAPCHAIN_MAX_IMAGES];
uint32_t image_count;
int width;
int height;
} XrSwapchainState;
// Creates the swapchain and wraps each of its images in its own GL
// framebuffer, ready to bind and render into directly. instance is only
// used to log a human-readable error string on failure.
bool xr_swapchain_create(XrInstance instance, XrSession session, int64_t format, int width,
int height, XrSwapchainState *out);
void xr_swapchain_destroy(XrSwapchainState *state);
// Acquires the next image, waits for the runtime to finish with it, and
// binds its framebuffer (sized to exactly fill it) as the current render
// target.
bool xr_swapchain_acquire(XrInstance instance, XrSwapchainState *state);
void xr_swapchain_release(XrInstance instance, XrSwapchainState *state);
#ifdef __cplusplus
}
#endif
#endif