Guia de início rápido do Google Cardboard para iOS

Este guia mostra como usar o SDK do Cardboard para iOS para criar seu próprio Experiências de realidade (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, rastrear e reagir a movimentos da cabeça e interagem com apps detectando quando o usuário pressiona o botão do visualizador.

Para começar, você vai usar o HelloCardboard, um jogo de demonstração que demonstra os principais recursos do SDK do Cardboard. No jogo, os usuários olham ao redor do mundo virtual para encontrar e coletar objetos. Ele mostra como:

  • Configurar o ambiente de desenvolvimento
  • Fazer o download e criar o app de demonstração
  • Ler o QR code de um visor do Google Cardboard para salvar os parâmetros dele
  • Monitorar os movimentos da cabeça do usuário
  • Renderizar imagens estereoscópicas definindo a distorção correta para cada olho

Configurar o ambiente de desenvolvimento

Requisitos de hardware:

Requisitos de software:

Fazer o download e criar o app de demonstração

O SDK do Cardboard é criado usando buffers de protocolo pré-compilados Arquivos de origem C++. As etapas para criar os arquivos de origem do zero podem ser encontradas aqui.

  1. Clone o SDK do Cardboard e o app de demonstração do Hello Cardboard do GitHub: executando este comando:

    git clone https://github.com/googlevr/cardboard.git
  2. Instale a dependência dos Buffers de protocolo no projeto Xcode executando este comando na raiz do repositório:

    pod install
  3. Abra o espaço de trabalho do Cardboard (Cardboard.xcworkspace) no Xcode.

  4. Altere o ID do pacote do app para assiná-lo com sua equipe.

  5. Acesse SDK > Fases de compilação > Vincular binário com bibliotecas

    1. Selecione libPods-sdk.a e clique no ícone "-" para removê-lo da lista .
    2. Adicione libProtobuf-C++.a à lista clicando no sinal "+" e selecionando o botão. Caso apareça uma mensagem sugerindo o uso de um XCFramework, clique em "Adicionar mesmo assim".
  6. Clique em Executar.

Leia o QR code

Para salvar os parâmetros do dispositivo, leia o QR code no visor do Google Cardboard:

Teste a demonstração

No HelloCardboard, você procura e coleta esferas geodésicas no espaço 3D.

Para encontrar e coletar uma esfera:

  1. Mova a cabeça em qualquer direção até ver uma esfera flutuante.

  2. Olhe diretamente para a esfera. Isso faz com que ele mude de cor.

  3. Pressione o botão do visor do Google Cardboard para "coletar" na esfera.

Configurar o dispositivo

Quando o usuário toca no ícone de engrenagem para alternar os visores do Google Cardboard, o didTapSwitchButton é chamado em HelloCardboardOverlayView.

- (void)didTapSwitchButton:(id)sender {
  if ([self.delegate respondsToSelector:@selector(didTapBackButton)]) {
    [self.delegate didChangeViewerProfile];
  }
  self.settingsBackgroundView.hidden = YES;
}

Isso chama CardboardQrCode_scanQrCodeAndSaveDeviceParams, que abre a para ler o QR code do leitor. Quando o usuário faz a leitura do QR code, o código parâmetros de distorção são atualizados.

- (void)switchViewer {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

- (void)didChangeViewerProfile {
  [self pauseCardboard];
  [self switchViewer];
  [self resumeCardboard];
}

rastreamento da cabeça

Criar um rastreador de cabeça

O rastreador principal é criado uma vez no método viewDidLoad de HelloCardboardViewController:

_cardboardHeadTracker = CardboardHeadTracker_create();

Pausar e retomar o rastreador da cabeça

Os métodos pauseCardboard e resumeCardboard na Pause a classe HelloCardboardViewController e retome o rastreador principal, respectivamente. resumeCardboard também define a flag _updateParams, que faz com que os parâmetros do dispositivo a serem atualizados na próxima chamada de desenho.

- (void)pauseCardboard {
  self.paused = true;
  CardboardHeadTracker_pause(_cardboardHeadTracker);
}

- (void)resumeCardboard {
  // Parameters may have changed.
  _updateParams = YES;

  // Check for device parameters existence in app storage. If they're missing,
  // we must scan a Cardboard QR code and save the obtained parameters.
  uint8_t *buffer;
  int size;
  CardboardQrCode_getSavedDeviceParams(&buffer, &size);
  if (size == 0) {
    [self switchViewer];
  }
  CardboardQrCode_destroy(buffer);

  CardboardHeadTracker_resume(_cardboardHeadTracker);
  self.paused = false;
}

Distorção da lente

Sempre que o Cardboard ler um novo QR code, o código a seguir lerá os parâmetros salvos. e os usa para criar o objeto de distorção da lente, que aplica a distorção adequada ao conteúdo renderizado:

CardboardQrCode_getSavedDeviceParams(&encodedDeviceParams, &size);

// Create CardboardLensDistortion.
CardboardLensDistortion_destroy(_cardboardLensDistortion);
_cardboardLensDistortion =
    CardboardLensDistortion_create(encodedDeviceParams, size, width, height);

// Initialize HelloCardboardRenderer.
_renderer.reset(new cardboard::hello_cardboard::HelloCardboardRenderer(
      _cardboardLensDistortion, _cardboardHeadTracker, width, height));

Renderização

A renderização de conteúdo no Cardboard envolve o seguinte:

  • Como criar texturas
  • Como obter matrizes de visã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

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. O aplicativo de exemplo usa uma única textura para ambos os olhos, mas também é possível criar uma textura separada textura para cada olho.

// Generate texture to render left and right eyes.
glGenTextures(1, &_eyeTexture);
glBindTexture(GL_TEXTURE_2D, _eyeTexture);
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, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

_leftEyeTexture.texture = _eyeTexture;
_leftEyeTexture.left_u = 0;
_leftEyeTexture.right_u = 0.5;
_leftEyeTexture.top_v = 1;
_leftEyeTexture.bottom_v = 0;

_rightEyeTexture.texture = _eyeTexture;
_rightEyeTexture.left_u = 0.5;
_rightEyeTexture.right_u = 1;
_rightEyeTexture.top_v = 1;
_rightEyeTexture.bottom_v = 0;
CheckGLError("Create Eye textures");

Essas texturas são transmitidas como parâmetros para CardboardDistortionRenderer_renderEyeToDisplay.

Obter matrizes de visão e projeção para o olho esquerdo e direito

Primeiro, recupere as matrizes oculares para os olhos esquerdo e direito:

CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kLeft, _eyeMatrices[kLeft]);
CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kRight, _eyeMatrices[kRight]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kLeft, kZNear, kZFar,
                                            _projMatrices[kLeft]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kRight, kZNear, kZFar,
                                            _projMatrices[kRight]);

Em seguida, colete as malhas de distorção para cada um dos olhos e transmita-as para o renderizador de distorção:

CardboardLensDistortion_getDistortionMesh(_lensDistortion, kLeft, &leftMesh);
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kRight, &rightMesh);

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 o novo de distorção para os olhos esquerdo e direito, de acordo com os valores de malha retornados do função CardboardLensDistortion_getDistortionMesh.

_distortionRenderer = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(_distortionRenderer, &leftMesh, kLeft);
CardboardDistortionRenderer_setMesh(_distortionRenderer, &rightMesh, kRight);

Renderizar o conteúdo

Recupere a orientação atual da cabeça de CardboardHeadTracker_getPose:

CardboardHeadTracker_getPose(_headTracker, targetTime, position, orientation);
_headView =
    GLKMatrix4Multiply(GLKMatrix4MakeTranslation(position[0], position[1], position[2]),
                       GLKMatrix4MakeWithQuaternion(GLKQuaternionMakeWithArray(orientation)));

Usar a orientação atual da cabeça com as matrizes de visualização e projeção para compor uma visualização matriz de projeção e usá-las para renderizar o conteúdo mundial para cada um dos olhos:

// Draw left eye.
glViewport(0, 0, _width / 2.0, _height);
glScissor(0, 0, _width / 2.0, _height);
DrawWorld(_leftEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kLeft]));

// Draw right eye.
glViewport(_width / 2.0, 0, _width / 2.0, _height);
glScissor(_width / 2.0, 0, _width / 2.0, _height);
DrawWorld(_rightEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kRight]));

Usar CardboardDistortionRenderer_renderEyeToDisplay para aplicar a distorção a correção do conteúdo e o renderiza na tela.

CardboardDistortionRenderer_renderEyeToDisplay(_distortionRenderer, renderTarget, /*x=*/0,
                                               /*y=*/0, _width, _height, &_leftEyeTexture,
                                               &_rightEyeTexture);