Krótkie wprowadzenie do Google Cardboard na iOS

Z tego przewodnika dowiesz się, jak za pomocą pakietu SDK Cardboard na iOS tworzyć własne projekty VR.

Za pomocą pakietu SDK Cardboard możesz zmienić smartfona w platformę VR. Smartfon może wyświetlać sceny 3D z renderowaniem stereoskopowym, śledzić ruchy głowy i reagować na nie oraz wchodzić w interakcje z aplikacjami, wykrywając, kiedy użytkownik naciśnie przycisk gogli.

Na początek użyjesz HelloCardboard, gry demonstracyjnej, która prezentuje główne funkcje pakietu SDK Cardboard. Użytkownicy w grze rozglądają się po wirtualnym świecie, aby znajdować i zbierać obiekty. Pokazuje ono, jak:

  • Konfigurowanie środowiska programistycznego
  • Pobierz i stwórz aplikację demonstracyjną
  • Zeskanuj kod QR gogli Cardboard, aby zapisać jej parametry
  • Śledź ruchy głową użytkownika
  • Renderuj obrazy stereoskopowe, ustawiając odpowiednie zniekształcenia dla każdego oka

Konfigurowanie środowiska programistycznego

Wymagania sprzętowe:

Wymagania dotyczące oprogramowania:

Pobierz i stwórz aplikację demonstracyjną

Pakiet Google Cardboard SDK jest oparty na wstępnie skompilowanych plikach źródłowych buforów protokołów w języku C++. Instrukcje tworzenia plików źródłowych od zera znajdziesz tutaj.

  1. Skopiuj pakiet SDK Cardboard i aplikację demonstracyjną Hello Cardboard z GitHuba, uruchamiając to polecenie:

    git clone https://github.com/googlevr/cardboard.git
  2. Zainstaluj zależność buforów protokołu w projekcie Xcode, uruchamiając to polecenie w katalogu głównym repozytorium:

    pod install
  3. Otwórz obszar roboczy Cardboard (Cardboard.xcworkspace) w Xcode.

  4. Zmień identyfikator pakietu aplikacji, aby móc podpisać aplikację wspólnie z zespołem.

  5. Wybierz SDK > Etapy kompilacji > Połącz plik binarny z bibliotekami.

    1. Usuń z listy libPods-sdk.a, wybierając go i klikając przycisk „-”.
    2. Dodaj firmę libProtobuf-C++.a do listy, klikając przycisk „+” i wybierając ją. Jeśli pojawi się komunikat sugerujący użycie elementu XCFramework, kliknij „Dodaj mimo to”.
  6. Kliknij Uruchom.

Zeskanuj kod QR

Aby zapisać parametry urządzenia, zeskanuj kod QR za pomocą gogli Cardboard:

Wypróbuj wersję demonstracyjną

W HelloCardboard wyszukujesz i gromadzisz sfery geodetyczne w przestrzeni 3D.

Aby znaleźć i zebrać sferę:

  1. Poruszaj głową w dowolnym kierunku, aż zobaczysz unoszącą się kulę.

  2. Spójrz bezpośrednio na sferę. Powoduje to zmianę koloru.

  3. Naciśnij przycisk gogli Cardboard, aby „zbierać” sferę.

Skonfiguruj urządzenie

Gdy użytkownik kliknie ikonę koła zębatego, aby przełączyć gogle Cardboard, metoda didTapSwitchButton zostanie wywołana w HelloCardboardOverlayView.

- (void)didTapSwitchButton:(id)sender {
  if ([self.delegate respondsToSelector:@selector(didTapBackButton)]) {
    [self.delegate didChangeViewerProfile];
  }
  self.settingsBackgroundView.hidden = YES;
}

Spowoduje to otwarcie okna zeskanowania kodu QR widza na stronie CardboardQrCode_scanQrCodeAndSaveDeviceParams. Gdy użytkownik skanuje kod QR, parametry zniekształcania urządzenia są aktualizowane.

- (void)switchViewer {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

- (void)didChangeViewerProfile {
  [self pauseCardboard];
  [self switchViewer];
  [self resumeCardboard];
}

Monitorowanie ruchów głowy

Utwórz urządzenie śledzące ruchy głowy

Monitorowanie ruchów głowy jest tworzone raz w metodzie viewDidLoad HelloCardboardViewController:

_cardboardHeadTracker = CardboardHeadTracker_create();

Wstrzymywanie i wznawianie śledzenia ruchów głowy

Metody pauseCardboard i resumeCardboard w klasie HelloCardboardViewController wstrzymują i wznawiają urządzenie śledzące ruchy głowy. resumeCardboard ustawia też flagę _updateParams, która powoduje zaktualizowanie parametrów urządzenia przy następnym wywołaniu rysowania.

- (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;
}

Zniekształcenie obiektywu

Za każdym razem, gdy Cardboard skanuje nowy kod QR, poniższy kod odczytuje zapisane parametry i wykorzystuje je do utworzenia obiektu zniekształconego obiektywu, który stosuje odpowiednie zniekształcenia obiektywu do renderowanych treści:

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

renderowanie,

Renderowanie treści w goglach Cardboard:

  • Tworzenie tekstur
  • Uzyskiwanie macierzy wyświetlania i odwzorowania dla lewego i prawego oka
  • Tworzenie mechanizmu renderowania i konfigurowanie siatki zniekształceń
  • Renderowanie każdej klatki.

Tworzenie tekstur

Treść jest rysowana na teksturze, która jest podzielona na sekcje dla lewego i prawego oka. Inicjowane sekcje są odpowiednio _leftEyeTexture i _rightEyeTexture. Aplikacja wykorzystuje 1 teksturę dla obu oczu, ale można też utworzyć osobną teksturę dla każdego oka.

// 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");

Te tekstury są przekazywane jako parametry do funkcji CardboardDistortionRenderer_renderEyeToDisplay.

Pobierz macierze widoku i odwzorowania dla lewego i prawego oka

Najpierw pobierz macierze oka dla lewego i prawego oka:

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]);

Następnie pobierz sieci zniekształceń dla każdego oczu i przekaż je do mechanizmu renderowania zniekształceń:

CardboardLensDistortion_getDistortionMesh(_lensDistortion, kLeft, &leftMesh);
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kRight, &rightMesh);

Utwórz mechanizm renderowania i ustaw prawidłową siatkę zniekształceń

Mechanizm renderowania wystarczy zainicjować tylko raz. Po utworzeniu mechanizmu renderowania ustaw nową siatkę zniekształceń dla lewego i prawego oka zgodnie z wartościami sieci typu mesh zwróconymi przez funkcję CardboardLensDistortion_getDistortionMesh.

_distortionRenderer = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(_distortionRenderer, &leftMesh, kLeft);
CardboardDistortionRenderer_setMesh(_distortionRenderer, &rightMesh, kRight);

Renderowanie treści

Pobierz bieżącą orientację głowicy z CardboardHeadTracker_getPose:

CardboardHeadTracker_getPose(_headTracker, targetTime, position, orientation);
_headView =
    GLKMatrix4Multiply(GLKMatrix4MakeTranslation(position[0], position[1], position[2]),
                       GLKMatrix4MakeWithQuaternion(GLKQuaternionMakeWithArray(orientation)));

Korzystając z bieżącej orientacji głowy z macierzami widoku i projekcji, utwórz macierz widoków danych, a następnie użyj jej do renderowania zawartości całego świata dla każdego oczu:

// 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]));

Użyj narzędzia CardboardDistortionRenderer_renderEyeToDisplay, aby zastosować korektę zniekształceń do treści i wyrenderować ją na ekranie.

CardboardDistortionRenderer_renderEyeToDisplay(_distortionRenderer, renderTarget, /*x=*/0,
                                               /*y=*/0, _width, _height, &_leftEyeTexture,
                                               &_rightEyeTexture);