Ce guide vous 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 un rendu stéréoscopique, suivre les mouvements de la tête et y réagir, et interagir avec les applications en détectant lorsque l'utilisateur appuie sur le bouton du casque.
Pour commencer, vous allez utiliser HelloCardboard, un jeu de démonstration qui présente les principales fonctionnalités du SDK Cardboard. Dans le jeu, les utilisateurs explorent un monde virtuel pour trouver et collecter des objets. Il vous explique comment :
- Configurer l'environnement de développement
- Télécharger et compiler l'application de démonstration
- Scanner le QR code d'une visionneuse Cardboard pour enregistrer ses paramètres
- Suivre les mouvements de la tête de l'utilisateur
- Afficher des images stéréoscopiques en définissant la matrice de projection de vue appropriée pour chaque œil
HelloCardboard utilise le NDK Android. Chaque méthode native :
- être lié 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 2024.1.2 "Koala Feature Drop" ou ultérieure
- SDK Android 15.0 "Vanilla Ice Cream" (niveau d'API 35) ou version ultérieure
Dernière version du framework Android NDK
Pour consulter ou mettre à jour les SDK installés, accédez à Préférences > Apparence et comportement.
System Settings > Android SDK dans Android Studio.
Télécharger et compiler l'application de démonstration
Le SDK Cardboard est conçu à l'aide d'un fichier d'en-tête Vulkan précompilé pour chaque nuanceur. Pour savoir comment créer les fichiers d'en-tête à partir de zéro, cliquez ici.
Exécutez la commande suivante pour cloner le SDK Cardboard et l'application de démonstration HelloCardboard depuis GitHub :
git clone https://github.com/googlevr/cardboard.git
Dans Android Studio, sélectionnez Open an existing Android Studio Project (Ouvrir un projet Android Studio existant), puis sélectionnez le répertoire dans lequel le SDK Cardboard et l'application de démonstration HelloCardboard ont été clonés.
Votre code s'affiche dans la fenêtre "Projet" d'Android Studio.
Pour assembler le SDK Cardboard, double-cliquez sur l'option assemble dans le dossier cardboard/:sdk/Tasks/build de l'onglet Gradle (Affichage > Fenêtres d'outils > Gradle).
Exécutez l'application de démonstration HelloCardboard sur votre téléphone en sélectionnant Run > Run… (Exécuter > Exécuter…) et sélectionnez la cible
hellocardboard-android
.
Scannez le QR code
Pour enregistrer les paramètres de l'appareil, scannez le code QR sur la visionneuse Cardboard :
Si l'utilisateur appuie sur "SKIP" (IGNORER) et qu'aucun paramètre n'a été enregistré précédemment, Cardboard enregistre les paramètres de Google Cardboard v1 (lancé lors de Google I/O 2014).
Essayer la démo
Dans HelloCardboard, vous devez rechercher et collecter des sphères géodésiques dans l'espace 3D.
Pour trouver et collecter une sphère :
Bougez votre tête dans n'importe quelle direction jusqu'à ce qu'une forme flottante apparaisse.
Regardez directement la sphère. La couleur change.
Appuyez sur le bouton du casque Cardboard pour "collecter" la sphère.
Configurer l'appareil
Lorsque l'utilisateur appuie sur l'icône en forme d'engrenage pour changer de casque Cardboard, la méthode nativeSwitchViewer
est appelée. nativeSwitchViewer
appels
CardboardQrCode_scanQrCodeAndSaveDeviceParams
, ce qui ouvre la fenêtre permettant de scanner le code QR du spectateur. La distorsion de l'objectif et les autres paramètres du spectateur sont mis à jour une fois le code QR scanné.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Activer l'émulateur x86 d'Android Studio
Pour compiler pour l'émulateur x86 d'Android Studio, supprimez la ligne suivante des fichiers build.gradle
dans SDK et Sample :
abiFilters 'armeabi-v7a', 'arm64-v8a'
Cela active tous les ABI et augmente considérablement la taille du fichier .aar
généré. Pour en savoir plus, consultez ABI Android.
Suivi de la tête
Créer un capteur de mouvements de la tête
Le capteur de tête est créé une seule 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());
//...
}
Mettre en pause et reprendre le suivi de la tête
Pour mettre en pause, reprendre et détruire le suivi de la tête, CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
et CardboardHeadTracker_destroy(head_tracker_)
doivent être appelés, respectivement. Dans l'application "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 que Cardboard scanne 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, qui applique la distorsion appropriée 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
L'affichage de contenu dans Cardboard implique les éléments suivants :
- Créer des textures
- Obtenir les matrices de vue et de projection pour l'œil gauche et l'œil droit
- Créer le moteur de rendu et définir le maillage de distorsion
- Rendu de chaque frame
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 initialisées dans _leftEyeTexture
et _rightEyeTexture
, respectivement.
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
Tout d'abord, récupérez les matrices oculaires pour l'œil gauche et l'œil 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]);
Ensuite, obtenez 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 maillage de distorsion pour l'œil gauche et l'œil droit en fonction des valeurs de maillage renvoyées par la fonction CardboardLensDistortion_getDistortionMesh
.
distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);
Affichage du contenu
Pour chaque frame, 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]);
Utilisez l'orientation actuelle de la tête avec les matrices de vue et de projection pour composer une matrice de vue/projection pour chacun des yeux et afficher 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();
}
Utilisez CardboardDistortionRenderer_renderEyeToDisplay
pour appliquer la correction de la distorsion au 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_);