In diesem Leitfaden wird erläutert, wie du mit dem Cardboard SDK für Android eigene Virtual-Reality-Erlebnisse (VR) erstellen kannst.
Mit dem Cardboard SDK kannst du dein Smartphone in eine VR-Plattform verwandeln. Ein Smartphone kann 3D-Szenen mit stereoskopischem Rendering darstellen, Kopfbewegungen erfassen und darauf reagieren sowie mit Apps interagieren, indem es erkennt, wenn der Nutzer die Taste des Betrachters drückt.
Als Erstes verwendest du das Demospiel HelloCardboard, in dem die Hauptfunktionen des Cardboard SDK veranschaulicht werden. Im Spiel schauen sich Nutzer eine virtuelle Welt an, um Objekte zu finden und zu sammeln. Darin erfahren Sie, wie Sie
- Entwicklungsumgebung einrichten
- Demo-App herunterladen und erstellen
- Scanne den QR-Code eines Cardboard, um seine Parameter zu speichern
- Kopfbewegungen des Nutzers erfassen
- Stereoskopische Bilder durch Festlegen der richtigen Projektionsmatrix für jedes Auge rendern
HelloCardboard verwendet das Android-NDK. Alle nativen Methoden sind:
- Abhängig von einer
HelloCardboardApp
-Klassenmethode oder - Erstellt oder löscht eine Instanz dieser Klasse
Entwicklungsumgebung einrichten
Hardwareanforderungen:
- Android-Geräte mit Android 7.0 (Nougat) (API-Level 24) oder höher
- Brillenkarton
Softwareanforderungen:
- Android Studio 4.2.2 oder höher
- Android SDK 11.0 „R“ (API-Level 30) oder höher
Die aktuelle Version des Android NDK-Frameworks
Wenn Sie installierte SDKs prüfen oder aktualisieren möchten, gehen Sie zu Einstellungen > Darstellung und Verhalten.
Gehen Sie zu Systemeinstellungen > Android SDK in Android Studio.
Demo-App herunterladen und erstellen
Das Cardboard SDK wird für jeden Shader mit einer vorkompilierten Vulkan-Header-Datei erstellt. Eine Anleitung dazu, wie Sie die Headerdateien neu erstellen, finden Sie hier.
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 Bestehendes Android Studio-Projekt öffnen und dann das Verzeichnis aus, in dem das Cardboard SDK und die Demo-App „HelloCardboard“ geklont wurden.
Der Code wird in Android Studio im Projektfenster angezeigt.
Du kannst das Cardboard SDK zusammenstellen, indem du im Tab Gradle (<Ansicht > Tool-Fenster > Gradle)doppelt auf die Option cardboard/:sdk/Tasks/buildzusammenbaust.
Führen Sie die Demo-App „HelloCardboard“ auf Ihrem Smartphone aus. Wählen Sie dazu Run > Run... (Ausführen > Ausführen...) und das Ziel
hellocardboard-android
aus.
QR-Code scannen
Wenn du die Geräteparameter speichern möchtest, scanne den QR-Code auf der Cardboard-Brille:
Wenn der Nutzer auf „SKIP“ drückt und keine zuvor gespeicherten Parameter vorhanden sind, speichert Cardboard die Parameter von Google Cardboard v1 (wird bei Google I/O 2014 eingeführt).
Demo ausprobieren
In HelloCardboard suchen und sammeln Sie geodätische Kugeln in 3D.
So finden und sammeln Sie eine Kugel:
Bewegen Sie den Kopf in eine beliebige Richtung, bis Sie eine schwebende Form sehen.
Sieh die Kugel direkt an. Dadurch werden die Farben geändert.
Drücken Sie die Cardboard-Brille, um die Kugel zu „sammeln“.
Gerät konfigurieren
Wenn der Nutzer auf das Zahnradsymbol tippt, um zur Cardboard-Brille zu wechseln, wird die Methode nativeSwitchViewer
aufgerufen. nativeSwitchViewer
ruft CardboardQrCode_scanQrCodeAndSaveDeviceParams
auf. Dadurch wird das Fenster geöffnet, in dem der QR-Code des Betrachters gescannt werden kann. 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 die folgende Zeile aus den build.gradle
-Dateien im SDK und Beispiel, um Builds für den Android Studio x86-Emulator zu erstellen:
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-ABAB.
Erfassung von Kopfbewegungen
Kopf-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 eine Instanz der Klasse HelloCardboardApp
durch Aufrufen der Methode nativeOnCreate
generiert:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
„Tracker starten“ pausieren und fortsetzen
Zum Pausieren, Fortsetzen und Löschen des Kopf-Trackers müssen CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
und 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, liest der folgende Code die gespeicherten Parameter und verwendet sie, um ein Objektivverzeichnungsobjekt zu erstellen, das die richtige Objektivverzeichnung auf den gerenderten Inhalt anwendet:
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
- Matrixs für das linke und rechte Auge werden angezeigt
- Renderer erstellen und verzerrtes Mesh einrichten
- Rendering für jeden Frame
Texturen erstellen
Der gesamte Inhalt wird auf eine Textur gezeichnet, die in Abschnitte für das linke und rechte Auge aufgeteilt 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.
Matrix für Ansicht und Projektion für linkes und rechtes Auge
Zuerst werden Augenmatrize für das linke und rechte Auge abgerufen:
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 das Verzerrungsnetz für jedes Auge ab und übergeben es an den Verzerrungsrenderer:
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. Nachdem der Renderer erstellt wurde, legen Sie das neue Verzerrungsnetz für das linke und rechte Auge gemäß den von der CardboardLensDistortion_getDistortionMesh
-Funktion zurückgegebenen Mesh-Werten fest.
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 Kopfausrichtung mit der Ansichts- und Projektionsmatrizen, um für jedes Auge eine Matrix für die Darstellung 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();
}
Mit CardboardDistortionRenderer_renderEyeToDisplay
können Sie die Verzerrung auf den Inhalt anwenden und den Inhalt auf dem Bildschirm 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_);