Guide de démarrage rapide pour Google Cardboard pour le NDK Android

Ce guide explique comment utiliser le SDK Cardboard. pour Android afin de créer vos propres expériences de réalité virtuelle (RV).

Vous pouvez utiliser le SDK Cardboard pour transformer un smartphone en plate-forme de réalité virtuelle. Un smartphone peut afficher des scènes 3D avec rendu stéréoscopique, suivre les mouvements de la tête et réagir en conséquence, et interagir avec les applications en détectant le moment où l'utilisateur appuie sur le bouton de la visionneuse.

Pour commencer, vous allez utiliser HelloCardboard, un jeu de démonstration qui présente les du SDK Cardboard. Dans le jeu, les utilisateurs parcourent un monde virtuel pour trouver et collecter des objets. Il vous explique comment:

  • Configurer l'environnement de développement
  • Télécharger et créer l'application de démonstration
  • Scannez le code QR d'une visionneuse Cardboard pour enregistrer ses paramètres
  • Suivre les mouvements de la tête de l'utilisateur
  • Définissez la matrice de projection de vue appropriée pour chaque œil pour obtenir des images stéréoscopiques

HelloCardboard utilise le NDK Android. Chaque méthode native est:

  • est limitée de manière unique à une méthode de classe HelloCardboardApp ;
  • Crée ou supprime une instance de cette classe

Configurer l'environnement de développement

Configuration matérielle requise:

  • Appareil Android équipé d'Android 8.0 "Oreo" (niveau d'API 26) ou version ultérieure
  • Visionneuse Cardboard

Configuration logicielle requise:

  • Android Studio version 2022.1.1 "Electric Eel" ou supérieur
  • SDK Android 13.0 "Tiramisu" (niveau d'API 33) ou version ultérieure
  • La dernière version du framework du NDK Android

    Pour vérifier ou mettre à jour les SDK installés, accédez à Préférences > Apparence et comportement

    Paramètres système > SDK Android dans Android Studio

Télécharger et créer l'application de démonstration

Le SDK Cardboard est créé à l'aide d'une bibliothèque Vulkan précompilée. pour chaque nuanceur. Vous trouverez les étapes permettant de créer à partir de zéro les fichiers d'en-tête cliquez ici.

  1. Exécutez la commande suivante pour cloner le SDK Cardboard et la démonstration HelloCardboard. depuis GitHub:

    git clone https://github.com/googlevr/cardboard.git
  2. Dans Android Studio, sélectionnez Open an existing Android Studio Project (Ouvrir un projet Android Studio existant), puis sélectionnez le dans lequel le SDK Cardboard et l'application de démonstration HelloCardboard ont été clonés.

    Votre code s'affiche dans la fenêtre "Project" (Projet) d'Android Studio.

  3. Pour assembler le SDK Cardboard, double-cliquez sur l'option assemble dans cardboard/:sdk/Tasks/build dans l'onglet "Gradle" (Vue > Fenêtres d'outils > Gradle).

  4. Exécutez l'application de démonstration HelloCardboard sur votre téléphone en sélectionnant Run > Run... (Exécuter) et sélectionnez la cible hellocardboard-android.

Scanner le code QR

Pour enregistrer les paramètres de l'appareil, scannez le code QR sur la visionneuse Cardboard:

Si l'utilisateur appuie sur "IGNORER" et qu'aucun paramètre n'a été enregistré précédemment, Paramètres de Google Cardboard v1 (lancée lors de la conférence Google I/O en 2014).

Essayer la démo

Dans HelloCardboard, vous allez rechercher et collecter des sphères géodésiques dans un espace 3D.

Pour rechercher et collecter une sphère:

  1. Déplacez la tête dans n'importe quelle direction jusqu'à ce qu'une forme flottante apparaisse.

  2. Regardez directement la sphère. Cela entraîne un changement de couleur.

  3. Appuyez sur le bouton de la visionneuse Cardboard pour "recueillir" la sphère.

Configurer l'appareil

Lorsque l'utilisateur appuie sur l'icône en forme de roue dentée pour changer de visionneuse Cardboard, nativeSwitchViewer est appelée. nativeSwitchViewer appels CardboardQrCode_scanQrCodeAndSaveDeviceParams, qui ouvre la fenêtre de numérisation le code QR de l'utilisateur. La distorsion de l'objectif de l'utilisateur et les autres paramètres sont mis à jour une fois le code QR est scanné.

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

Activer l'émulateur Android Studio x86

Pour compiler pour l'émulateur Android Studio x86, supprimez la ligne suivante de build.gradle fichiers dans le SDK et Sample:

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

Cela permet d'activer toutes les ABI et d'augmenter considérablement la taille .aar. Voir ABI Android pour en savoir plus.

Suivi de la tête

Créer un outil de suivi des mouvements de la tête

L'outil de suivi des mouvements de la tête est créé une fois dans le constructeur de HelloCardboardApp:

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

Lorsque VrActivity est créé, une instance de la classe HelloCardboardApp est générée. en appelant la méthode nativeOnCreate:

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

Interrompre et reprendre le suivi des mouvements de la tête

Pour mettre en pause, reprendre et détruire le suivi des mouvements de la tête, CardboardHeadTracker_pause(head_tracker_), CardboardHeadTracker_resume(head_tracker_) et CardboardHeadTracker_destroy(head_tracker_) doivent être appelés respectivement. Dans "HelloCardboard" nous les appelons dans nativeOnPause, nativeOnResume et 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;
}

Distorsion de l'objectif

Chaque fois qu'Cardboard analyse un nouveau code QR, le code suivant lit les paramètres enregistrés et les utilise pour créer l'objet de distorsion de l'objectif, lequel applique la au contenu affiché:

CardboardQrCode_getSavedDeviceParams(&buffer, &size);

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

CardboardQrCode_destroy(buffer);

Affichage

Pour afficher du contenu dans une visionneuse, procédez comme suit:

  • Création de textures
  • Obtenir des matrices de vue et de projection pour les yeux gauche et droit
  • Créer le moteur de rendu et définir le maillage de distorsion
  • Afficher chaque image

Créer des textures

Tout le contenu est dessiné sur une texture, qui est divisée en sections pour l'œil gauche et l'œil droit. Ces sections sont respectivement initialisées dans _leftEyeTexture et _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");
}

Ces textures sont transmises en tant que paramètres à CardboardDistortionRenderer_renderEyeToDisplay.

Obtenir les matrices de vue et de projection pour l'œil gauche et l'œil droit

Commencez par récupérer les matrices oculaires des yeux gauche et droit:

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]);

Obtenez ensuite les maillages de distorsion pour chacun des yeux et transmettez-les au moteur de rendu de distorsion:

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

Créer le moteur de rendu et définir le maillage de distorsion approprié

Le moteur de rendu ne doit être initialisé qu'une seule fois. Une fois le moteur de rendu créé, définissez le nouveau grille de distorsion pour les yeux gauche et droit en fonction des valeurs de maillage renvoyées par fonction CardboardLensDistortion_getDistortionMesh.

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

Afficher le contenu

Pour chaque image, récupérez l'orientation actuelle de la tête à partir de CardboardHeadTracker_getPose:

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

Utiliser l'orientation actuelle de la tête avec les matrices de vue et de projection pour composer une vue matrice de projection pour chacun des yeux et affiche le contenu à l'écran:

// 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();
}

Utiliser CardboardDistortionRenderer_renderEyeToDisplay pour appliquer la distorsion la correction du contenu et l'afficher à l'écran.

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