- xr_input.c/h: an OpenXR action set (aim pose, trigger/select click, a menu-toggle button) plus ray/quad hit-testing, and a visible laser-pointer line drawn from the controller toward the hit point. - xr_menu.c/h + MenuOverlay.java: a second composition-layer quad, toggled by a controller button, showing an off-screen, never-attached Android View tree (one "Keyboard" button so far) driven by synthetic touch events computed from the laser ray's hit UV. - Migrate gl4es from a prebuilt binary baked into the Docker build-image to a vendored source snapshot (android/gl4es-src/) compiled from source at APK build time via CMake add_subdirectory(), patched through a new android/gl4es-patches/ (mirrors the existing engine-patches/ pattern). This was needed to track down and fix a bug hit while building the menu: gl4es's fixed-pipeline emulation (fpe.c) was unconditionally substituting its own shader onto the menu's draw call (fpe_ReleventState() always sets alphafunc to a nonzero sentinel, so its fpe_IsEmpty() check could never see the state as empty), making the menu quad show the game's own rendering instead of its own content. Fixed by routing the menu's blit through a real glBlitFramebuffer() call instead of a shader-based draw, which gl4es's fpe.c has nothing to intercept - documented in README.md's new "Debugging notes" section. - Renumber android/engine-patches/ to close the gap left by removing an unrelated diagnostic-only patch, and strip investigation-journal comments and dead diagnostic code (temporary tracing, env-var probes) left over from finding the bug above. - Restructure README.md into numbered sections, document every engine/gl4es patch, add Android Studio dev/testing-cycle instructions, and generalize Quest-specific wording to any OpenXR headset. Update NOTICE.txt to match (gl4es is now vendored/patched source, not a prebuilt binary; add the OpenXR-SDK loader).
This commit is contained in:
+60
-20
@@ -4,18 +4,25 @@ apply plugin: 'com.android.application'
|
||||
// build-apk.sh, or standalone with --host-paths to prep for a native
|
||||
// build in Android Studio - see README) since they're only known at
|
||||
// prep/build time, not something a checked-in build.gradle can hardcode.
|
||||
// engineDir is the scratch, patched copy of engine/; prebuiltDir is the
|
||||
// Android SDL2/SDL2_mixer/fluidsynth-lite/gl4es prebuilts - both point
|
||||
// into this container's own paths for build-apk.sh's own gradlew call,
|
||||
// or host-resolvable paths (plus a host-side export of prebuiltDir, since
|
||||
// /opt/prebuilt/android only exists in the image) when prepared with
|
||||
// --host-paths for Android Studio.
|
||||
// engineDir is the scratch, patched copy of engine/; gl4esDir is the
|
||||
// scratch, patched copy of android/gl4es-src/ (built from source as a
|
||||
// CMake subdirectory of engine/'s own native build below, not prebuilt);
|
||||
// prebuiltDir is the Android SDL2/SDL2_mixer/fluidsynth-lite/openxr
|
||||
// prebuilts - all point into this container's own paths for
|
||||
// build-apk.sh's own gradlew call, or host-resolvable paths (plus a
|
||||
// host-side export of prebuiltDir, since /opt/prebuilt/android only
|
||||
// exists in the image) when prepared with --host-paths for Android
|
||||
// Studio.
|
||||
def engineProps = new Properties()
|
||||
file("${projectDir}/../engine.properties").withInputStream { engineProps.load(it) }
|
||||
def engineDir = engineProps.getProperty('engineDir')
|
||||
if (engineDir == null) {
|
||||
throw new GradleException("android/engine.properties is missing 'engineDir' - run via build-apk.sh or prepare-android-project.sh, not gradlew directly")
|
||||
}
|
||||
def gl4esDir = engineProps.getProperty('gl4esDir')
|
||||
if (gl4esDir == null) {
|
||||
throw new GradleException("android/engine.properties is missing 'gl4esDir' - run via build-apk.sh or prepare-android-project.sh, not gradlew directly")
|
||||
}
|
||||
def prebuiltDir = engineProps.getProperty('prebuiltDir')
|
||||
if (prebuiltDir == null) {
|
||||
throw new GradleException("android/engine.properties is missing 'prebuiltDir' - run via build-apk.sh or prepare-android-project.sh, not gradlew directly")
|
||||
@@ -27,14 +34,29 @@ if (prebuiltDir == null) {
|
||||
def questshockVersionName = project.hasProperty('questshockVersionName') ? project.property('questshockVersionName') : '0.0.0-dev'
|
||||
def questshockVersionCode = project.hasProperty('questshockVersionCode') ? project.property('questshockVersionCode').toInteger() : 1
|
||||
|
||||
// Auto-refreshes the staged, patched engine/ copy and prebuilt libraries
|
||||
// (see build-image/prepare-android-project.sh --host-paths, and the
|
||||
// engineDir/prebuiltDir properties read above) so a plain Android Studio
|
||||
// build/run can never silently compile against a stale scratch copy after
|
||||
// engine/ or android/engine-patches/ change - previously a manual, easy to
|
||||
// forget re-run. inputs/outputs are declared so Gradle skips the (Docker-
|
||||
// invoking, not free) step entirely when nothing relevant actually changed,
|
||||
// keeping pure-Java edit/run cycles fast.
|
||||
// Auto-refreshes the staged, patched engine/ and gl4es-src/ copies and
|
||||
// prebuilt libraries (see build-image/prepare-android-project.sh
|
||||
// --host-paths, and the engineDir/gl4esDir/prebuiltDir properties read
|
||||
// above) so a plain Android Studio build/run can never silently compile
|
||||
// against a stale scratch copy after engine/, android/engine-patches/,
|
||||
// android/gl4es-src/, or android/gl4es-patches/ change - previously a
|
||||
// manual, easy to forget re-run. inputs/outputs are declared so Gradle
|
||||
// skips the (Docker-invoking, not free) step entirely when nothing
|
||||
// relevant actually changed, keeping pure-Java edit/run cycles fast.
|
||||
//
|
||||
// This step only re-stages whatever is already baked into the build-image
|
||||
// (it re-runs prepare-android-project.sh inside the existing image, which
|
||||
// is fast - no compilation happens here) - engine/ and gl4es-src/ are both
|
||||
// then compiled from these scratch copies by the externalNativeBuild CMake
|
||||
// configure below (see android/engine-patches/02-android-opengl-es.patch's
|
||||
// add_subdirectory of gl4esDir), so Gradle's own incremental CMake/Ninja
|
||||
// build only recompiles what actually changed, same as any other native
|
||||
// source edit. This task does NOT rebuild the image itself: if you changed
|
||||
// build-image/Dockerfile (a real toolchain/dependency change, not
|
||||
// engine-patches/ or gl4es-patches/, which this task re-stages on its own),
|
||||
// you still need to run ./build-image.sh yourself first (a slow, deliberate
|
||||
// step - see the memory on build-image versioning) so the image actually
|
||||
// contains your changes before this task re-stages them.
|
||||
def repoRoot = file("${projectDir}/../..")
|
||||
def stageEngineTask = tasks.register("stageEngine", Exec) {
|
||||
group = "build setup"
|
||||
@@ -55,8 +77,11 @@ def stageEngineTask = tasks.register("stageEngine", Exec) {
|
||||
|
||||
inputs.dir("${repoRoot}/engine")
|
||||
inputs.dir("${projectDir}/../engine-patches")
|
||||
inputs.dir("${projectDir}/../gl4es-src")
|
||||
inputs.dir("${projectDir}/../gl4es-patches")
|
||||
inputs.file("${repoRoot}/build-image/Dockerfile")
|
||||
outputs.dir("${repoRoot}/build/android-engine")
|
||||
outputs.dir("${repoRoot}/build/android-gl4es")
|
||||
outputs.dir("${repoRoot}/build/android-prebuilt")
|
||||
outputs.file("${projectDir}/../engine.properties")
|
||||
}
|
||||
@@ -102,8 +127,12 @@ android {
|
||||
// SDL2_mixer and FluidSynth via the same build_ext/ BUNDLED
|
||||
// convention the desktop build already uses (populated in the
|
||||
// scratch engine copy by prepare-android-project.sh from
|
||||
// prebuiltDir). ANDROID_PREBUILT_DIR is also read directly by
|
||||
// android/engine-patches/02-android-opengl-es.patch, for gl4es.
|
||||
// prebuiltDir). ANDROID_GL4ES_DIR is read by
|
||||
// android/engine-patches/02-android-opengl-es.patch, which
|
||||
// add_subdirectory()'s it to compile gl4es from source as
|
||||
// part of this same CMake configure, instead of linking a
|
||||
// prebuilt .so - so gl4es-patches/ changes just need a normal
|
||||
// rebuild here, not a build-image rebuild.
|
||||
// The CMAKE_FIND_ROOT_PATH* overrides below are needed
|
||||
// because the NDK toolchain file restricts find_package/
|
||||
// find_path/find_library to its own sysroot by default,
|
||||
@@ -113,17 +142,28 @@ android {
|
||||
// -Wl,-z,max-page-size=16384: NDK 26 doesn't 16 KB-align ELF
|
||||
// LOAD segments by default (only automatic in NDK 28+) - see
|
||||
// build-image/Dockerfile's ANDROID_16KB_LDFLAGS, which does
|
||||
// the same for the prebuilt SDL2/SDL2_mixer/fluidsynth-lite/
|
||||
// gl4es .so's this links against.
|
||||
// the same for the prebuilt SDL2/SDL2_mixer/fluidsynth-lite
|
||||
// .so's this links against (gl4es is compiled here with the
|
||||
// same flag passed straight through, see its add_subdirectory
|
||||
// above).
|
||||
// ANDROID_EXTRA_SOURCES is a semicolon-separated CMake list,
|
||||
// not shell-split - AGP passes each "arguments" string
|
||||
// straight through as one argv element to cmake, so the
|
||||
// ';' below survives intact. ANDROID_EXTRA_INCLUDE_DIRS lets
|
||||
// engine/'s own OpenGL.cc find "xr_session.h" (see
|
||||
// android/engine-patches/11-android-openxr-cmake.patch,
|
||||
// android/engine-patches/10-android-openxr-cmake.patch,
|
||||
// which adds it to include_directories()).
|
||||
// USE_ANDROID_LOG/STATICLIB used to be passed to gl4es's own,
|
||||
// separate cmake invocation in build-image/Dockerfile - now
|
||||
// that it's add_subdirectory()'d into this same configure,
|
||||
// they need to be set here instead, or gl4es silently falls
|
||||
// back to stdio logging, which never reaches logcat. ANDROID
|
||||
// itself doesn't need setting here - the NDK toolchain file
|
||||
// already defines it before any CMakeLists.txt runs.
|
||||
arguments "-DENABLE_SDL2=ON", "-DENABLE_SOUND=BUNDLED", "-DENABLE_FLUIDSYNTH=BUNDLED", \
|
||||
"-DANDROID_PREBUILT_DIR=${prebuiltDir}", \
|
||||
"-DANDROID_GL4ES_DIR=${gl4esDir}", \
|
||||
"-DUSE_ANDROID_LOG=ON", "-DSTATICLIB=OFF", \
|
||||
"-DANDROID_EXTRA_INCLUDE_DIRS=${projectDir}/src/main/cpp", \
|
||||
"-DCMAKE_PREFIX_PATH=${prebuiltDir}/sdl2", \
|
||||
"-DCMAKE_FIND_ROOT_PATH=${prebuiltDir}/sdl2", \
|
||||
@@ -131,7 +171,7 @@ android {
|
||||
"-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH", \
|
||||
"-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH", \
|
||||
"-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384", \
|
||||
"-DANDROID_EXTRA_SOURCES=${projectDir}/src/main/cpp/questshock_native.c;${projectDir}/src/main/cpp/xr_session.c"
|
||||
"-DANDROID_EXTRA_SOURCES=${projectDir}/src/main/cpp/questshock_native.c;${projectDir}/src/main/cpp/xr_session.c;${projectDir}/src/main/cpp/xr_input.c;${projectDir}/src/main/cpp/xr_menu.c"
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user