Z tego przewodnika dowiesz się, jak za pomocą pakietu SDK Cardboard na Androida tworzyć własne rozwiązania 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, a także wchodzić w interakcje z aplikacjami, wykrywając, kiedy użytkownik naciśnie przycisk gogli.
Na początek użyj HelloCardboard – gry demonstracyjnej, która prezentuje główne funkcje pakietu Cardboard SDK. Użytkownicy 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 stereoskopowe obrazy, ustawiając odpowiednią macierz projekcji obrazu dla każdego oka.
HelloCardboard korzysta z pakietu NDK Androida. Każda metoda natywna:
- Ograniczony jednoznacznie do metody 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 nowszym,
- Gogle Google Cardboard
Wymagania dotyczące oprogramowania:
- Android Studio w wersji 2022.1.1 „Electric Eel” lub nowszy,
- Android SDK 13.0 „Tiramisu” (poziom interfejsu API 33) lub nowszy
Najnowsza wersja platformy Android NDK
Aby przejrzeć lub zaktualizować zainstalowane pakiety SDK, kliknij Ustawienia > Wygląd i działanie.
Ustawienia systemu > Android SDK w Android Studio.
Pobierz i stwórz aplikację demonstracyjną
Pakiet Cardboard SDK został utworzony na podstawie wstępnie skompilowanego pliku nagłówka Vulkan dla każdego programu do cieniowania. Instrukcje tworzenia plików nagłówkowych od zera znajdziesz tutaj.
Uruchom to polecenie, aby skopiować pakiet SDK Cardboard i wersję demonstracyjną aplikacji HelloCardboard z GitHuba:
git clone https://github.com/googlevr/cardboard.git
W Android Studio wybierz Otwórz istniejący projekt Android Studio, a potem wybierz katalog, w którym sklonowano pakiet SDK Cardboard i aplikację demonstracyjną HelloCardboard.
Kod pojawi się w oknie projektu w Android Studio.
Aby złożyć pakiet SDK Cardboard, kliknij dwukrotnie opcję montuj w folderze cardboard/:sdk/Tasks/build (Widok > Okna narzędzi > Gradle).
Uruchom demonstracyjną aplikację HelloCardboard na telefonie, wybierając Uruchom > Uruchom... i wybierz
hellocardboard-android
środowisko docelowe.
Zeskanuj kod QR
Aby zapisać parametry urządzenia, zeskanuj kod QR za pomocą gogli Cardboard:
Jeśli użytkownik naciśnie „POMIŃ” bez zapisanych wcześniej parametrów, Cardboard zapisze parametry Google Cardboard v1 (udostępnionej na konferencji Google I/O 2014).
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ący się kształt.
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, wywołana jest metoda nativeSwitchViewer
. nativeSwitchViewer
wywołuje CardboardQrCode_scanQrCodeAndSaveDeviceParams
, co otwiera okno, w którym można zeskanować kod QR widza. Zniekształcenie obiektywu i inne parametry gogli zostaną zaktualizowane po zeskanowaniu kodu QR.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Włącz emulator Androida Studio x86
Aby utworzyć kompilację do emulatora Androida Studio x86, usuń ten wiersz z plików build.gradle
w pakietach SDK i Przykład:
abiFilters 'armeabi-v7a', 'arm64-v8a'
Spowoduje to włączenie wszystkich interfejsów ABI i znacznie zwiększy rozmiar wygenerowanego pliku .aar
. Więcej informacji znajdziesz w sekcji na temat interfejsów ABI Androida.
Monitorowanie ruchów głowy
Utwórz urządzenie śledzące ruchy głowy
Monitorowanie ruchów głowy tworzony jest 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
instancja klasy HelloCardboardApp
jest generowana przez wywołanie metody nativeOnCreate
:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
Wstrzymywanie i wznawianie śledzenia ruchów głowy
Aby wstrzymać, wznowić i zniszczyć urządzenie śledzące, należy wywołać odpowiednio CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
i CardboardHeadTracker_destroy(head_tracker_)
. W aplikacji „HelloCardboard” wywołujemy je w językach 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, 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(&buffer, &size);
CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
buffer, size, screen_width_, screen_height_);
CardboardQrCode_destroy(buffer);
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
Cała zawartość jest rysowana na teksturze, która jest podzielona na sekcje dla lewego i prawego oka.
Inicjowane sekcje są odpowiednio _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 widoku i odwzorowania dla lewego i prawego oka
Najpierw pobierz macierze oka 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 sieci zniekształceń dla każdego oczu i przekaż je do mechanizmu renderowania zniekształceń:
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);
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
.
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łowicy z CardboardHeadTracker_getPose
:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Użyj bieżącej orientacji głowy z matrycami widoku i projekcji, aby utworzyć macierz projekcji widoków dla każdego oczu i renderować zawartość na ekran:
// 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();
}
Użyj narzędzia CardboardDistortionRenderer_renderEyeToDisplay
, aby zastosować korektę zniekształceń do treści i wyrenderować ją 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_);