In diesem Leitfaden erfährst du, wie du mit dem SDK für iOS eigene VR-Erlebnisse erstellen kannst.
Mit dem SDK lässt sich aus einem Smartphone eine VR-Plattform machen. Ein Smartphone kann 3D-Szenen mit stereoskopischem Rendering anzeigen, Kopfbewegungen verfolgen und darauf reagieren sowie mit Apps interagieren, indem es erkennt, wenn der Nutzer die Betrachtertaste drückt.
Zuerst verwendest du HelloCardboard, ein Demospiel, in dem die wichtigsten Funktionen des Cardboard SDK veranschaulicht werden. Im Spiel sehen sich Nutzer um eine virtuelle Welt, um Objekte zu finden und zu sammeln. Sie erfahren, wie Sie:
- Entwicklungsumgebung einrichten
- Demo-App herunterladen und erstellen
- Scanne den QR-Code einer Karteikarte, um ihre Parameter zu speichern
- Kopfbewegungen des Nutzers erfassen
- Stereoskopische Bilder rendern, indem für jedes Auge die richtige Verzerrung festgelegt wird
Entwicklungsumgebung einrichten
Hardwareanforderungen:
- iPhone mit iOS 12.0 oder höher
- Cardboard-Brille
Softwareanforderungen:
- Xcode 12.5 oder höher
- CocoaPods 1.9 oder höher
Demo-App herunterladen und erstellen
Das Cardboard SDK wird mit vorkompilierten Protokollzwischenspeicher-C++-Quelldateien erstellt. Hier erfahren Sie, wie Sie die Quelldateien von Grund auf neu erstellen.
Mit dem folgenden Befehl klonst du das Demo-SDK und das Demo-Tool von GitHub aus GitHub:
git clone https://github.com/googlevr/cardboard.git
Installieren Sie die Protokollzwischenspeicher-Abhängigkeit im Xcode-Projekt, indem Sie den folgenden Befehl im Stammverzeichnis des Repositorys ausführen:
pod install
Öffne den Arbeitsbereich „Cardboard“ (
Cardboard.xcworkspace
) in Xcode.Ändern Sie die Bundle-ID der App, damit Sie die App mit Ihrem Team signieren können.
Gehen Sie zu SDK > Build-Phasen > Binärdatei mit Bibliotheken verknüpfen
- Entfernen Sie
libPods-sdk.a
aus der Liste, indem Sie ihn auswählen und auf die Schaltfläche '-' klicken. - Fügen Sie der Liste „
libProtobuf-C++.a
“ hinzu, indem Sie auf die Schaltfläche '+' klicken und sie auswählen. Falls Sie in einer Meldung aufgefordert werden, ein XCFramework zu verwenden, klicken Sie auf "Trotzdem hinzufügen".
- Entfernen Sie
Klicken Sie auf Ausführen.
QR-Code scannen
Wenn du die Geräteparameter speichern möchtest, scanne den QR-Code auf dem Gerät:
Demo ansehen
Auf HelloCardboard suchen und sammeln Sie geodätische Kugeln in 3D.
So finden Sie eine Kugel:
Bewegen Sie den Kopf in eine beliebige Richtung, bis Sie eine schwebende Kugel sehen.
Sehen Sie sich die Kugel direkt an. Dadurch ändert sich die Farbe.
Drücke die VR-Brille, um die Kugel zu erfassen.
Gerät konfigurieren
Wenn der Nutzer auf das Zahnradsymbol tippt, um zwischen den VR-Brillen zu wechseln, wird die Methode didTapSwitchButton
in HelloCardboardOverlayView
aufgerufen.
- (void)didTapSwitchButton:(id)sender {
if ([self.delegate respondsToSelector:@selector(didTapBackButton)]) {
[self.delegate didChangeViewerProfile];
}
self.settingsBackgroundView.hidden = YES;
}
Dadurch wird CardboardQrCode_scanQrCodeAndSaveDeviceParams
aufgerufen, wodurch das Fenster zum Scannen des QR-Codes des Betrachters geöffnet wird. Wenn der Nutzer den QR-Code scannt, werden die Verzerrungsparameter des Geräts aktualisiert.
- (void)switchViewer {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
- (void)didChangeViewerProfile {
[self pauseCardboard];
[self switchViewer];
[self resumeCardboard];
}
Erfassung von Kopfbewegungen
Kopf-Tracker erstellen
Der Kopf-Tracker wird einmal in der Methode viewDidLoad
von HelloCardboardViewController
erstellt:
_cardboardHeadTracker = CardboardHeadTracker_create();
Kopf-Tracker pausieren und fortsetzen
Die Methoden pauseCardboard
und resumeCardboard
in der Klasse HelloCardboardViewController
pausieren und setzen den Kopf-Tracker jeweils fort. resumeCardboard
legt außerdem das Flag _updateParams
fest, wodurch die Geräteparameter im nächsten Zeichenaufruf aktualisiert werden.
- (void)pauseCardboard {
self.paused = true;
CardboardHeadTracker_pause(_cardboardHeadTracker);
}
- (void)resumeCardboard {
// Parameters may have changed.
_updateParams = YES;
// Check for device parameters existence in app storage. If they're missing,
// we must scan a Cardboard QR code and save the obtained parameters.
uint8_t *buffer;
int size;
CardboardQrCode_getSavedDeviceParams(&buffer, &size);
if (size == 0) {
[self switchViewer];
}
CardboardQrCode_destroy(buffer);
CardboardHeadTracker_resume(_cardboardHeadTracker);
self.paused = false;
}
Objektivverzeichnung
Jedes Mal, wenn ein neuer QR-Code gescannt wird, liest der Code die gespeicherten Parameter aus und erstellt daraus ein Objektiv, das die Objektivverzerrung auf den gerenderten Inhalt anwendet:
CardboardQrCode_getSavedDeviceParams(&encodedDeviceParams, &size);
// Create CardboardLensDistortion.
CardboardLensDistortion_destroy(_cardboardLensDistortion);
_cardboardLensDistortion =
CardboardLensDistortion_create(encodedDeviceParams, size, width, height);
// Initialize HelloCardboardRenderer.
_renderer.reset(new cardboard::hello_cardboard::HelloCardboardRenderer(
_cardboardLensDistortion, _cardboardHeadTracker, width, height));
Rendering
Für das Rendern von Inhalten in Cardboard sind folgende Schritte erforderlich:
- Texturen erstellen
- Anzeige- und Projektionsmatrizen für das linke und rechte Auge werden abgerufen
- Renderer erstellen und verzerrtes Mesh-Netzwerk festlegen
- Rendering für jeden Frame
Texturen erstellen
Der 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.
Die Beispielanwendung verwendet für beide Augen dieselbe Textur. Es ist aber auch möglich, für jedes Auge eine separate Textur zu erstellen.
// Generate texture to render left and right eyes.
glGenTextures(1, &_eyeTexture);
glBindTexture(GL_TEXTURE_2D, _eyeTexture);
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, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
_leftEyeTexture.texture = _eyeTexture;
_leftEyeTexture.left_u = 0;
_leftEyeTexture.right_u = 0.5;
_leftEyeTexture.top_v = 1;
_leftEyeTexture.bottom_v = 0;
_rightEyeTexture.texture = _eyeTexture;
_rightEyeTexture.left_u = 0.5;
_rightEyeTexture.right_u = 1;
_rightEyeTexture.top_v = 1;
_rightEyeTexture.bottom_v = 0;
CheckGLError("Create Eye textures");
Diese Texturen werden als Parameter an CardboardDistortionRenderer_renderEyeToDisplay
übergeben.
Anzeige- und Projektionsmatrizen für das linke und rechte Auge
Rufen Sie zuerst Augenmatrizen für das linke und das rechte Auge ab:
CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kLeft, _eyeMatrices[kLeft]);
CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kRight, _eyeMatrices[kRight]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kLeft, kZNear, kZFar,
_projMatrices[kLeft]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kRight, kZNear, kZFar,
_projMatrices[kRight]);
Als Nächstes erhalten Sie die verzerrten Meshes für jedes Auge und übergeben es an den verzerrten Rendering-Renderer:
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kLeft, &leftMesh);
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kRight, &rightMesh);
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 das rechte Auge anhand der von der Funktion CardboardLensDistortion_getDistortionMesh
zurückgegebenen Mesh-Werte fest.
_distortionRenderer = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(_distortionRenderer, &leftMesh, kLeft);
CardboardDistortionRenderer_setMesh(_distortionRenderer, &rightMesh, kRight);
Inhalte rendern
Rufen Sie die aktuelle Ausrichtung des Kopfes aus CardboardHeadTracker_getPose
ab:
CardboardHeadTracker_getPose(_headTracker, targetTime, position, orientation);
_headView =
GLKMatrix4Multiply(GLKMatrix4MakeTranslation(position[0], position[1], position[2]),
GLKMatrix4MakeWithQuaternion(GLKQuaternionMakeWithArray(orientation)));
Verwenden Sie die aktuelle Kopfausrichtung mit den Anzeige- und Projektionsmatrizen, um eine Projektionsmatrix für die Ansicht zu erstellen. Damit können Sie den Weltinhalt für jedes Auge rendern:
// Draw left eye.
glViewport(0, 0, _width / 2.0, _height);
glScissor(0, 0, _width / 2.0, _height);
DrawWorld(_leftEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kLeft]));
// Draw right eye.
glViewport(_width / 2.0, 0, _width / 2.0, _height);
glScissor(_width / 2.0, 0, _width / 2.0, _height);
DrawWorld(_rightEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kRight]));
Mit CardboardDistortionRenderer_renderEyeToDisplay
kannst du die Verzerrungskorrektur auf den Inhalt anwenden und ihn dann auf dem Bildschirm rendern.
CardboardDistortionRenderer_renderEyeToDisplay(_distortionRenderer, renderTarget, /*x=*/0,
/*y=*/0, _width, _height, &_leftEyeTexture,
&_rightEyeTexture);