Este guia mostra como usar o SDK do Cardboard para Android para criar suas próprias experiências de Realidade Virtual (RV).
Você pode usar o SDK do Cardboard para transformar um smartphone em uma plataforma de RV. Um smartphone pode exibir cenas em 3D com renderização estereoscópica, acompanhar e reagir a movimentos da cabeça e interagir com apps detectando quando o usuário pressiona o botão do visualizador.
Para começar, use o HelloCardboard, um jogo de demonstração que demonstra os principais recursos do SDK do Cardboard. No jogo, os usuários procuram em um mundo virtual para encontrar e coletar objetos. Ele mostra como:
- Configurar o ambiente de desenvolvimento
- Fazer o download e criar o aplicativo de demonstração
- Leia o código QR de um visor do Google Cardboard para salvar os parâmetros dele
- Acompanhar os movimentos da cabeça do usuário
- Renderize imagens estereoscópicas definindo a matriz de projeção de visualização correta para cada olho
O HelloCardboard usa o Android NDK. Cada método nativo é:
- Vinculado exclusivamente a um método da classe
HelloCardboardApp
ou - Cria ou exclui uma instância dessa classe
Configurar o ambiente de desenvolvimento
Requisitos de hardware:
- Dispositivo com o Android 7.0 "Nougat" (nível 24 da API) ou mais recente
- Visualizador do Cardboard
Requisitos de software:
- Android Studio versão 4.2.2 ou posterior
- SDK do Android 11.0 "R" (API de nível 30) ou mais recente
A versão mais recente da biblioteca do Android NDK
Para revisar ou atualizar SDKs instalados, acesse Preferências > Aparência e comportamento
System Settings > Android SDK no Android Studio.
Fazer o download e criar o aplicativo de demonstração
O SDK do Cardboard é criado usando um arquivo de cabeçalho Vulkan pré-compilado para cada sombreador. As etapas para criar os arquivos de cabeçalho do zero podem ser encontradas neste link.
Execute o seguinte comando para clonar o SDK do Cardboard e o aplicativo de demonstração HelloCardboard no GitHub:
git clone https://github.com/googlevr/cardboard.git
No Android Studio, selecione Abrir um projeto existente do Android Studio e selecione o diretório em que o SDK do Cardboard e o aplicativo de demonstração HelloCardboard foram clonados.
O código vai aparecer na janela "Project" do Android Studio.
Para montar o SDK do Cardboard, clique duas vezes na opção assemble dentro da pasta cardboard/:sdk/Tasks/build na guia do Gradle (View > Tool Windows > Gradle).
Execute o app de demonstração HelloCardboard no seu smartphone selecionando Run > Run... e selecionando o destino
hellocardboard-android
.
Leia o código QR
Para salvar os parâmetros do dispositivo, leia o código QR no visualizador do Google Cardboard:
Se o usuário pressionar "SKIP" e não houver parâmetros salvos anteriormente, o Google Cardboard salvará os parâmetros do Google Cardboard v1 (lançado no Google I/O 2014).
Iniciar a demonstração
No HelloCardboard, você procurará e coletar esferas geodésicas no espaço 3D.
Para encontrar e coletar uma esfera:
Mova a cabeça em qualquer direção até ver uma forma flutuante.
Olhe diretamente para a esfera. Isso faz com que ele mude de cor.
Pressione o botão do visor do Google Cardboard para "coletar" a esfera.
Configurar o dispositivo
Quando o usuário toca no ícone de engrenagem para alternar entre os visualizadores do Google Cardboard, o método nativeSwitchViewer
é chamado. nativeSwitchViewer
chama
CardboardQrCode_scanQrCodeAndSaveDeviceParams
, que abre a janela para ler
o código QR do visualizador. A distorção de lente do visualizador e outros parâmetros são atualizados depois
que o código QR é lido.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
Ativar o emulador do Android Studio x86
Para criar para o emulador do Android Studio x86, remova a seguinte linha dos
arquivos build.gradle
no SDK
e Sample:
abiFilters 'armeabi-v7a', 'arm64-v8a'
Isso ativa todas as ABIs e aumenta significativamente o tamanho do arquivo
.aar
gerado. Consulte ABIs do Android para ver mais informações.
Acompanhamento da cabeça
Criar tracker principal
O rastreador principal é criado uma vez no construtor do 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 VrActivity
é criado, uma instância da classe HelloCardboardApp
é gerada
chamando o método nativeOnCreate
:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
nativeApp = nativeOnCreate(getAssets());
//...
}
Pausar e retomar o tracker principal
Para pausar, retomar e destruir o rastreador principal, é preciso chamar CardboardHeadTracker_pause(head_tracker_)
, CardboardHeadTracker_resume(head_tracker_)
e CardboardHeadTracker_destroy(head_tracker_)
, respectivamente. No
app "HelloCardboard", os chamamos em 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;
}
Distorção de lentes
Sempre que o Cardboard lê um novo código QR, o código a seguir lê os parâmetros salvos e os usa para criar o objeto de distorção de lentes, que aplica a distorção adequada ao conteúdo renderizado:
CardboardQrCode_getSavedDeviceParams(&buffer, &size);
CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
buffer, size, screen_width_, screen_height_);
CardboardQrCode_destroy(buffer);
Renderização
A renderização de conteúdo no Cardboard envolve:
- Como criar texturas
- Obtenção de matrizes de visualização e projeção para os olhos esquerdo e direito
- Como criar o renderizador e definir a malha de distorção
- Como renderizar cada frame
Criar texturas
Todo o conteúdo é desenhado em uma textura, que é dividida em seções para os olhos esquerdo e direito.
Essas seções são inicializadas em _leftEyeTexture
e _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");
}
Essas texturas são transmitidas como parâmetros para CardboardDistortionRenderer_renderEyeToDisplay
.
Acessar matrizes de visualização e projeção para os olhos esquerdo e direito
Primeiro, recupere matrizes para os olhos esquerdo e direito:
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]);
Em seguida, pegue as malhas de distorção de cada um dos olhos e passe-as para o renderizador de distorção:
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);
Criar o renderizador e definir a malha de distorção correta
O renderizador precisa ser inicializado apenas uma vez. Depois que o renderizador for criado, defina a nova malha de distorção para os olhos esquerdo e direito de acordo com os valores de malha retornados da função CardboardLensDistortion_getDistortionMesh
.
distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);
Como renderizar o conteúdo
Para cada frame, recupere a orientação atual da cabeça de CardboardHeadTracker_getPose
:
CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);
Use a orientação atual da cabeça com as matrizes de visualização e projeção para compor uma matriz de projeção de visualização para cada um dos olhos e renderizar o conteúdo na tela:
// 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();
}
Use CardboardDistortionRenderer_renderEyeToDisplay
para aplicar a correção da distorção ao conteúdo e renderizar o conteúdo na tela.
// Render
CardboardDistortionRenderer_renderEyeToDisplay(
distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
screen_width_, screen_height_, &left_eye_texture_description_,
&right_eye_texture_description_);