In diesem Leitfaden erfährst du, wie du mit dem Cardboard SDK for Android deine eigenen Virtual-Reality-Erlebnisse erstellen kannst.
Mit dem Cardboard SDK kannst du ein Smartphone in eine VR-Plattform verwandeln. Ein Smartphone kann 3D-Szenen mit stereoskopischem Rendering anzeigen, Kopfbewegungen verfolgen und darauf reagieren und mit Apps interagieren, indem es erkennt, wann der Nutzer auf die Schaltfläche des Betrachters drückt.
Verwende als Erstes HelloCardboard, ein Demospiel, in dem die wichtigsten Funktionen des Cardboard SDK demonstriert werden. In dem Spiel sehen sich Nutzer in einer virtuellen Welt um, um Objekte zu finden und zu sammeln. Sie erfahren, wie Sie:
- Entwicklungsumgebung einrichten
- Demo-App herunterladen und erstellen
- QR-Code eines Cardboard scannen, um dessen Parameter zu speichern
- Die Kopfbewegungen der Nutzenden erfassen
- Stereoskopische Bilder rendern, indem für jedes Auge die richtige Matrix für die Ansichtsprojektion festgelegt wird
HelloCardboard verwendet den Android NDK. Für jede native Methode gilt:
- Eindeutiger Begrenzung auf eine
HelloCardboardApp
-Klassenmethode 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-Brille
Softwareanforderungen:
- Android Studio 2022.1.1 „Electric Eel“ oder höher
- Android SDK 13.0 „Tiramisu“ (API-Level 33) oder höher
Die aktuelle Version des Android NDK-Frameworks
Installierte SDKs kannst du unter Einstellungen > Darstellung und Verhalten prüfen oder aktualisieren.
Systemeinstellungen > Android SDK in Android Studio.
Demo-App herunterladen und erstellen
Das Cardboard SDK wird mithilfe einer vorkompilierten Vulkan-Header-Datei für jeden Shader erstellt. Hier finden Sie eine Anleitung dazu, wie Sie Headerdateien von Grund auf neu erstellen.
Führe den folgenden Befehl aus, um das Cardboard SDK und die Demo-App HelloCardboard von GitHub zu klonen:
git clone https://github.com/googlevr/cardboard.git
Wähle in Android Studio Vorhandenes Android Studio-Projekt öffnen und 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.
Um das Cardboard SDK zusammenzustellen, klicke im Ordner cardboard/:sdk/Tasks/build auf dem Gradle-Tab (View > Tool Windows > Gradle) auf die Option configure.
Führe die Demo-App HelloCardboard auf deinem Smartphone aus. Wähle dazu Ausführen > Ausführen... und das Ziel
hellocardboard-android
aus.
Scanne den QR-Code.
Scanne den QR-Code auf der Cardboard-Brille, um die Geräteparameter zu speichern:
Wenn der Nutzer auf „ÜBERSPRINGEN“ klickt und keine zuvor gespeicherten Parameter vorhanden sind, speichert Cardboard die Parameter von Google Cardboard Version 1, die bei der Google I/O 2014 eingeführt wurde.
Zur Demo
In HelloCardboard suchen und sammeln Sie geodätische Kugeln im 3D-Raum.
So finden und erfassen Sie eine Kugel:
Bewegen Sie den Kopf in eine beliebige Richtung, bis Sie eine schwebende Form sehen.
Blicken Sie direkt in die Kugel. Dadurch ändert es die Farbe.
Drücken Sie die Taste des Cardboard, um die Kugel einzusammeln.
Gerät konfigurieren
Wenn der Nutzer auf das Zahnradsymbol tippt, um das Cardboard zu wechseln, wird die Methode nativeSwitchViewer
aufgerufen. nativeSwitchViewer
ruft CardboardQrCode_scanQrCodeAndSaveDeviceParams
auf, um das Fenster zum Scannen des QR-Codes des Zuschauers zu öffnen. Die Objektivverzeichnung des Betrachters und andere Parameter werden aktualisiert, sobald der QR-Code gescannt wurde.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Android Studio x86-Emulator aktivieren
Entfernen Sie zum Erstellen von Builds für den Android Studio x86-Emulator im SDK und im Beispiel die folgende Zeile aus den build.gradle
-Dateien:
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();
}
Beim Erstellen von VrActivity
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
Zum Pausieren, Fortsetzen und Löschen des Head Trackers müssen CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
bzw. CardboardHeadTracker_destroy(head_tracker_)
aufgerufen werden. In der App „HelloCardboard“ rufen wir sie in nativeOnPause
, nativeOnResume
und nativeOnDestroy
auf:
// 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, liest der folgende Code die gespeicherten Parameter aus und verwendet sie, um das Objekt zur Objektivverzeichnung zu erstellen. Dadurch wird die richtige Objektivverzeichnung auf den gerenderten Inhalt angewendet:
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 die folgenden Schritte:
- Texturen erstellen
- Ansichts- und Projektionsmatrizen für das linke und rechte Auge abrufen
- Renderer erstellen und Verzerrungsnetz festlegen
- Frames rendern
Texturen erstellen
Der gesamte Inhalt wird 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 linkes und rechtes 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]);
Rufen Sie als Nächstes die Verzerrungsmaschen 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 Verzerrungsnetz festlegen
Der Renderer muss nur einmal initialisiert werden. Legen Sie nach dem Erstellen des Renderers das neue Verzerrungsnetz für das linke und rechte Auge gemäß 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);
Inhalt rendern
Rufen Sie für jeden Frame die aktuelle Kopfausrichtung von CardboardHeadTracker_getPose
ab:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Verwenden Sie die aktuelle Kopfausrichtung mit den Ansichts- und Projektionsmatrizen, um eine Ansichtsprojektionsmatrix für jedes der 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 den Inhalt anzuwenden und ihn 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_);