# Programação com OpenGL/Instalação/Android NDK

Nosso tutorial de GLUT pode ser rodado no Android usando um simples empacotador(wrapper) próprio.
Nota: Um empacotador(wrapper) vem sendo integrado ao FreeGLUT oficial! (Fonte)

## Nosso empacotador(wrapper)

Para entender como o nosso empacotador(wrapper) GLUT funciona, veja Android GLUT Wrapper

## Dependências

Este documento foi feito usando o Android NDK r7c. Você também precisará de um ambiente de desenvolvimento em Java:
Seu programa também vai precisar do GLM e FreeType - veja nas seções dedicadas abaixo.

## Emulador (falta de) suporte para o OpenGL ES 2.0

O emulador do Android começou a suportar a OpenGL ES 2.0 apenas em Abril de 2012, requerendo assim um emulador bem configurado e um sistema de imagem(system image), e não parece funcionar em todas as plataformas.
Também tenha cuidado com as "API Demos" os aplicativos estão em "OpenGL ES 2.0" que silenciosamente falha com OpenGL ES 1.0 se não tiver suporte a versão 2.0, por isto elas não são um bom teste para ver se a OpenGL ES 2.0 é suportada.
Então apenas faça testes com OpenGL 2.0 em aparelho Android com suporte a ela.
Documentação Oficial: https://developer.android.com/tools/devices/emulator.html#accel-graphics

## Conectando Aparelho pela USB

Quando você conectar seu aparelho pela USB, você poderá usar os comandos da adb ( disponivel na Android SDK) para navegar pelo sistema de arquivos e instalar aplicativos, debugar eles e etc...
O jeito mais fácil rodar o adb como root(superusuário).

## Permitir acesso pelo USB para usuários non-root

Uma alternativa é liberando o acesso a usuários sem privilégios para conectar ao dispositivo, através da criação de um arquivo udev Primeiro, determine o idVendor do seu aparelho, digitando 'dmesg' depois de conecta-lo; deverá aparecer mais ou menos isto:
Em seguida crie a regra udev abaixo, que estará em /etc/udev/rules.d/51-android.rules:
(Isto pode ser melhorado com o idProduct.) Em seguida reinicie o serviço udev:
Se você plugar seu dispositivo, o carácter USB do dispositivo deverá aparecer no grupo "plugdev":

## Usando nosso empacotador(wrapper)

Neste wikibook, os exemplos serão baseados na biblioteca GLUT
o GLUT ainda não foi portada para o Android, então escreveremos um simples empacotador(wrapper) para Android( veja em repositório de código).
Nota: este empacotador(wrapper) ainda é bem recente e poderá haver algumas mudanças futuramente.
Veja como usa-lo:
Procure o diretório 'tut01_intro_android/'.
* Conecte seu dispositivo ( smartphone, tablet...) pela USB
* Adicione as directivas do PATH pelas ferramentas do Android:
Here's how to use it:
* Dentro da pasta jni/, faça do tut.cpp um symlink(link simbólico) para poder compilar código com GLUT (ex: ../../tut02_clean/triangle.cpp)
* Faça um assets como link simbólico para o tutorial que você está compilando (ex: ../tut02_clean)
* Agora vocẽ pode digitar:
* Você vai ter uma aplicação "OpenGL Wikibook" em seu dispostivo, pronto para rodar!

## Tela Cheia

Para fazer um aplicativo de tela cheia, adicione os seguintes atributos em sua AndroidManifest.xml

## Teclado

O teclado padrão do Android não possue as teclas F1/F2/F3.
Em vez disto, você pode usar um "Teclado Hackeado" com alternativa para dispositivo com mais teclas:
* homepage.
* market

## Ícone

Certifique-se que seu aplicativo possua o android:icon definido em AndroidManifest.xml:
Crie dois icones:
* res/drawable/icon.png (48x48)
* res/drawable-hdpi/icon.png (72x72)
Agora seu aplicativo possue um ícone personalizado no lançador.r.

## Debugando

se você quer ver as saídas padrão (stdout e stderr) do seu programa, você precisa redirecionar para o log do sistema:
Para ver os arquivos de log, você pode usar:
* O comando: adb logcat
* O utilitário 'ddms', que é uma GUI gráfica para navegar nos logs.
* O Eclipse possui um LogCat similar ao 'ddms'

## Vendo as chamadas da JNI

Você ativar o acompanhador das chamadas do JNI para o C/C++, assim:
Você vai obter todos traços adicionais no log do sistema, e o JNI ficara mais restrito ao que ele pode aceitar.

## GDB

O GDB pode ser usado também
Nota: no NDKr7, existe algumas questões a serem resolvidas para ele funcionar:
* Veja abaixo se você usa o Cyanogen 7.1 para corrigir o 'run-as'
* Usando o formato "stabs" para depurar os símbolos no Android.mk, senão o GDB pode mostrar as linhas de códigos errada:
GDB precisa da depuração do compilador, coloque um NDK_DEBUG=1 enquanto compila seu código C++:
Enquanto inicia o gdb, veja se seu AndroidManifest.xml menciona um depurador, se não o gdb se comportará mal (com falhas nas informações do thread, crash e etc...):
O gdb-server precisa de alguns segundos para iniciar no seu dispositivo, assim que seu programa iniciar ele possa de ser pausado pelo depurador. você precisar colocar em sua função android_main:
Para iniciar a sessão do depurador, digite:

### Correção no Cyanogen 2.3

o ndk-gdb depende do comando run-as, que faz uma série de verificações na pasta /data/data No Cyanogen 2.3, é um link simbólico, e falha com uma mensagem estranha, e o ndk-gdb falha retornado com:
Então trabalhe em cima para recriar o /data/data com link simbólico :

## Carregamento da biblioteca nativa indisponível

Se aparecer este erro: E/AndroidRuntime( 3021): java.lang.RuntimeException: Unable to start activity
O sistema não pode carregar sua .so para acessar ao baixo nível do sistema.
Para obter maiores informações você precisa criar um aplicativo Java bem simples para carregar as bibliotecas manualmente:
Pode aparecer um este erro mais especifico, existe uma falha na implementação do STL:
ou falta uma dependência:
No pior caso, a biblioteca pode não carregar totalmente. Isto pode acontecer caso quando o construtor do C++ de uma global estática quebrar enquanto chama a biblioteca, mesmo antes de sua aplicação ser iniciada. Você precisa reproduzir um carregamento de uma biblioteca em C básico:
Para manda-lo para o dispositivo execute isto:
Você também pode usar o strace que é mais precisa:
Lá não possui um ldd como padrão do Android, mas você pode simular ele usando:

## Abstração das diferenças entre o OpenGL e o GLES2

Quando você usa apenas as funções do GLES2, seus aplicativos não são portáveis para desktop ou dispositivo moveis. Existe algumas questões que precisam ser tratadas:
* O GLSL #version é diferente.
* O GLES2 precisa que alguns pontos de precisão que não são compatíveis com o OpenGL 2.1
Veja nos tutoriais básico 02 e 03 para mais detalhes e a uma solução proposta.

## GLM

Para instalar o GLM, você precisa extrair a ultima versão em em /usr/src/glm (de mode que o /usr/src/glm/glm.hpp exista). Ela é apenas uma biblioteca-cabeçalho não é necessário uma compilação separada.

## FreeType

Se você precisar da FreeType (a biblioteca de fontes), você que fazer uma compilação-cruzada. Nota: O Android usa o FreeType porem apenas internalmente ele não está disponível para um native apps.
Primeiro, prepare o compilador-cruzado pelo NDK:
Em seguida use o compilado-cruzado para o freetype:
(Você pode usar o --prefix=/usr/src/ndk-standalone-9/sysrot/usr como alternativa se você não planeja usar o compilador NDK do sistema.)
--without-zlib é usado internalmente para copiar o zlib dentro do freetype bastante usado em compilações independentes para Android, senão dara erros como:
Em seguida escreva no Android.mk a nova pasta do freetype:
See docs/STANDALONE-TOOLCHAIN.html and docs/PREBUILTS.html in the NDK for details. The CLEAR_VARS bit is not documented, but is necessary to avoid mixed-up paths; it is used in the native_app_glue NDK module. Para usar o FreeType em seus projetos edite o arquivo Android.mk:
Para isto você especificara a pasta aonde o freetype esta, usando a variável NDK_MODULE_PATH. Para instancia-lo, você precisa copiar o freetype na pasta do seu projeto e compilar usando o:
Nosso empacotador já esta definido em NDK_MODULE_PATH=$$NDK_MODULE_PATH:.
Nota: Antes na versão 2.4.10, você precisava usar o CFLAGS="-std=gnu99" nas linhas do ./configure, veja nesta discussão. Isto foi oficialmente comunicado e corrigido no canal do FreeType