Kurzanleitung für Google Cardboard für iOS

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:

Softwareanforderungen:

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.

  1. 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
  2. Installieren Sie die Protokollzwischenspeicher-Abhängigkeit im Xcode-Projekt, indem Sie den folgenden Befehl im Stammverzeichnis des Repositorys ausführen:

    pod install
  3. Öffne den Arbeitsbereich „Cardboard“ (Cardboard.xcworkspace) in Xcode.

  4. Ändern Sie die Bundle-ID der App, damit Sie die App mit Ihrem Team signieren können.

  5. Gehen Sie zu SDK > Build-Phasen > Binärdatei mit Bibliotheken verknüpfen

    1. Entfernen Sie libPods-sdk.a aus der Liste, indem Sie ihn auswählen und auf die Schaltfläche '-' klicken.
    2. 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".
  6. 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:

  1. Bewegen Sie den Kopf in eine beliebige Richtung, bis Sie eine schwebende Kugel sehen.

  2. Sehen Sie sich die Kugel direkt an. Dadurch ändert sich die Farbe.

  3. 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);