Z tego przewodnika dowiesz się, jak korzystać z pakietu SDK Cardboard. na Androida do tworzenia własnych rozwiązań rzeczywistości wirtualnej.
Za pomocą pakietu SDK Cardboard możesz zamienić smartfona w platformę VR. Smartfon umożliwia wyświetlanie scen 3D z renderowaniem stereoskopowym, śledzenie ruchów głowy i reagowanie na nie, i interakcji z aplikacjami, wykrywając, kiedy użytkownik naciśnie przycisk na goglach.
Na początek skorzystaj z HelloCardboard – gry demonstracyjnej, która przedstawia podstawowe funkcje z pakietu SDK Cardboard. Gracze rozglądają się po wirtualnym świecie, aby znaleźć i zbierać obiekty. Pokazuje on, jak:
- Konfigurowanie środowiska programistycznego
- Pobierz i utwórz aplikację w wersji demonstracyjnej
- Zeskanuj kod QR gogli Cardboard, aby zapisać jego parametry
- Śledzenie ruchów głowy użytkownika
- Renderuj obrazy stereoskopowe, ustawiając prawidłową macierz rzutowania obrazu dla każdego oka
HelloCardboard używa pakietu Android NDK. Każda metoda natywna:
- powiązany wyłącznie z metodą klasy
HelloCardboardApp
lub - Tworzy lub usuwa instancję tej klasy
Konfigurowanie środowiska programistycznego
Wymagania sprzętowe:
- Urządzenie z Androidem 8.0 „Oreo” (poziom interfejsu API 26) lub wyższy
- Gogle gogli Cardboard
Wymagania dotyczące oprogramowania:
- Android Studio w wersji 2022.1.1 „Electric Eel” lub więcej
- Pakiet SDK na Androida 13.0 „Tiramisu” (poziom interfejsu API 33) lub wyższy
Najnowsza wersja platformy Android NDK.
Aby sprawdzić lub zaktualizować zainstalowane pakiety SDK, kliknij Preferencje > Wygląd i działanie
Ustawienia systemu > Pakiet SDK do Androida w Android Studio.
Pobierz i utwórz aplikację w wersji demonstracyjnej
Pakiet SDK Cardboard został stworzony na podstawie wstępnie skompilowanego kodu Vulkan pliku nagłówkowego każdego modułu cieniowania. Instrukcje tworzenia plików nagłówka od zera znajdziesz w opisie tutaj.
Uruchom następujące polecenie, aby skopiować pakiet SDK Cardboard i wersję demonstracyjną HelloCardboard z GitHuba:
git clone https://github.com/googlevr/cardboard.git
W Android Studio kliknij Otwórz istniejący projekt Android Studio, a potem wybierz katalogu, w którym sklonowano pakiet SDK Cardboard oraz aplikację demonstracyjną HelloCardboard.
Kod pojawi się w oknie projektu w Android Studio.
Aby złożyć pakiet SDK Cardboard, kliknij dwukrotnie opcję Zamontuj. cardboard/:sdk/Tasks/build i na karcie Gradle (Widok > Okna narzędzi > Gradle).
Uruchom na telefonie aplikację demonstracyjną HelloCardboard, klikając Uruchom > Uruchom... i wybierz wartość docelową
hellocardboard-android
.
Zeskanuj kod QR
Aby zapisać parametry urządzenia, zeskanuj kod QR goglami Cardboard:
Jeśli użytkownik kliknie „POMIŃ” i nie ma żadnych zapisanych parametrów, Parametry Google Cardboard v1 (udostępnione na konferencji Google I/O 2014).
Wypróbuj wersję demonstracyjną
W HelloCardboard możesz wyszukiwać i zbierać kule geodezyjne w przestrzeni 3D.
Aby znaleźć i zebrać kulę:
Poruszaj głową w dowolnym kierunku, aż zobaczysz pływający kształt.
Patrz prosto w sferę. Powoduje to zmianę koloru.
Naciśnij przycisk gogli Cardboard, aby zebrać dane w całej sferze.
Konfigurowanie urządzenia
Gdy użytkownik kliknie ikonę koła zębatego, aby przełączyć gogle Cardboard, nativeSwitchViewer
. nativeSwitchViewer
połączenia
CardboardQrCode_scanQrCodeAndSaveDeviceParams
, który otwiera okno skanowania.
kod QR widza. Zniekształcenie obiektywu widza oraz inne parametry są aktualizowane raz
kod QR zostanie zeskanowany.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Włącz emulator Android Studio x86
Aby utworzyć emulator Androida Studio x86, usuń ten wiersz z
Pliki build.gradle
w pakiecie SDK
i Przykład:
abiFilters 'armeabi-v7a', 'arm64-v8a'
Włącza to wszystkie interfejsy ABI i znacznie zwiększa rozmiar generowanych
.aar
. Zobacz interfejsy ABI Androida
.
Monitorowanie ruchów głowy
Utwórz tracker aktywności
Tag śledzenia głowy jest tworzony raz w konstruktorze HelloCardboardApp
:
HelloCardboardApp::HelloCardboardApp(JavaVM* vm, jobject obj, jobject asset_mgr_obj) {
Cardboard_initializeAndroid(vm, obj); // Must be called in constructor
head_tracker_ = CardboardHeadTracker_create();
}
Po utworzeniu klasy VrActivity
generowana jest instancja klasy HelloCardboardApp
wywołując metodę nativeOnCreate
:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
Wstrzymaj i wznów tracker na głowie
Aby wstrzymać, wznowić lub zniszczyć tracker,
CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
,
i CardboardHeadTracker_destroy(head_tracker_)
muszą być wywoływane odpowiednio. W
"HelloCardboard" dzwonimy za nativeOnPause
, nativeOnResume
i
nativeOnDestroy
:
// 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;
}
Zniekształcenie obiektywu
Za każdym razem, gdy Cardboard skanuje nowy kod QR, ten kod odczytuje zapisane parametry. i używa ich do utworzenia obiektu zniekształcenia w obiektywie, który stosuje odpowiednie zniekształcenia. do wyrenderowanej treści:
CardboardQrCode_getSavedDeviceParams(&buffer, &size);
CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
buffer, size, screen_width_, screen_height_);
CardboardQrCode_destroy(buffer);
renderowanie,
Renderowanie treści w aplikacji Cardboard obejmuje:
- Tworzenie tekstur
- Pobieranie matryc obrazu i rzutu dla lewej i prawej gałki ocznej
- Tworzenie mechanizmu renderowania i konfigurowanie siatki zniekształceń
- Renderowanie każdej klatki
Tworzenie tekstur
Cała zawartość jest narysowana na teksturze, która jest podzielona na sekcje dla lewego i prawego oka.
Te sekcje są zainicjowane odpowiednio w _leftEyeTexture
i _rightEyeTexture
.
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");
}
Te tekstury są przekazywane jako parametry do funkcji CardboardDistortionRenderer_renderEyeToDisplay
.
Pobierz macierze obrazu i projekcji dla lewego i prawego oka
Najpierw pobierz macierze dla lewego i prawego oka:
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]);
Następnie pobierz siatki zniekształceń dla każdego oka i przekaż je do mechanizmu renderowania zniekształceń:
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);
Tworzenie mechanizmu renderowania i ustawianie prawidłowej siatki zniekształceń
Mechanizm renderowania wystarczy zainicjować tylko raz. Po utworzeniu mechanizmu renderowania ustaw nowy
dla lewego i prawego oka zgodnie z wartościami siatki zwróconymi przez
CardboardLensDistortion_getDistortionMesh
.
distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);
Renderowanie treści
Dla każdej klatki pobierz bieżącą orientację głowy z CardboardHeadTracker_getPose
:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Aby utworzyć widok, użyj bieżącej orientacji głowy z matrycami widoku i projekcji. matrycy projekcji dla każdego oczu i renderują zawartość ekranu:
// 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();
}
Aby zastosować zniekształcenie, użyj funkcji CardboardDistortionRenderer_renderEyeToDisplay
poprawienie treści i wyświetlenie jej na ekranie.
// Render
CardboardDistortionRenderer_renderEyeToDisplay(
distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
screen_width_, screen_height_, &left_eye_texture_description_,
&right_eye_texture_description_);