Guida rapida di Google Cardboard per Android NDK

Questa guida illustra come utilizzare l'SDK Cardboard. per Android per creare le tue esperienze di realtà virtuale (VR).

Puoi utilizzare l'SDK di Cardboard per trasformare uno smartphone in una piattaforma per la realtà virtuale. Uno smartphone può visualizzare scene 3D con rendering stereoscopico, monitorare e reagire ai movimenti della testa, e interagire con le app, rilevando quando l'utente preme il pulsante del visualizzatore.

Per iniziare, utilizzerai HelloCardboard, un gioco demo che dimostra le caratteristiche principali caratteristiche dell'SDK di Cardboard. Nel gioco gli utenti si guardano in tutto il mondo virtuale per trovare per raccogliere oggetti. Ti spiega come:

  • Configurazione dell'ambiente di sviluppo
  • Scarica e crea l'app demo
  • Scansiona il codice QR di un visore Cardboard per salvarne i parametri
  • Monitora i movimenti della testa dell'utente
  • Esegui il rendering delle immagini stereoscopiche impostando la matrice di proiezione corretta per ciascun occhio

HelloCardboard utilizza Android NDK. Ogni metodo nativo è:

  • Limitato in modo univoco a un metodo di classe HelloCardboardApp oppure
  • Crea o elimina un'istanza della classe in questione

Configurazione dell'ambiente di sviluppo

Requisiti hardware:

  • Dispositivo Android con Android 8.0 "Oreo" (livello API 26) o superiore
  • Visore di cartone
di Gemini Advanced.

Requisiti software:

  • Android Studio versione 2022.1.1 "Electric Eel" o successiva
  • SDK Android 13.0 "Tiramisù" (livello API 33) o superiore
  • Ultima versione del framework Android NDK

    Per esaminare o aggiornare gli SDK installati, vai a Preferenze > Aspetto e comportamento

    Impostazioni di sistema > L'SDK Android in Android Studio.

Scarica e crea l'app demo

L'SDK di Cardboard è stato creato utilizzando un file Vulkan precompilato di intestazione per ogni shadowr. Qui puoi trovare i passaggi per creare i file di intestazione da zero qui

  1. Esegui questo comando per clonare l'SDK Cardboard e la demo HelloCardboard app da GitHub:

    git clone https://github.com/googlevr/cardboard.git
  2. In Android Studio, seleziona Apri un progetto Android Studio esistente, quindi seleziona la in cui sono stati clonati l'SDK Cardboard e l'app demo HelloCardboard.

    Il codice verrà visualizzato nella finestra Progetto in Android Studio.

  3. Per assemblare l'SDK Cardboard, fai doppio clic sull'opzione assembla all'interno cardboard/:sdk/Tasks/build nella scheda Gradle (Visualizza > Finestre strumenti > Gradle).

  4. Esegui l'app demo HelloCardboard sul tuo smartphone selezionando Esegui > Esegui... e seleziona il target hellocardboard-android.

Scansiona il codice QR

Per salvare i parametri del dispositivo, scansiona il codice QR sul visualizzatore Cardboard:

Se l'utente preme "IGNORA" e non ci sono parametri salvati in precedenza, Parametri di Google Cardboard v1 (lanciato a Google I/O 2014).

Prova la demo

In HelloCardboard dovrai cercare e raccogliere le sfere geodetiche nello spazio 3D.

Per trovare e raccogliere una sfera:

  1. Muovi la testa in qualsiasi direzione finché non vedi una forma fluttuante.

  2. Guarda dritto nella sfera. Questo fa sì che cambi colore.

  3. Premi il pulsante del visore Cardboard per "raccogliere" nella sfera.

Configura il dispositivo

Quando l'utente tocca l'icona dell'ingranaggio per passare da un visualizzatore Cardboard, l'nativeSwitchViewer . nativeSwitchViewer chiamate CardboardQrCode_scanQrCodeAndSaveDeviceParams, che apre la finestra di cui eseguire la scansione il codice QR dello spettatore. La distorsione dell'obiettivo e gli altri parametri dello spettatore vengono aggiornati una volta viene scansionato il codice QR.

// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

Attiva l'emulatore Android Studio x86

Per sviluppare l'emulatore Android Studio x86, rimuovi la riga seguente da build.gradle file nell'SDK e Esempio:

abiFilters 'armeabi-v7a', 'arm64-v8a'

In questo modo vengono attivate tutte le ABI e aumenterà significativamente le dimensioni .aar. Vedi le ABI Android per ulteriori informazioni.

Rilevamento dei movimenti della testa

Crea tracker della testa

Il tracker della testa viene creato una volta nel costruttore di HelloCardboardApp:

HelloCardboardApp::HelloCardboardApp(JavaVM* vm, jobject obj, jobject asset_mgr_obj) {
  Cardboard_initializeAndroid(vm, obj); // Must be called in constructor
  head_tracker_ = CardboardHeadTracker_create();
}

Quando viene creata VrActivity, viene generata un'istanza della classe HelloCardboardApp richiamando il metodo nativeOnCreate:

public void onCreate(Bundle savedInstance) {
  super.onCreate(savedInstance);
  nativeApp = nativeOnCreate(getAssets());
  //...
}

Metti in pausa e riprendi il tracker della testa

Per mettere in pausa, riprendere e distruggere il tracker della testa, CardboardHeadTracker_pause(head_tracker_), CardboardHeadTracker_resume(head_tracker_), e CardboardHeadTracker_destroy(head_tracker_). Nella "HelloCardboard" nell'app, li chiamiamo in nativeOnPause, nativeOnResume e nativeOnDestroy:

// Code to pause head tracker in hello_cardboard_app.cc

void HelloCardboardApp::OnPause() { CardboardHeadTracker_pause(head_tracker_); }

// Call nativeOnPause in VrActivity
@Override
protected void onPause() {
  super.onPause();
  nativeOnPause(nativeApp);
  //...
}

// Code to resume head tracker in hello_cardboard_app.cc
void HelloCardboardApp::onResume() {
  CardboardHeadTracker_resume(head_tracker_);
  //...
}

// Call nativeOnResume in VrActivity
@Override
protected void onResume() {
  super.onResume();
  //...
  nativeOnResume(nativeApp);
}

// Code to destroy head tracker in hello_cardboard_app.cc
HelloCardboardApp::~HelloCardboardApp() {
  CardboardHeadTracker_destroy(head_tracker_);
  //...
}

// Call nativeOnDestroy in VrActivity
@Override
protected void onDestroy() {
  super.onDestroy();
  nativeOnDestroy(nativeApp);
  nativeApp = 0;
}

Distorsione dell'obiettivo

Ogni volta che Cardboard scansiona un nuovo codice QR, i parametri salvati vengono letti dal codice seguente e li utilizza per creare l'oggetto di distorsione dell'obiettivo, che applica la distorsione dell'obiettivo corretta. ai contenuti visualizzati:

CardboardQrCode_getSavedDeviceParams(&buffer, &size);

CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
    buffer, size, screen_width_, screen_height_);

CardboardQrCode_destroy(buffer);

Rendering

Il rendering dei contenuti in Cardboard prevede quanto segue:

  • Creazione di texture
  • Recupero delle matrici di visualizzazione e proiezione per gli occhi destro e sinistro
  • Creazione del renderer e impostazione della mesh di distorsione
  • Rendering di ogni frame

Crea texture

Tutti i contenuti vengono tracciati su una texture, divisa in sezioni per gli occhi a sinistra e a destra. Queste sezioni sono inizializzate rispettivamente in _leftEyeTexture e _rightEyeTexture.

void HelloCardboardApp::GlSetup() {
  LOGD("GL SETUP");

  if (framebuffer_ != 0) {
    GlTeardown();
  }

  // Create render texture.
  glGenTextures(1, &texture_);
  glBindTexture(GL_TEXTURE_2D, texture_);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width_, screen_height_, 0,
               GL_RGB, GL_UNSIGNED_BYTE, 0);

  left_eye_texture_description_.texture = texture_;
  left_eye_texture_description_.left_u = 0;
  left_eye_texture_description_.right_u = 0.5;
  left_eye_texture_description_.top_v = 1;
  left_eye_texture_description_.bottom_v = 0;

  right_eye_texture_description_.texture = texture_;
  right_eye_texture_description_.left_u = 0.5;
  right_eye_texture_description_.right_u = 1;
  right_eye_texture_description_.top_v = 1;
  right_eye_texture_description_.bottom_v = 0;

  //...
  CHECKGLERROR("GlSetup");
}

Queste texture vengono passate come parametri a CardboardDistortionRenderer_renderEyeToDisplay.

Ottieni matrici di visualizzazione e proiezione per l'occhio destro e sinistro

Innanzitutto, recupera le matrici degli occhi per gli occhi sinistro e destro:

CardboardLensDistortion_getEyeFromHeadMatrix(
    lens_distortion_, kLeft, eye_matrices_[0]);
CardboardLensDistortion_getEyeFromHeadMatrix(
    lens_distortion_, kRight, eye_matrices_[1]);
CardboardLensDistortion_getProjectionMatrix(
    lens_distortion_, kLeft, kZNear, kZFar, projection_matrices_[0]);
CardboardLensDistortion_getProjectionMatrix(
    lens_distortion_, kRight, kZNear, kZFar, projection_matrices_[1]);

Quindi, ottieni le mesh di distorsioni per ciascuno degli occhi e passale al renderer di distorsione:

CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);

Creare il renderer e impostare la mesh di distorsione corretta.

Il renderer deve essere inizializzato una sola volta. Dopo aver creato il renderer, imposta il nuovo renderer distorsione della mesh degli occhi a destra e a sinistra in base ai valori di mesh restituiti dalla Funzione CardboardLensDistortion_getDistortionMesh.

distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);

Rendering dei contenuti

Per ogni fotogramma, recupera l'orientamento corrente della testa da CardboardHeadTracker_getPose:

CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);

Usa l'orientamento corrente della testa con le matrici di vista e proiezione per comporre una vista una matrice di proiezione per ciascuno degli occhi e visualizzare i contenuti sullo schermo:

// Draw eyes views
for (int eye = 0; eye < 2; ++eye) {
  glViewport(eye == kLeft ? 0 : screen_width_ / 2, 0, screen_width_ / 2,
             screen_height_);

  Matrix4x4 eye_matrix = GetMatrixFromGlArray(eye_matrices_[eye]);
  Matrix4x4 eye_view = eye_matrix * head_view_;

  Matrix4x4 projection_matrix =
      GetMatrixFromGlArray(projection_matrices_[eye]);
  Matrix4x4 modelview_target = eye_view * model_target_;
  modelview_projection_target_ = projection_matrix * modelview_target;
  modelview_projection_room_ = projection_matrix * eye_view;

  // Draw room and target. Replace this to render your own content.
  DrawWorld();
}

Usa CardboardDistortionRenderer_renderEyeToDisplay per applicare la distorsione correzione dei contenuti ed eseguire il rendering dei contenuti sullo schermo.

// Render
CardboardDistortionRenderer_renderEyeToDisplay(
    distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
    screen_width_, screen_height_, &left_eye_texture_description_,
    &right_eye_texture_description_);