Questa guida mostra come utilizzare l'SDK Cardboard per Android per creare esperienze di realtà virtuale (VR).
Puoi usare l'SDK di Cardboard per trasformare uno smartphone in una piattaforma VR. Uno smartphone può mostrare scene 3D con rendering stereoscopico, seguire e reagire ai movimenti della testa e interagire con le app rilevando quando l'utente preme il pulsante del visore.
Per iniziare, utilizzerai HelloCardboard, un gioco demo che dimostra le caratteristiche principali dell'SDK di Cardboard. Nel gioco gli utenti esplorano il mondo virtuale per trovare e raccogliere oggetti. Ti mostra come:
- Configurazione dell'ambiente di sviluppo
- Scarica e crea l'app demo
- Scansiona il codice QR di un visore Cardboard per salvarne i parametri
- Monitorare i movimenti della testa dell'utente
- Esegui il rendering delle immagini stereoscopiche impostando la matrice di proiezione corretta per ogni occhio
HelloCardboard utilizza l'NDK di Android. Ogni metodo nativo è:
- Associato in modo univoco a un metodo di classe
HelloCardboardApp
oppure - Crea o elimina un'istanza di quella classe
Configurazione dell'ambiente di sviluppo
Requisiti hardware:
- Dispositivo Android con Android 8.0 "Oreo" (livello API 26) o versioni successive
- Visore Cardboard
Requisiti software:
- Android Studio versione 2022.1.1 "Electric Anguilla" o successive
- SDK per Android 13.0 "Tiramisù" (livello API 33) o versioni successive
La versione più recente del framework Android NDK
Per esaminare o aggiornare gli SDK installati, vai a Preferenze > Aspetto e comportamento
Impostazioni di sistema > SDK Android in Android Studio.
Scarica e crea l'app demo
L'SDK Cardboard è realizzato utilizzando un file di intestazione Vulkan precompilato per ogni Shader. La procedura per creare i file di intestazione da zero è disponibile qui.
Esegui questo comando per clonare l'SDK Cardboard e l'app demo HelloCardboard da GitHub:
git clone https://github.com/googlevr/cardboard.git
In Android Studio, seleziona Apri un progetto Android Studio esistente, quindi seleziona la directory in cui sono stati clonati l'SDK Cardboard e l'app demo HelloCardboard.
Il codice verrà visualizzato nella finestra del progetto in Android Studio.
Per assemblare l'SDK Cardboard, fai doppio clic sull'opzione Assembla nella cartella cardboard/:sdk/Tasks/build nella scheda Gradle (Visualizza > Finestre degli strumenti > Gradle).
Avvia l'app demo HelloCardboard sul tuo smartphone selezionando Esegui > Esegui... e seleziona il target
hellocardboard-android
.
Scansiona il codice QR
Per salvare i parametri del dispositivo, scansiona il codice QR sul visore Cardboard:
Se l'utente preme "IGNORA" e non esistono parametri salvati in precedenza, Cardboard salva i parametri di Google Cardboard v1 (lanciata alla conferenza Google I/O 2014).
Prova la demo
In HelloCardboard cercare e raccogliere sfere geodetiche nello spazio 3D.
Per trovare e raccogliere una sfera:
Muovi la testa in qualsiasi direzione finché non vedi una forma fluttuante.
Guardare direttamente la sfera. Questo causa la modifica dei colori.
Premi il pulsante del visore Cardboard per "raccogliere" la sfera.
Configura il dispositivo
Quando l'utente tocca l'icona a forma di ingranaggio per cambiare i visori Cardboard, viene richiamato il metodo nativeSwitchViewer
. nativeSwitchViewer
chiama
CardboardQrCode_scanQrCodeAndSaveDeviceParams
, che apre la finestra per scansionare
il codice QR dello spettatore. La distorsione dell'obiettivo e altri parametri del visualizzatore vengono aggiornati dopo la scansione del codice QR.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Attiva l'emulatore x86 di Android Studio
Per creare l'emulatore x86 per Android Studio, rimuovi la seguente riga dai file build.gradle
in SDK e in Esempio:
abiFilters 'armeabi-v7a', 'arm64-v8a'
Ciò abilita tutte le ABI e aumenterà notevolmente le dimensioni del file .aar
generato. Per ulteriori informazioni,
consulta le ABI Android.
Rilevamento dei movimenti della testa
Crea tracker della testa
Il tracker della testa viene creato una volta nel costruttore di HelloCardboardApp
:
HelloCardboardApp::HelloCardboardApp(JavaVM* vm, jobject obj, jobject asset_mgr_obj) {
Cardboard_initializeAndroid(vm, obj); // Must be called in constructor
head_tracker_ = CardboardHeadTracker_create();
}
Quando viene creata VrActivity
, viene generata un'istanza della classe HelloCardboardApp
chiamando il metodo nativeOnCreate
:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
Metti in pausa e riprendi il tracker della testa
Per mettere in pausa, riprendere e distruggere il tracker della testa, è necessario chiamare rispettivamente CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
e CardboardHeadTracker_destroy(head_tracker_)
. Nell'app "HelloCardboard", li chiamiamo in nativeOnPause
, nativeOnResume
e 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;
}
Distorsione obiettivo
Ogni volta che Cardboard scansiona un nuovo codice QR, il seguente codice legge i parametri salvati e li utilizza per creare l'oggetto di distorsione dell'obiettivo, che applica la corretta distorsione dell'obiettivo al contenuto visualizzato:
CardboardQrCode_getSavedDeviceParams(&buffer, &size);
CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
buffer, size, screen_width_, screen_height_);
CardboardQrCode_destroy(buffer);
Rendering
Il rendering dei contenuti in Cardboard prevede quanto segue:
- Creazione di texture
- Come ottenere le matrici di visualizzazione e di proiezione per l'occhio sinistro e destro
- Creazione del renderer e impostazione del mesh di distorsione
- Rendering di ogni frame
Crea texture
Tutti i contenuti vengono disegnati su una texture, suddivisa in sezioni per gli occhi destro e sinistro.
Queste sezioni sono inizializzate rispettivamente in _leftEyeTexture
e _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");
}
Queste texture vengono passate come parametri a CardboardDistortionRenderer_renderEyeToDisplay
.
Visualizza le matrici di visualizzazione e proiezione per l'occhio sinistro e destro
Per prima cosa, recupera le matrici dell'occhio sinistro e destro:
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]);
Quindi ottieni i mesh di distorsione per ciascuno degli occhi e passali al renderer di distorsione:
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);
Crea il renderer e imposta il mesh di distorsione corretto
Il renderer deve essere inizializzato una sola volta. Dopo aver creato il renderer, imposta il nuovo mesh di distorsione per gli occhi sinistro e destro in base ai valori mesh restituiti dalla funzione CardboardLensDistortion_getDistortionMesh
.
distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);
Rendering dei contenuti
Per ogni fotogramma, recupera l'orientamento corrente della testa da CardboardHeadTracker_getPose
:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Utilizza l'orientamento corrente della testa con le matrici di vista e proiezione per comporre una matrice di proiezione della vista per ciascuno degli occhi e per eseguire il rendering dei contenuti sullo schermo:
// 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();
}
Usa CardboardDistortionRenderer_renderEyeToDisplay
per applicare la correzione della distorsione
ai contenuti e visualizzarli sullo schermo.
// Render
CardboardDistortionRenderer_renderEyeToDisplay(
distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
screen_width_, screen_height_, &left_eye_texture_description_,
&right_eye_texture_description_);