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:
- iPhone z systemem iOS 12.0 lub nowszym
- Gogle Google Cardboard
Wymagania dotyczące oprogramowania:
- Xcode 12.5 lub nowsza wersja,
- CocoaPods w wersji 1.9 lub nowszej
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.
Skopiuj pakiet SDK Cardboard i aplikację demonstracyjną Hello Cardboard z GitHuba, uruchamiając to polecenie:
git clone https://github.com/googlevr/cardboard.git
Zainstaluj zależność buforów protokołu w projekcie Xcode, uruchamiając to polecenie w katalogu głównym repozytorium:
pod install
Otwórz obszar roboczy Cardboard (
Cardboard.xcworkspace
) w Xcode.Zmień identyfikator pakietu aplikacji, aby móc podpisać aplikację wspólnie z zespołem.
Wybierz SDK > Etapy kompilacji > Połącz plik binarny z bibliotekami.
- Usuń z listy
libPods-sdk.a
, wybierając go i klikając przycisk „-”. - 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”.
- Usuń z listy
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ę:
Poruszaj głową w dowolnym kierunku, aż zobaczysz unoszącą się kulę.
Spójrz bezpośrednio na sferę. Powoduje to zmianę koloru.
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);