In dieser Anleitung erfahren Sie, wie Sie mit dem Cardboard SDK für Android eigene Virtual-Reality-Anwendungen (VR) erstellen.
Mit dem Cardboard SDK können Sie ein Smartphone in eine VR-Plattform verwandeln. Ein Smartphone kann 3D-Szenen mit stereoskopischem Rendering darstellen, Kopfbewegungen in alle Richtungen erfassen und in die virtuelle Welt umsetzen sowie mit Apps interagieren, indem es erkennt, wenn der Nutzer die Viewer-Schaltfläche drückt.
Als Erstes verwenden Sie HelloCardboard, ein Demospiel, das die wichtigsten Funktionen des Cardboard SDK veranschaulicht. Im Spiel sehen sich Nutzer in einer virtuellen Welt um, um Objekte zu finden und zu sammeln. Darin wird Folgendes beschrieben:
- Entwicklungsumgebung einrichten
- Demo-App herunterladen und erstellen
- QR‑Code eines Cardboard-Viewers scannen, um seine Parameter zu speichern
- Kopfbewegungen des Nutzers erfassen
- Stereoskopische Bilder rendern, indem Sie für jedes Auge die richtige Ansichtsprojektionsmatrix festlegen
HelloCardboard verwendet das Android NDK. Jede native Methode ist:
- eindeutig an eine
HelloCardboardApp-Klassenmethode gebunden ist oder - Erstellt oder löscht eine Instanz dieser Klasse.
Entwicklungsumgebung einrichten
Hardwareanforderungen:
- Android-Gerät mit Android 8.0 „Oreo“ (API-Level 26) oder höher
- Cardboard-Viewer
Softwareanforderungen:
- Android Studio ab Version 2024.1.2 „Koala Feature Drop“
- Android SDK 15.0 „Vanilla Ice Cream“ (API‑Level 35) oder höher
Die aktuelle Version des Android NDK-Frameworks
Wenn Sie installierte SDKs ansehen oder aktualisieren möchten, gehen Sie zu Einstellungen > Darstellung und Verhalten.
System Settings > Android SDK in Android Studio.
Demo-App herunterladen und erstellen
Das Cardboard SDK wird mit einer vorkompilierten Vulkan-Headerdatei für jeden Shader erstellt. Eine Anleitung zum Erstellen der Header-Dateien von Grund auf finden Sie hier.
Führen Sie den folgenden Befehl aus, um das Cardboard SDK und die HelloCardboard-Demo-App von GitHub zu klonen:
git clone https://github.com/googlevr/cardboard.git
Wählen Sie in Android Studio Open an existing Android Studio Project (Vorhandenes Android Studio-Projekt öffnen) aus und wählen Sie dann das Verzeichnis aus, in das das Cardboard SDK und die HelloCardboard-Demo-App geklont wurden.
Ihr Code wird im Projektfenster in Android Studio angezeigt.
Doppelklicken Sie zum Erstellen des Cardboard SDK auf dem Tab „Gradle“ (Ansicht > Toolfenster > Gradle) im Ordner cardboard/:sdk/Tasks/build auf die Option assemble.
Führen Sie die HelloCardboard-Demo-App auf Ihrem Smartphone aus, indem Sie Run > Run... (Ausführen > Ausführen...) auswählen und das Ziel
hellocardboard-androidauswählen.
QR-Code scannen
Scanne den QR‑Code auf dem Cardboard-Viewer, um die Geräteparameter zu speichern:
Wenn der Nutzer auf „ÜBERSPRINGEN“ tippt und keine zuvor gespeicherten Parameter vorhanden sind, werden die Parameter für Google Cardboard V1 (eingeführt auf der Google I/O 2014) gespeichert.
Demo ansehen
In HelloCardboard suchen und sammeln Sie geodätische Kugeln im 3D-Raum.
So finden und sammeln Sie eine Kugel:
Bewegen Sie Ihren Kopf in eine beliebige Richtung, bis Sie eine schwebende Form sehen.
Sehen Sie direkt auf die Kugel. Dadurch ändert sich die Farbe.
Drücken Sie die Taste auf dem Cardboard-Viewer, um die Kugel „einzusammeln“.
Gerät konfigurieren
Wenn der Nutzer auf das Zahnradsymbol tippt, um die Cardboard-Brille zu wechseln, wird die Methode nativeSwitchViewer aufgerufen. nativeSwitchViewer calls
CardboardQrCode_scanQrCodeAndSaveDeviceParams, wodurch das Fenster zum Scannen des QR‑Codes des Zuschauers geöffnet wird. Die Linsenverzerrung und andere Parameter des Zuschauers werden aktualisiert, sobald der QR‑Code gescannt wird.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Android Studio x86-Emulator aktivieren
Wenn Sie für den x86-Emulator von Android Studio erstellen möchten, entfernen Sie die folgende Zeile aus den build.gradle-Dateien in SDK und Sample:
abiFilters 'armeabi-v7a', 'arm64-v8a'
Dadurch werden alle ABIs aktiviert und die Größe der generierten .aar-Datei wird erheblich erhöht. Weitere Informationen finden Sie unter Android-ABIs.
Erfassung von Kopfbewegungen
Head-Tracker erstellen
Der Head-Tracker wird einmal im Konstruktor von HelloCardboardApp erstellt:
HelloCardboardApp::HelloCardboardApp(JavaVM* vm, jobject obj, jobject asset_mgr_obj) {
Cardboard_initializeAndroid(vm, obj); // Must be called in constructor
head_tracker_ = CardboardHeadTracker_create();
}
Wenn VrActivity erstellt wird, wird durch Aufrufen der Methode nativeOnCreate eine Instanz der Klasse HelloCardboardApp generiert:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
Head-Tracker pausieren und fortsetzen
Um den Head-Tracker zu pausieren, fortzusetzen und zu zerstören, müssen CardboardHeadTracker_pause(head_tracker_), CardboardHeadTracker_resume(head_tracker_) bzw. CardboardHeadTracker_destroy(head_tracker_) aufgerufen werden. In der App „HelloCardboard“ werden sie in nativeOnPause, nativeOnResume und nativeOnDestroy aufgerufen:
// 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;
}
Objektivverzeichnung
Jedes Mal, wenn Cardboard einen neuen QR-Code scannt, werden mit dem folgenden Code die gespeicherten Parameter gelesen und verwendet, um das Objekt für die Linsenverzerrung zu erstellen, mit dem die gerenderte Grafik entsprechend verzerrt wird:
CardboardQrCode_getSavedDeviceParams(&buffer, &size);
CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
buffer, size, screen_width_, screen_height_);
CardboardQrCode_destroy(buffer);
Rendering
Das Rendern von Inhalten in Cardboard umfasst Folgendes:
- Texturen erstellen
- Ansichts- und Projektionsmatrizen für das linke und rechte Auge abrufen
- Renderer erstellen und das Verzerrungs-Mesh festlegen
- Rendern jedes Frames
Texturen erstellen
Alle Inhalte werden auf eine Textur gezeichnet, die in Abschnitte für das linke und das rechte Auge unterteilt ist.
Diese Abschnitte werden in _leftEyeTexture bzw. _rightEyeTexture initialisiert.
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");
}
Diese Texturen werden als Parameter an CardboardDistortionRenderer_renderEyeToDisplay übergeben.
Ansichts- und Projektionsmatrizen für das linke und rechte Auge abrufen
Rufen Sie zuerst die Augenmatrizen für das linke und das rechte Auge ab:
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]);
Als Nächstes rufen Sie die Verzerrungs-Meshes für jedes der Augen ab und übergeben Sie sie an den Verzerrungs-Renderer:
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);
Renderer erstellen und das richtige Verzerrungs-Mesh festlegen
Der Renderer muss nur einmal initialisiert werden. Nachdem der Renderer erstellt wurde, legen Sie das neue Verzerrungs-Mesh für das linke und rechte Auge entsprechend den Mesh-Werten fest, die von der Funktion CardboardLensDistortion_getDistortionMesh zurückgegeben werden.
distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);
Inhalte rendern
Rufen Sie für jeden Frame die aktuelle Ausrichtung des Kopfes aus CardboardHeadTracker_getPose ab:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Verwenden Sie die aktuelle Ausrichtung des Kopfes mit den Ansichts- und Projektionsmatrizen, um eine Ansichts-Projektionsmatrix für jedes der beiden Augen zu erstellen und Inhalte auf dem Bildschirm zu rendern:
// 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();
}
Verwenden Sie CardboardDistortionRenderer_renderEyeToDisplay, um die Verzerrungskorrektur auf die Inhalte anzuwenden und die Inhalte auf dem Bildschirm zu rendern.
// Render
CardboardDistortionRenderer_renderEyeToDisplay(
distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
screen_width_, screen_height_, &left_eye_texture_description_,
&right_eye_texture_description_);




