En esta guía, se muestra cómo usar el SDK de Cardboard para que Android cree tus propias experiencias de realidad virtual (RV).
Puedes usar el SDK de Cardboard para convertir un smartphone en una plataforma de RV. Un smartphone puede mostrar escenas en 3D con renderización estereoscópica, seguir y reaccionar a los movimientos de la cabeza, e interactuar con las apps detectando cuando el usuario presiona el botón del visor.
Para comenzar, usa HelloCardboard, un juego de demostración que demuestra los del SDK de Cardboard. En el juego, los usuarios miran alrededor de un mundo virtual para encontrar y recolectar objetos. Allí se indica cómo hacer lo siguiente:
- Configura tu entorno de desarrollo
- Descarga y compila la app de demostración
- Escanea el código QR de un visor Cardboard para guardar sus parámetros
- Realizar un seguimiento de los movimientos de la cabeza del usuario
- Renderiza imágenes estereoscópicas configurando la matriz de proyección de vista correcta para cada ojo.
HelloCardboard usa el NDK de Android. Cada método nativo tiene las siguientes características:
- Está limitada de forma única a un método de clase
HelloCardboardApp
. - Crea o borra una instancia de esa clase.
Configura tu entorno de desarrollo
Requisitos de hardware:
- Dispositivo Android con Android Oreo 8.0 (nivel de API 26) o una versión posterior
- Visor de Cardboard
Requisitos de software:
- Android Studio versión 2022.1.1 "Electric Eel" o una superior
- SDK de Android 13.0 "Tiramisu" (nivel de API 33) o versiones posteriores
La versión más reciente del framework del NDK de Android
Para revisar o actualizar los SDKs instalados, ve a Preferencias > Apariencia y comportamiento
Configuración del sistema > SDK de Android en Android Studio.
Descarga y compila la app de demostración
El SDK de Cardboard se compiló con un Vulkan precompilado. de encabezado de cada sombreador. Puedes encontrar los pasos para compilar los archivos de encabezado desde cero aquí.
Ejecuta el siguiente comando para clonar el SDK de Cardboard y la demostración de HelloCardboard. App de GitHub:
git clone https://github.com/googlevr/cardboard.git
En Android Studio, selecciona Open an existing Android Studio Project y, luego, elige la en el que se clonaron el SDK de Cardboard y la app de demostración HelloCardboard.
Tu código aparecerá en la ventana Project de Android Studio.
Para armar el SDK de Cardboard, haz doble clic en la opción ensamblar dentro La carpeta cardboard/:sdk/Tasks/build en la pestaña Gradle (View > Tool Windows > Gradle).
Ejecuta la app de demo de HelloCardboard en tu teléfono. Para ello, selecciona Run > Ejecutar... Selecciona el objetivo
hellocardboard-android
.
Escanea el código QR
Para guardar los parámetros del dispositivo, escanea el código QR del visor Cardboard:
Si el usuario presiona “OMITIR” y no hay parámetros guardados anteriormente, Cardboard guarda Parámetros de Google Cardboard v1 (lanzado en Google I/O 2014)
Probar la demostración
En HelloCardboard, buscarás y recopilarás esferas geodésicas en un espacio 3D.
Para buscar y recopilar una esfera, sigue estos pasos:
Mueve la cabeza en cualquier dirección hasta que veas una forma flotante.
Mira directamente la esfera. Esto hace que cambie de color.
Presiona el botón del visor Cardboard para "recopilar" la esfera.
Configura el dispositivo
Cuando el usuario presiona el ícono de ajustes para cambiar los visores de Cardboard, el elemento nativeSwitchViewer
método. nativeSwitchViewer
llamada
CardboardQrCode_scanQrCodeAndSaveDeviceParams
, que abre una ventana para analizar
el código QR del usuario. La distorsión de lente del usuario y otros parámetros se actualizan una vez
se escanee el código QR.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Cómo habilitar el emulador de Android Studio x86
Para compilar el emulador de Android Studio x86, quita la siguiente línea de
Archivos build.gradle
en el SDK
y Muestra:
abiFilters 'armeabi-v7a', 'arm64-v8a'
De esta manera, se habilitarán todas las ABI y se aumentará de forma significativa el tamaño de la interfaz
.aar
. Consulta ABI de Android
para obtener más información.
Seguimiento de cabeza
Crea un monitor de cabeza
El seguimiento de cabeza se crea una vez en el constructor de HelloCardboardApp
:
HelloCardboardApp::HelloCardboardApp(JavaVM* vm, jobject obj, jobject asset_mgr_obj) {
Cardboard_initializeAndroid(vm, obj); // Must be called in constructor
head_tracker_ = CardboardHeadTracker_create();
}
Cuando se crea VrActivity
, se genera una instancia de la clase HelloCardboardApp
.
llamando al método nativeOnCreate
:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
Pausar y reanudar el seguimiento de la cabeza
Para pausar, reanudar y destruir el dispositivo de rastreo de la cabeza, haz lo siguiente:
CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
,
y se debe llamar a CardboardHeadTracker_destroy(head_tracker_)
, respectivamente. En la
"HelloCardboard" la llamamos en nativeOnPause
, nativeOnResume
y
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;
}
Distorsión del lente
Cada vez que Cardboard escanea un nuevo código QR, el siguiente código lee los parámetros guardados y los usa para crear el objeto de distorsión de la lente, que aplica la distorsión de lente adecuada al contenido procesado:
CardboardQrCode_getSavedDeviceParams(&buffer, &size);
CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
buffer, size, screen_width_, screen_height_);
CardboardQrCode_destroy(buffer);
Renderización
La renderización de contenido en Cardboard implica lo siguiente:
- Cómo crear texturas
- Obtén matrices de vistas y proyección para el ojo izquierdo y derecho
- Cómo crear el procesador y configurar la malla de distorsión
- Cómo renderizar cada fotograma
Crea texturas
Todo el contenido se dibuja en una textura que se divide en secciones para el ojo izquierdo y el derecho.
Estas secciones se inicializan en _leftEyeTexture
y _rightEyeTexture
, respectivamente.
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");
}
Esas texturas se pasan como parámetros a CardboardDistortionRenderer_renderEyeToDisplay
.
Obtén matrices de vistas y proyección para el ojo izquierdo y derecho
Primero, recupera las matrices oculares para el ojo izquierdo y derecho:
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]);
A continuación, obtén las mallas de distorsión para cada uno de los ojos y pásalas al renderizador de distorsión:
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);
Crea el procesador y establece la malla de distorsión correcta
El renderizador solo se debe inicializar una vez. Cuando se haya creado el renderizador, configura el nuevo
malla de distorsión para el ojo izquierdo y derecho de acuerdo con los valores de malla que devuelve el
función CardboardLensDistortion_getDistortionMesh
.
distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);
Cómo renderizar el contenido
Para cada fotograma, recupera la orientación actual de la cabeza desde CardboardHeadTracker_getPose
:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Usa la orientación actual de la cabeza con las matrices de vista y proyección para crear una vista de proyección para cada uno de los ojos y renderizar el contenido en la pantalla:
// 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
para aplicar la distorsión.
corrección del contenido y renderizarlo en la pantalla.
// Render
CardboardDistortionRenderer_renderEyeToDisplay(
distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
screen_width_, screen_height_, &left_eye_texture_description_,
&right_eye_texture_description_);