ipin-vr/vr-poc/README.md
Oskar Kapala cc3d066854 feat(vr-poc): Phase 1 scaffold — native OpenXR passthrough + quad panel
NDK/C++ NativeActivity, arm64-v8a, Gradle 8.12 + AGP 8.7.3 + CMake 3.22.1.

Implementacja (main.cpp):
- EGL headless PBuffer context (wymagany przez OpenXR GLES binding)
- xrCreateInstance z XR_FB_passthrough + XR_KHR_opengl_es_enable
- xrCreateSession → XrGraphicsBindingOpenGLESAndroidKHR
- XR_FB_passthrough: xrCreatePassthroughFB / xrCreatePassthroughLayerFB
  (dynamiczne PFN, graceful fallback gdy extension niedostępna)
- Quad swapchain 512×256 — statyczny ciemnoniebieski panel 80×40 cm,
  1 m przed użytkownikiem (przygotowany pod stb_truetype w fazie 5)
- Pętla klatek: xrWaitFrame / xrBeginFrame / [passthrough + quad] / xrEndFrame
- environmentBlendMode = OPAQUE (passthrough przez warstwę FB_passthrough)

Brakujące pliki SDK (nie w git, lista w vr-poc/README.md):
- libs/arm64-v8a/libopenxr_loader.so   — z Meta OpenXR Mobile SDK
- ovr_sdk/OpenXR/Include/openxr/*.h    — nagłówki OpenXR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:33:27 +02:00

4.9 KiB

vr-poc — Phase 1: passthrough + quad panel (native OpenXR, Quest 3)

Natywna apka C++/NDK, arm64-v8a. Renderuje passthrough + jeden statyczny panel przed użytkownikiem. Brak LLM, brak TTS — czysty baseline do pomiaru FPS.

Szczegóły architektury: ../docs/POC_VR_SPEC.md.


Wymagane pliki SDK

Przed ./gradlew assembleDebug musisz zainstalować toolchain i wrzucić dwa zestawy plików. Poniżej dokładna lista — bez tych plików build nie przejdzie.

1. Android SDK + NDK + CMake

Zainstaluj przez Android Studio (SDK Manager) lub sdkmanager:

# Jeśli masz sdkmanager (cmdline-tools):
sdkmanager "platforms;android-35" \
           "build-tools;35.0.0" \
           "ndk;27.2.12479018" \
           "cmake;3.22.1"

Oczekiwane lokalizacje (domyślna instalacja Linux):

~/Android/Sdk/platforms/android-35/
~/Android/Sdk/build-tools/35.0.0/
~/Android/Sdk/ndk/27.2.12479018/
~/Android/Sdk/cmake/3.22.1/

Następnie skopiuj local.properties.templatelocal.properties (plik jest w .gitignore):

cp local.properties.template local.properties
# Upewnij się że sdk.dir wskazuje na Twój Android/Sdk

2. Meta OpenXR Mobile SDK — headery

Pobierz Meta OpenXR Mobile SDK z:

https://developer.oculus.com/downloads/package/oculus-openxr-mobile-sdk/

Aktualnie testowana wersja: v71 (lub nowsza).

Po pobraniu i rozpakowaniu skopiuj dokładnie te 4 pliki:

Źródło w archiwum SDK Cel w projekcie
OpenXR/Include/openxr/openxr.h ovr_sdk/OpenXR/Include/openxr/openxr.h
OpenXR/Include/openxr/openxr_platform.h ovr_sdk/OpenXR/Include/openxr/openxr_platform.h
OpenXR/Include/openxr/openxr_platform_defines.h ovr_sdk/OpenXR/Include/openxr/openxr_platform_defines.h
OpenXR/Include/openxr/openxr_reflection.h ovr_sdk/OpenXR/Include/openxr/openxr_reflection.h

Szybko przez jeden cp -r:

SDK_DIR=~/Downloads/ovr_sdk_mobile_openxr_v71   # dopasuj nazwę folderu
cp "$SDK_DIR"/OpenXR/Include/openxr/openxr*.h \
   /home/oskar/projects/ipin-vr/vr-poc/ovr_sdk/OpenXR/Include/openxr/

3. Meta OpenXR Mobile SDK — loader .so

Z tego samego archiwum SDK skopiuj loader do libs/arm64-v8a/:

Źródło w archiwum SDK Cel w projekcie
OpenXR/Libs/Android/arm64-v8a/Release/libopenxr_loader.so libs/arm64-v8a/libopenxr_loader.so
cp "$SDK_DIR"/OpenXR/Libs/Android/arm64-v8a/Release/libopenxr_loader.so \
   /home/oskar/projects/ipin-vr/vr-poc/libs/arm64-v8a/

Ten plik musi być w dwóch miejscach (albo możesz zrobić symlink):

  • libs/arm64-v8a/libopenxr_loader.so — dla Gradle (pakuje do APK jako lib/arm64-v8a/)
  • CMakeLists.txt czyta go z tej samej lokalizacji do linkowania

Build i deploy

cd vr-poc/

# Weryfikacja: upewnij się że te pliki istnieją
ls libs/arm64-v8a/libopenxr_loader.so
ls ovr_sdk/OpenXR/Include/openxr/openxr.h

# Build APK (debug)
./gradlew assembleDebug

# Install na Quest 3 (włącz Developer Mode, podłącz USB)
adb install -r app/build/outputs/apk/debug/app-debug.apk

# Logi z apki
adb logcat -s ipin-vr-poc

APK output: app/build/outputs/apk/debug/app-debug.apk


Weryfikacja Phase 1 (Definition of Done)

  • ./gradlew assembleDebug — SUCCESS
  • adb install — wchodzi na urządzenie
  • Apka startuje w passthrough (widać świat przez kamery)
  • Pływający ciemnoniebieski panel widoczny ~1 m przed użytkownikiem
  • OVR Metrics Tool pokazuje ≥ 72 FPS (brak stale frames)

Obserwacja FPS: uruchom OVR Metrics Tool na urządzeniu przed startem apki.


Struktura kodu

vr-poc/
  app/
    CMakeLists.txt          # CMake: native_app_glue + openxr_loader + ipin_vr_poc
    src/main/
      AndroidManifest.xml   # NativeActivity, com.oculus.feature.PASSTHROUGH
      cpp/
        main.cpp            # Cały OpenXR: EGL + passthrough + quad layer
      res/values/strings.xml
  libs/
    arm64-v8a/
      libopenxr_loader.so   # [WRZUĆ TU — patrz §2/§3 powyżej]
  ovr_sdk/
    OpenXR/Include/openxr/  # [WRZUĆ TU headery — patrz §2 powyżej]

Następne fazy (wg POC_VR_SPEC.md §12)

Faza Co dodajemy
2 llama.cpp worker, generacja na trigger (log tok/s)
3 CPU affinity konfigurowalna, pomiar wpływu na FPS
4 sherpa-onnx + Oboe TTS
5 stb_truetype — tekst polecenia na panelu
6 Soak 15 min, logowanie, wykres FPS/temp