Full text
UNIVERSIDAD POLIT´ ECNICA DE VALENCIA Proyecto Final de Carrera Visualizaci´ on interactiva de escenas tridimensionales con OpenSceneGraph sobre dispositivos Android Autor: Jorge Izquierdo Ciges Titulaci´ on: Ingenier´ ıa Inform´ atica Dirigido por: Javier Lluch Crespo y Jordi Torres Fabra Instituto de Autom´atica e Inform´atica Industrial (AI2) Universidad Polit´ecnica de Valencia Camino de Vera, s/n 46020 Valencia, Spain 13 de septiembre de 2011
2
Palabras Clave Gr´ aficos por computador, Android, dispositivos embebidos, smartphones, OpenSceneGraph, OSG, grafo de escena, representaci´ on de escenas tridimensionales, representaci´ on de terrenos, GIS, 3D. 3
4
Resumen La representaci´ on interactiva de escenas tridimensionales en dispositivos m´ oviles es un problema con un largo recorrido. Con el aumento de las caracter´ ısticas de los dispositivos embebidos, la creaci´ on de contenidos gr´ aficamente atractivos se ha convertido en un factor de diferenciaci´ on en el mercado. La aparici´ on de la plataforma de c´ odigo abierto Android ha supuesto una revoluci´ on en el mercado de los dispositivos m´ oviles. Su estructura basada en el empleo de la m´ aquina virtual Dalvik no hab´ ıa permitido emplear librer´ ıas de representaci´ on gr´ afica que no estuvieran basadas en Java. Con la introducci´ on de la programaci´ on nativa, este trabajo aborda la compatibilizaci´ on de OpenSceneGraph, el est´ andar OpenGL para grafos de escena. Durante este trabajo se presentan los cambios realizados sobre la librer´ ıa, las pruebas de funcionamiento realizadas y la utilizaci´ on del grafo de escena para optimizar la representaci´ on de escenas que superan los l´ ımites de memoria de los dispositivos f´ ısicos. Seguidamente se analizar´ an los resultados y se presentar´ an las conclusiones de este trabajo. 5
6
´ Indice general 1. Introducci´on 17 2. Antecedentes 21 2.1. OpenGL ..................................... 21 2.1.1. OpenGLES1.X............................. 24 2.1.2. OpenGLES2.0 ............................. 25 2.1.3. WebGL.................................. 26 2.2. Android ..................................... 27 2.2.1. Fundamentos de la plataforma . . . . . . . . . . . . . . . . . . . . 29 2.3. OpenSceneGraph................................ 32 2.4. VirtualPlanetBuilder .............................. 34 2.5. CMake ...................................... 34 2.6. Compilaci´ oncruzada.............................. 35 2.7. Renderizado de geometr´ ıa tridimensional en dispositivos embebidos . . 35 2.7.1. jMonkey................................. 37 2.7.2. jPCT-AE ................................. 37 2.7.3. Simple DirectMedia Layer . . . . . . . . . . . . . . . . . . . . . . . 37 2.8. Renderizaci´ ondeterrenos........................... 38 7
8´ INDICE GENERAL 3. An´alisis del problema 41 3.1. La problem´ atica de la representaci´ on interactiva en Android . . . . . . . 41 3.2. La creaci´ on de una aplicaci´ on basada en OSG sobre Android . . . . . . . 43 3.3. Gesti´ on de la memoria en Android . . . . . . . . . . . . . . . . . . . . . . 50 3.4. Garantizar la compatibilidad entre dispositivos . . . . . . . . . . . . . . . 51 3.5. La creaci´ on de un paquete Third-Party . . . . . . . . . . . . . . . . . . . . 53 3.6. Filtrado de eventos de entrada t´ actil ..................... 54 3.7. Integraci´ on del sistema de compilado NDK con la librer´ ıa OSG . . . . . 55 3.8. Planificaci´ ondelproyecto ........................... 55 4. Desarrollo 63 4.1. Adaptaci´ on de la librer´ ıa OpenSceneGraph . . . . . . . . . . . . . . . . . 63 4.2. Integraci´ on de un sistema de compilado Android NDK en la librer´ ıa OpenSceneGraph................................ 64 4.2.1. Problemas presentados durante la compilaci´ on........... 68 4.2.2. Integraci´ on de los scripts NDK en los scripts CMake . . . . . . . 72 4.3. Creaci´ on de las aplicaciones de Test . . . . . . . . . . . . . . . . . . . . . 77 4.3.1. Desarrollo de las aplicaciones . . . . . . . . . . . . . . . . . . . . . 78 4.3.2. Generaci´ on de un paquete de librer´ ıas third party para OSG . . . 86 4.3.3. Pruebas funcionales . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.3.4. Prototipos de representaci´ on tridimensional de terreno . . . . . . 88 4.3.5. Sistema de control de memoria . . . . . . . . . . . . . . . . . . . . 90 4.3.6. Problemas presentados durante el desarrollo de la segunda fase . 93 4.4. Creaci´ on de la documentaci´ on y programas de ejemplo . . . . . . . . . . 95 5. Resultados 97 5.1. Caracter´ ısticas de los dispositivos de pruebas . . . . . . . . . . . . . . . . 97 5.2. Resultados modelos de baja resoluci´ on.................... 98
´ INDICE GENERAL 9 5.3. Resultados modelos de alta resoluci´ on....................101 5.4. Resultados de la representaci´ on de terrenos precalculada . . . . . . . . . 103 5.5. Resultados de la representaci´ on de terrenos generados en tiempo de dibujado .....................................106 6. Conclusiones y trabajo futuro 111 7. Agradecimientos 115
16 ´ INDICE DE TABLAS 5.7. Estad´ ısticas de los ejemplos de representaci´ on de terrenos. . . . . . . . . 105
1 Introducci´ on Los dispositivos m´ oviles est´ an entrando en una ´ epoca de grandes cambios, los avances en la capacidad de los procesadores embebidos y la aceptaci´ on social de los diferentes dispositivos que se abarca en esta familia (Smartphones, tabletas, gadgets, etc) los han convertido en un mercado objetivo para muchas compa˜ n´ ıas y desarrolladores. La representaci´ on gr´ afica sobre estos dispositivos se ha visto condicionada por las diversas limitaciones de estas plataformas, entre las cuales hay que se˜ nalar la falta de capacidad de procesamiento, la falta de memoria y su gran latencia, la necesidad de un consumo bajo de energ´ ıa, etc. Los diferentes estudios de representaci´ on tridimensional sobre estos dispositivos han buscado maneras de superar estos l´ ımites mediante el empleo de arquitecturas externas, simplificaci´ on de la representaci´ on, renderizado externo y otros. Comercialmente, las optimizaciones m´ as empleadas han sido las que se pod´ ıan implementar en el propio dispositivo. El uso de impostores, la simplificaci´ on de elementos o la representaci´ on de interfaces bidimensionales han sido la t´ onica general de las aplicaciones comerciales. Con el aumento de la potencia de c´ alculo en los dispositivos actuales, el sector de los dispositivos embebidos se ha convertido en un mercado competitivo que, mediante las evoluciones tecnol´ ogicas, est´ a intentando cubrir todas las necesidades posibles 17
18 Introducci´ on del consumidor. En un mundo donde el dise˜ no y lo visual marcan las modas y las tendencias, la capacidad para crear representaciones tridimensionales e incluso programas que ofrezcan contenido “3D” son caracter´ ısticas que el usuario demanda a los desarrolladores. A su vez, el usuario busca encontrar una respuesta a las acciones que realiza sobre su dispositivo. Busca establecer una conversaci´ on, una comunicaci´ on fluida donde las dos partes interaccionen. Si el usuario no percibe que la aplicaci´ on responde con suficiente rapidez, tendr´ a la sensaci´ on de que esta no funciona correctamente. Con las necesidades de las aplicaciones actuales en los dispositivos m´ oviles, el renderizado interactivo de escenas tridimensionales es un problema muy importante a abordar. Sin embargo, no tiene soluci´ on definitiva. Cuando se aumenta el nivel de detalle o el n´ umero de elementos en cualquier escena, se termina superando los l´ ımites de memoria y de procesamiento de cualquier dispositivo. As´ ı pues, el problema no consiste tanto en cambiar la metodolog´ ıa para que funcione, sino en escalar las escenas a las caracter´ ısticas del dispositivo objetivo. Escalar las necesidades de una escena tridimensional es un problema muy complicado de abordar cuando el programador se mueve en t´ erminos de instrucciones gr´ aficas de bajo nivel. Para abordar de una forma m´ as simple el problema existe la metodolog´ ıa de los grafos de escena. Un grafo de escena es una estructura basada en un grafos ac´ ıclico no dirigido que ordena los elementos gr´ aficos de una escena de forma jer´ arquica espacial donde cada nodo ´ unicamente posee un padre. Esta metodolog´ ıa permite al desarrollador abstraerse a un nivel superior donde puede aplicar optimizaciones para adecuar la representaci´ on de una escena a las caracter´ ısticas de cualquier dispositivo sin tener que lidiar con el c´ odigo de bajo nivel donde las relaciones entre elementos no son tan sencillas de percibir. El objetivo de este trabajo es portabilizar la librer´ ıa OpenSceneGraph (OSG), el estandar OpenGL para grafos de escena, al sistema operativo Android y, con ello, estudiar la problem´ atica para realizar representaciones interactivas de escenas tridimensionales en dispositivos actuales. La librer´ ıa OSG es una librer´ ıa de c´ odigo libre y multiplataforma escrita en C++ que proporciona las caracter´ ısticas de un grafo de escena. Se ha empleado en multitud de programas de todo tipo, desde aplicaciones cient´ ıficas y de simulaci´ on hasta juegos. Actualmente es uno de los referentes libres m´ as empleados por su versatilidad, su bajo grado de especializaci´ on y su capacidad para realizar aplicaciones multiplataforma. Actualmente permite realizar aplicaciones sobre Windows, Linux, Unix y los sistemas
Introducci´ on 19 Apple de sobremesa y embebidos. Si bien la librer´ ıa OSG ya ha sido portada a dispositivos embebidos (iOS), hasta ahora no hab´ ıa sido posible realizar una portabilizaci´ on con ´ exito a Android debido a la estructura del sistema operativo. Android est´ a orientado hacia el uso de la m´ aquina virtual Java/Dalvik. Hubiera sido necesario reimplementar todo el c´ odigo fuente de la librer´ ıa en el lenguaje Java para poder emplear la librer´ ıa con Android. Paulatinamente, Android ha ido incorporando el uso de componentes y aplicaciones nativas que no empleen la m´ aquina virtual a semejanza de los dispositivos embebidos de Apple. A´ un con la aceptaci´ on de la programaci´ on nativa y a pesar de que Android emplea el Kernel de Linux, las diferencias existentes en las librer´ ıas que emplea, la estructura de los programas y la dificultad que conlleva programar y depurar programas de forma remota han convertido en un reto este tipo de portabilizaciones. Pocas librer´ ıas han conseguido llevar a cabo una portabilizaci´ on completa y funcional a Android. En este trabajo se abordar´ a el problema mediante el estudio de todas las posibilidades actuales de la plataforma Android y de las diferentes dependencias de la librer´ ıa OSG. Con ello se buscar´ a realizar los cambios m´ ınimos e imprescindibles para incorporar la nueva plataforma a la librer´ ıa. Esta memoria se compone, principalmente, de cuatro partes. En primer lugar, se expone una visi´ on sobre el estado del arte de los diferentes elementos que se van a emplear y referenciar a lo largo del trabajo, as´ ı como las diferentes t´ ecnicas gr´ aficas empleadas en la creaci´ on de las aplicaciones de prueba. La segunda parte comprende el an´ alisis de la problem´ atica que supone compatibilizar el grafo de escena OSG con la plataforma Android y las soluciones planteadas durante la fase de an´ alisis de este trabajo. Seguidamente, se presenta el desarrollo realizado en este trabajo resaltando los elementos m´ as importantes y cr´ ıticos durante el proceso de compatibilizaci´ on y la creaci´ on de los test de funcionamiento y optimizaci´ on de escenas. Posteriormente se presentar´ an los resultados obtenidos durante el desarrollo del proyecto para finalizar con las conclusiones y los posibles desarrollos futuros basados en este proyecto.
20 Introducci´ on
2 Antecedentes Esta secci´ on cubre el estado actual del arte sobre el que se apoya el trabajo. A lo largo de esta secci´ on se hablar´ a de la evoluci´ on de los diferentes elementos empleados en el trabajo para dar una imagen de su uso en el trabajo. Seguidamente hablaremos de la evoluci´ on hist´ orica del renderizado en dispositivos embebidos para finalizar con un comentario de t´ ecnicas de representaci´ on de terreno tridimensional. 2.1. OpenGL OpenGL [Khr92] es una API multiplataforma dise˜ nada por la Kronos Architecture Research Board. Actualmente, se encargan de su mantenimiento un consorcio de empresas de CAD y, de forma destacada, las empresas Nvidia y Ati. Es un lenguaje de representaci´ on gr´ afica tridimensional creado con el objetivo de obtener un est´ andar multiplataforma libre. Est´ a dise˜ nada siguiendo una arquitectura cliente-servidor. Esta visi´ on de comunicaci´ on es la base que inspira toda la especificaci´ on. Una de sus caracter´ ısticas m´ as c´ elebres fue la inclusi´ on de un sistema de extensiones, que permit´ ıa la introducci´ on de nuevas caracter´ ısticas y t´ ecnicas sin necesidad de modificar la API. OpenGL ha sido durante muchos a˜ nos la API “puntera” que se empleaba para todo tipo de aplicaci´ on gr´ afica. Su comunicaci´ on con las tarjetas a bajo nivel, le permit´ ıa acceder con menor latencia a las tarjetas sin pasar por el sistema operativo. Recorde21
22 Antecedentes mos que DirectX [Mic92] (Competencia directa en el mercado de Windows) obligaba a pasar las llamadas a trav´ es del kernel del sistema operativo con las consecuentes penalizaciones que eso conlleva. Desde su nacimiento, OpenGl no fue concebido para un lenguaje espec´ ıfico, sin embargo, la implementaci´ on oficial est´ a pensada para un lenguaje de tipo imperativo. Existen versiones para lenguajes no imperativos que se limitan a enmascarar la imperatividad propia de la representaci´ on de elementos gr´ aficos de OpenGL. La implementaci´ on de referencia sobre la que est´ an basada la mayor parte de documentaci´ on es para ANSI C99. Existen una serie de bindings para diferentes lenguajes, entre los cuales se encuentra Haskell. No existe una versi´ on especifica para C++ que sea orientada a objetos, la ´ unica versi´ on que podr´ ıa considerarse as´ ı es una implementaci´ on creada para Java. El proceso por el cual se genera una representaci´ on a partir de una geometr´ ıa, se suele llamar “tuber´ ıa”. Este nombre se debe al dise˜ no en forma de cadena de producci´ on que tiene la API. Esta cadena de producci´ on recibe en un extremo una serie de datos geom´ etricos que van avanzando a trav´ es de una serie de fases en las cuales, el programador no puede intervenir f´ ısicamente. El programador, ´ unicamente puede ajustar una serie de par´ ametros predefinidos, los cuales controlan el funcionamiento de los diferentes procesos de la tuber´ ıa. Este dise˜ no proviene de las estaciones de renderizado que se empleaban en los principios de la representaci´ on gr´ afica en computadores. Ese car´ acter de fijo e inamovible es el que bautiza a este proceso como “Tuber´ ıa de procesado fija”. La figura: 2.1 muestra un resumen de los procesos que se realizaba sobre los datos desde su introducci´ on hasta su representaci´ on. Figura 2.1: Diagrama de los procesos de la tuber´ ıa de procesado fija en OpenGL. Durante los a˜ nos noventa, OpenGL adquiri´ o una posici´ on de ventaja competiti-
2.1 OpenGL 23 va en detrimento de alternativas como DirectX. Esta posici´ on se debe, sobre todo, a la constante evoluci´ on que permit´ ıa el mecanismo de extensiones en OpenGL, este permit´ ıa ofrecer a los desarrolladores las caracter´ ısticas que todav´ ıa no hab´ ıan sido integradas de forma fija en el lenguaje, de esta manera OpenGL se convierte en el sin´ onimo de API puntera. En el ´ ultimo lustro, OpenGL entr´ o en un periodo de letargo sin presentar novedades. La Kronos ARB se concentr´ o en la creaci´ on de una nueva iteraci´ on de la API que mejorase la actual; una versi´ on que eliminase los comandos y funciones replicadas. Finalmente, la API se concret´ o en dos nuevas versiones de OpenGL (3.0 y 4.0), ambas siguen sin romper con la parte fija de la librer´ ıa, pero sientan las bases para su futura eliminaci´ on creando dos perfiles de uso: N´ ucleo y Compatibilidad. El perfil n´ ucleo, se queda con un subconjunto de comandos y estados prescindiendo de los m´ etodos m´ as ineficientes. Los m´ etodos eliminados en este perfil, se pueden seguir empleando pero aparecen marcados como deprecados, lo cual obliga a emplear el perfil de compatibilidad. Los m´ etodos marcados como deprecados est´ an considerados como m´ etodos que se pueden eliminar en un futuro y como tales no deben usarse si se quiere garantizar el uso futuro del c´ odigo de un programa o librer´ ıa. Todo programa basado en el perfil n´ ucleo debe cumplir obligatoriamente con el uso exclusivo de la tuber´ ıa programable2.1, habiendo desaparecido el uso intermedio que permit´ ıa la versi´ on 2.1 de OpenGL. La tuber´ ıa programable es una nueva manera de procesar la informaci´ on geom´ etrica del usuario. La idea, detr´ as del uso de esta tuber´ ıa, es que el programador pueda controlar el procesado de sus datos en los procesos. Para ello, la API expone aquellos procesos no triviales para que el programador pueda programarlos a su voluntad, para ello el programador carga una serie de programas que se ejecutan desde la tarjeta gr´ afica, los shaders. Actualmente, existen tres tipos de shaders: los que afectan al procesado por cada v´ ertice, los que afectan al procesado a nivel de primitiva geom´ etrica y los que afectan a nivel de p´ ıxel visible. El uso de los programas shaders ha supuesto un aumento en las capacidades de decisi´ on para los programadores gr´ aficos permitiendo la implementaci´ on de nuevas t´ ecnicas y efectos que no se pod´ ıan representar en las limitaciones de la tuber´ ıa fija. El perfil de compatibilidad, mantiene todos los comandos y estados de las versiones anteriores. De la misma manera integra la tuber´ ıa de procesado fija y permite el uso de todas las extensiones y elementos que se pod´ ıan emplear en la versi´ on 2.4. Esto significa que se pueden emplear Shaders utilizando una mezcla de tuber´ ıa fija y tuber´ ıa programable.
24 Antecedentes Figura 2.2: Diagrama de los procesos de la tuber´ ıa de procesado programable. 2.1.1. OpenGL ES 1.X OpenGl Embebed Systems es la respuesta de la Kronos ARB a las necesidades de algunos miembros del consorcio como PowerVR [Ima92] para estandarizar una API gr´ afica para dispositivos embebidos o de recursos limitados. El objetivo a la hora de crear esta API fue crear un subconjunto interoperable con la API de sobremesa, persiguiendo con ello la simplificaci´ on de la API. La evoluci´ on continua de OpenGL hab´ ıa supuesto la inclusi´ on de muchos m´ etodos que replicaban funciones con diferentes rendimientos por compatibilidad. Por lo tanto en OpenGL ES encontramos con una versi´ on simplificada que elimina las versiones m´ as primitivas y lentas de env´ ıo de geometr´ ıa a la tarjeta gr´ afica. Se prescinde de las instrucciones por v´ ertices y de las listas de comandos conservando ´ unicamente los Vertex Array, la alternativa con el mejor rendimiento. Se prescinde tambi´ en de las instrucciones que permiten consultar las matrices, debido a su sobrecoste, y, en general, desaparecen los comandos que tienden a ser m´ as lentos o que
2.1 OpenGL 25 realizan funciones de apoyo cuyo coste computacional no compense su uso. En otras palabras, lo que encontramos es con una API compatible con su hermana de sobremesa siguiendo las referencias marcadas por OpenGL 1.4 y que emplea la tuber´ ıa fija para realizar el tratamiento de los datos geom´ etricos. Al igual que las versiones de sobremesa, las versiones embebidas tienen un sistema de extensiones que permiten incluir funcionalidades, que no estuvieran en un origen como las “Ambient Box”, sin necesidad de cambiar la API. En la versi´ on 1.0 de OpenGL ES existe una restricci´ on sobre las texturas. Esta obliga a que tengan que ser cuadradas y potencias de dos. Sin embargo, esta restricci´ on fue relajada en la versi´ on 1.1. En dicha versi´ on existen extensiones que permiten usar texturas que no tengan un tama˜ no de potencia de dos, si bien, por motivos de rendimiento se recomienda el uso de texturas cuadradas y con un tama˜ no que sea potencia de dos. Finalmente hay que comentar una limitaci´ on que exist´ ıa en OpenGL ES 1.0. Aunque se pod´ ıa emplear aritm´ etica de coma flotante para los gr´ aficos, su uso ralentizaba mucho el renderizado de resultados. Para evitar esto, se recomendaba usar n´ umeros decimales expresados en coma fija. 2.1.2. OpenGL ES 2.0 La versi´ on embebida 2.0, est´ a basada en la especificaci´ on de la versi´ on 2.1 de OpenGL, sin embargo, en contra de la ES 1.X no busca ser totalmente compatible con una versi´ on exacta. La especificaci´ on de OpenGL ES 2.0 se cre´ o en el per´ ıodo de transici´ on entre las versiones 2.1 y 3.0. Se eliminaron muchos elementos y comandos que duplicaban funcionalidades y se introdujo la obligatoriedad del uso de la tuber´ ıa programable con los shaders de forma an´ aloga a la versi´ on 3.0. En comparaci´ on con la versi´ on 1.0, los mayores cambios fueron la introducci´ on de tuber´ ıa de procesado programable representada en: 2.1.2, la eliminaci´ on total del uso de la tuber´ ıa de procesado fija y la retirada de limitaciones en los tama˜ nos de las texturas; si bien las versiones de sobremesa siguen siendo compatibles en mayor o menor medida con la tuber´ ıa fija, en OpenGL ES 2.0 la tuber´ ıa desaparece completamente y no se puede compatibilizar con el driver de la 1.0 ya que son drivers independientes. La implementaci´ on de la tuber´ ıa de procesado programable tiene algunas diferencias con la presentada en 3.0. En la versi´ on de sobremesa existen los programas shader para procesar v´ ertices, geometr´ ıa y fragmentos. En esta versi´ on, de forma parecida a la extensi´ on que exist´ ıa en 2.1, ´ unicamente se permiten shaders para procesar v´ ertices y fragmentos.
32 Antecedentes entorno sin interferir con el resto de actividades, as´ ı es como Android cumple el requisito de competencia igualitaria entre las aplicaciones por los recursos, a la vez que este encapsulamiento garantiza una m´ ınima tolerancia a fallos evitando su propagaci´ on fuera de la actividad que lo provoc´ o. Si una actividad incurre en un error grave, este no afecta a las otras actividades. En un dispositivo cuyo prop´ osito principal es poder utilizarlo para recibir y enviar llamadas, no es agradable tener que reiniciar tu tel´ efono para poder hacer una llamada porque se ha quedado congelado. Lo explicado hasta este punto, abarca las ideas b´ asicas de funcionamiento que tiene Android desde sus primeras versiones. Sin embargo, debido al desarrollo y a las nuevas tendencias se han tenido que a˜ nadir otras ideas. El n´ umero de dispositivos y la variedad de configuraciones ha crecido de forma significativa durante los ´ ultimos tres a˜ nos. Actualmente existe soporte para cinco tipos de pantalla diferentes, m´ ultiples diferencias de densidad de p´ ıxeles seg´ un dispositivos y resoluciones diferentes. El problema de la compatibilidad de la aplicaci´ on ya no es debido a su funcionamiento, ahora el problema de la compatibilidad es por la gran variabilidad de configuraciones de pantalla, componentes hardware, etc. No todas las aplicaciones son capaces para estar preparadas para todas las variabilidades existentes. La respuesta de Android es la inclusi´ on de requisitos m´ ınimos en las aplicaciones. Una aplicaci´ on puede pedir unos requisitos m´ ınimos al dispositivo en el que es instalado. Para comenzar, un dispositivo que no sea compatible ser´ a incapaz de encontrar en el repositorio de aplicaciones una que tenga un requisito m´ ınimo que no cumpla, si aun as´ ı el usuario intenta instalarla manualmente, el instalador revisa las caracter´ ısticas m´ ınimas e impide al usuario su instalaci´ on. 2.3. OpenSceneGraph OSG [OSG] es una librer´ ıa de alto rendimiento para trabajar con gr´ aficos tridimensionales, est´ a publicada como c´ odigo libre y ha sido integrada en en aplicaciones libres y comerciales de todo tipo. Es capaz de manejar entornos tridimensionales complejos y representar gr´ aficos de ´ ultima generaci´ on sin ning´ un tipo de limitaci´ on. A diferencia de otras alternativas, OSG ´ unicamente ofrece las funciones de un grafo de escena donde se pueden incluir nodos propios para extender sus funcionalidades b´ asicas de representaci´ on. Debido a la no especializaci´ on de la librer´ ıa, puede ser empleada para la creaci´ on de todo tipo de aplicaciones cient´ ıficas o comerciales que necesiten representar informaci´ on gr´ afica. Ha sido empleada para crear aplicaciones de visualizaci´ on, realidad aumentada, simuladores de vuelo o juegos.
2.3 OpenSceneGraph 33 El n´ ucleo de OSG es el empleo de una metodolog´ ıa de grafos de escena, son grafos ac´ ıclicos que forman una representaci´ on jer´ arquica de la escena. Esta ordenaci´ on permite realizar optimizaciones espaciales y de representaci´ on para mejorar el rendimiento de la visualizaci´ on en escenas complejas. Esto se realiza mediante inspecciones del grafo que permiten visualizar, o no, ramas enteras dependiendo de nuestro criterio de visibilidad y, a partir de la selecci´ on generar un orden de visualizaci´ on que sea ´ optimo para la renderizaci´ on en la API. Esto permite al programador abstraerse del uso de los comandos de bajo nivel de las API gr´ aficas y concentrarse a nivel de objetos de escena sin preocuparse del c´ odigo necesario para generar la visualizaci´ on Una de las caracter´ ısticas de OSG es su arquitectura modular que permite a˜ nadir elementos y generar nuevos m´ odulos y plugins para ser empleados en el grafo de escena permitiendo al programador extender la librer´ ıa seg´ un sus necesidades. Si estudiamos su estructura, OSG est´ a formada por una serie de peque˜ nas librer´ ıas y plugins. Ambos extienden la funcionalidad, bien a˜ nadiendo efectos y patrones gr´ aficos que se pueden incluir directamente en el grafo de escena, o bien a˜ nadiendo la posibilidad de trabajar con tipos de archivos. Generalmente estos plugins requieren de librer´ ıas externas independientes de OSG que se enlazan din´ amicamente con el programa en ejecuci´ on. OSG adem´ as se ha dise˜ nado para cargar las librer´ ıas y plugins bajo demanda. Esto supone que un programa que emplee OSG, ´ unicamente cargar´ a las librer´ ıas b´ asicas y, dependiendo de las necesidades, el resto de librer´ ıas y plugins ser´ an enlazadas din´ amicamente cuando el usuario lo requiera. Esta caracter´ ıstica permite ahorrar memoria durante la ejecuci´ on de un programa al no tener que cargar los m´ odulos que no se utilicen. Esta metodolog´ ıa funciona bien en plataformas de sobremesa. Por el contrario en dispositivos embebidos o smartphones resulta, muchas veces, imposible de usar, por ello, OSG incluye la posibilidad de una compilaci´ on est´ atica de todas las librer´ ıas y plugins. Esta compilaci´ on requiere que el usuario registre una serie de macros realizan una serie de definiciones internas en la base de datos de OSG que permitan emplear los plugins y librer´ ıas sin necesidad de enlazarlos din´ amicamente. La librer´ ıa OSG ´ unicamente tiene una dependencia directa, la librer´ ıa OpenThreads(OT). Para simplificar la cantidad de c´ odigo dependiente de sistemas operativos, OSG encapsula todas las operaciones de hilos en la librer´ ıa OT. Esta librer´ ıa ha sido publicada como un proyecto independiente de OSG, aunque se encuentra incorporada en la estructura de la distribuci´ on de la librer´ ıa. De forma opcional, OSG depende en una larga cantidad de librer´ ıas para el uso de diferentes formatos de archivos.
34 Antecedentes Por otro lado, OSG tiene implementadas diversas estrategias para la reducci´ on de complejidad de una escena tridimensional, carga de elementos bajo demanda y permite realizar inspecciones completas de los grafos de escenas. Con estas posibilidades, se pueden crear una t´ ecnicas de optimizaci´ on m´ as complejas como el uso de quadtrees, octrees u otros modos de ordenaci´ on del espacio geom´ etrico tridimensional. 2.4. VirtualPlanetBuilder VPB es una librer´ ıa basada en OSG. El prop´ osito de la librer´ ıa es la creaci´ on de bases de datos de geometr´ ıa tridimensional de terrenos. A diferencia de otras bases de datos geogr´ aficas, las generadas por el programa est´ an formadas por los diferentes nodos que conforman la representaci´ on del grafo de escena. Si desgranamos los archivos generados, vemos perfectamente la ordenaci´ on jer´ arquica que se carga en la escena de nodos y sus tipos. Al estar basada en OSG, permite emplear todos los tipos de archivo de modelos y texturas que soporta OSG para generar nuestras bases de datos geogr´ aficas. VPB permite generar bases de terrenos planos o esf´ ericos. Opcionalmente, si se poseen datos geom´ etricos, se pueden emplear para que se forme el terreno con mallas geom´ etricas que representen las alturas. Entre las opciones m´ as destacadas, hay que se˜ nalar que tambi´ en permite emplear la librer´ ıa Nvidia Texture Tools (NvTT) [Nvi] para emplear texturas con compresi´ on, el uso de texturas comprimidas est´ a muy extendido en la actualidad. Para ello se usan una serie de formatos de compresi´ on fija cuya descompresi´ on se ejecuta a muy bajo coste computacional en las tarjetas. Algunos de los formatos de compresi´ on que admite son: DXT 1/3/5 [Cas07]. 2.5. CMake CMake es una aplicaci´ on multiplataforma dise˜ nada para ofrecer un sistema de compilado independiente de la plataforma. Mantener una aplicaci´ on multiplataforma es una labor compleja, ya que suelen existir diferencias y parches que dependen de la plataforma objetivo, adem´ as, es necesario tener los scripts que sirvan para compilar la librer´ ıa en cada uno de los sistemas para los que ha sido desarrollada. El objetivo de CMake es evitar el mantenimiento de un gran n´ umero de scripts por plataforma unific´ andolos en un ´ unico tipo de fichero. El programador ´ unicamente tiene que escribir una serie de ficheros con el lenguaje de scripting de CMake, en ellos define los paque-
2.6 Compilaci´ on cruzada 35 tes, archivos a compilar, opciones, etc. Finalmente el usuario que desea compilar el proyecto ejecuta CMake, a partir de dichos scripts, CMake generar´ a los ficheros apropiados para ejecutar la compilaci´ on de acuerdo a la plataforma objetivo que emplea el usuario. Al ser un lenguaje de scripting, CMake puede ser empleado para extenderse a si mismo. Es posible emplearlo para generar scripts de compilaci´ on diferentes a los que ya tiene programados internamente. 2.6. Compilaci´ on cruzada La compilaci´ on cruzada, es un t´ ermino que emplearemos varias veces en el trabajo y que conviene clarificar. La compilaci´ on cruzada (Cross compiling en ingl´ es), sirve para denominar aquellas compilaciones que se generan en una arquitectura diferente de la arquitectura en la cual se va a ejecutar el c´ odigo compilado. Es la forma normal de compilaci´ on para dispositivos embebidos, consolas, o en general todo sistema operativo donde no se tiene la posibilidad de emplear un compilador. En la actualidad existen varios ejemplos de compiladores libre y comerciales que permiten esta t´ ecnica: GCC, GUB o Intel C++ Compiler entre otros. 2.7. Renderizado de geometr´ıa tridimensional en dispositivos embebidos La representaci´ on gr´ afica tridimensional en dispositivos embebidos es un problema que ha tenido un largo recorrido. La inexistencia de unos criterios comunes en las diferentes plataformas propici´ o el uso de API gr´ aficas propietarias sin compatibilidad. Conforme las necesidades gr´ aficas aumentaron se fue generando la necesidad de un est´ andar gr´ afico m´ ınimo. Siguiendo a su hom´ ologo de sobremesa, la Kronos ARB cre´ o un est´ andar OpenGL para dispositivos embebidos [Khr04], aunque en la actualidad sea un est´ andar para la mayor parte de dispositivos, a lo largo de la evoluci´ on de estos dispositivos han aparecido otros est´ andares que han entrado en competencia. Por citar algunos, habr´ ıa que hablar de PocketGL [Ler04] o la reciente implementaci´ on de DirectX en el sistema m´ ovil de Windows. La estandarizaci´ on de la API no supuso el fin de las restricciones de estos dispositivos, recordemos que estas surgen debido al hardware. La potencia de c´ alculo y la
36 Antecedentes capacidad de memoria de estos dispositivos no permit´ ıan representar escenas gr´ aficamente complejas. Para salvar estas limitaciones aparecieron una serie de t´ ecnicas que permit´ ıan salvar las restricciones: renderizado basado en im´ agenes, en puntos, en geometr´ ıa y simplificaci´ on en memoria externa basada en el punto de visi´ on. El renderizado basado en im´ agenes, consist´ ıa en emplear el uso de im´ agenes para reemplazar elementos geom´ etricos. [CG02] propone el uso de una arquitectura cliente-servidor que renderizaba la escena en el servidor y env´ ıa la imagen al cliente. Por su parte, el renderizado basado en puntos consiste en representar la geometr´ ıa dibujando una serie de puntos en la superficie del modelo [DD04] empleaba un mecanismo de representaci´ on de puntos jer´ arquico. El renderizado basado en la geometr´ ıa es el mismo que se emplea en los sistemas de sobremesa, para adaptarlo al uso en dispositivos embebidos se emplean m´ etodos como el que se plantea en [SZL02] que propone el uso de una arquitectura para buscar, recuperar y renderizar modelos complejos. La t´ ecnica de simplificaci´ on en memoria externa basada en el punto de visi´ on es un trabajo previo que se empleo en los trabajos [LGCV05] [Cam06]. Esta t´ ecnica emplea un modelo cliente-servidor para realizar el renderizado. La clave para salvar las limitaciones consist´ ıa en el empleo de un grafo de escena (OSG) para simplificar, mediante una serie de optimizaciones, la geometr´ ıa dependiendo del punto actual de visi´ on. El resultado era que el dispositivo cliente ´ unicamente recib´ ıa la parte de la geometr´ ıa que era necesaria, de esta manera se reduc´ ıa el coste computacional de la representaci´ on y el espacio necesario para contenerlo en memoria. Los trabajos previos han demostrado la utilidad del empleo de jerarqu´ ıas y estructuras como los grafos de escena para la optimizaci´ on de escenas como en el trabajo [ESC00]. El n´ ucleo que mover´ a las escenas en este trabajo es OSG, que como grafo de escena, realiza optimizaciones gr´ aficas como: culling, fustrum culling, LOD, y otras. Adem´ as permite incorporar t´ ecnicas de inspecci´ on del grafo de escena para operaciones complejas con la metodolog´ ıa de los “visitor”. Su gran adaptabilidad permite adecuarlo con m´ ınimos cambios para optimizar escenas complejas. Desde la versi´ on 2.9 soporta el uso de OpenGL ES 1.X y 2.0. A diferencia de otros grafos de escena, OSG tiene una arquitectura modular basada en plugins, esto permite incluir ´ unicamente los componentes que necesitamos, rebajando su ocupaci´ on en memoria, lo que representa un punto muy importante para el desarrollo de aplicaciones en estos dispositivos. Los chipsets gr´ aficos para dispositivos embebidos han evolucionado de forma paralela a sus hom´ ologos de sobremesa. En la actualidad, la API OpenGL ES 1.0 est´ a siendo sustituida por su evoluci´ on natural, OpenGL ES 2.0 [Khr04]. La novedad funda-
2.7 Renderizado de geometr´ ıa tridimensional en dispositivos embebidos 37 mental de esta nueva versi´ on es el abandono del procesado de geometr´ ıa con la tuber´ ıa fija. Dada la potencia actual, se ha decidido seguir el camino de los chipsets de sobremesa incluyendo el procesado de geometr´ ıa programable. Esto permite programar tal y como deseemos que se representen nuestros objetos geom´ etricos, de esta manera se han generado una gran cantidad de t´ ecnicas aprovechando esta posibilidad. Para una referencia m´ as extensa de las posibilidades que permite la nueva API, el articulo [Cat10] resume el funcionamiento y ofrece una serie de ejemplos de shaders y t´ ecnicas. Tambi´ en es recomendable la lectura del art´ ıculo [GBO09] que cubre las posibles optimizaciones que se pueden realizar con las API 1.0 y 2.0. Un punto importante de este art´ ıculo son las conclusiones sobre pr´ acticas que se pueden convertir en cuellos de botella dependiendo de su uso. Actualmente existe una serie de librer´ ıas que se est´ an empleando para gestionar el renderizado en dispositivos embebidos. Algunas de estas librer´ ıas, como OSG ya hab´ ıan sido utilizadas en los dispositivos iPhone; sin embargo, muchas de ellas todav´ ıa no tienen compatibilidad con Android debido a las dificultades para la programaci´ on nativa como ocurre con la librer´ ıa Ogre que todav´ ıa no es compatible. Algunas de las librer´ ıas que se emplean actualmente en Android son: jMonkey, jPCT-AE o Simple DirectMedia Layer(SDL). 2.7.1. jMonkey Es una librer´ ıa especializada para la creaci´ on de videojuegos cuyo lenguaje primario es Java. Actualmente se usa en algunos proyectos libres. La librer´ ıa implementa un grafo de escena para la renderizaci´ on de elementos, los cuales son extensibles debido a su dise˜ no modular. 2.7.2. jPCT-AE Es una librer´ ıa especializada para la creaci´ on de videojuegos cuyo lenguaje primario es Java, permite la implementaci´ on de programas con f´ ısicas y capacidades en red. Emplea optimizaciones jer´ arquicas basadas en en la geometr´ ıa de la escena. 2.7.3. Simple DirectMedia Layer SDL es una librer´ ıa libre con un largo desarrollo en los computadores de sobremesa. Su lenguaje primario es C aunque existen una serie de enlaces para usarse con
38 Antecedentes otros. Est´ a especializada en ofrecer acceso a nivel bajo del hardware de audio, v´ ıdeo y controles. Ninguna de las alternativas actuales ofrece la libertad de uso y especializaci´ on propia de la librer´ ıa OSG, adem´ as, el renderizado, en la mayor parte de ellas, se realiza desde el nivel de la m´ aquina virtual mediante Java sin acceso nativo. En este trabajo, se ha decidido abordar la compatibilizaci´ on de la librer´ ıa OSG para poder tener una librer´ ıa que no est´ e especializada para hacer representaciones gr´ aficas de un ´ unico tipo de programa y que realice el renderizado desde un nivel nativo. De esta manera, este trabajo pretende prescindir de cualquier tipo de arquitectura de refuerzo externa o simplificaci´ on no geom´ etrica. Se entiende que la evoluci´ on actual de los dispositivos tras el recorrido presentado en esta secci´ on, permitir´ a emplear un grafo de escena desde el propio dispositivo y ser capaz de optimizar las escenas para renderizar, con ´ el, terrenos tridimensionales. 2.8. Renderizaci´ on de terrenos La renderizaci´ on de terrenos tridimensionales, es la uni´ on de varias capas de informaci´ on expresada en una geometr´ ıa. Para generar la geometr´ ıa de un terreno se necesita la informaci´ on visual del terreno, la ortofoto, y, al menos, una capa de informaci´ on de puntos geod´ esicos de altura. A partir de estos datos se puede generar una representaci´ on visual en tres dimensiones. Este proceso puede ser realizado de tres formas distintas: Durante la creaci´ on de la base de datos, durante la carga de los datos y en el dibujado. La conversi´ on geom´ etrica de los datos bidimensionales a un espacio tridimensional es un proceso id´ entico en los tres casos, las ´ unicas diferencias entre ellos radican en el n´ umero de veces que se realizan, cuando y qu´ e herramientas est´ an al alcance para realizar el proceso. Sin entrar de forma detallada, se genera una grat´ ıcula o malla cuyas alturas son alteradas para ajustarse a los diferentes par´ ametros de altura. La ortofoto se emplea para dar el color a los pol´ ıgonos de dicha malla. Es el mismo proceso que se realiza en las t´ ecnicas de mapas de alturas [AMHH08]. Cuando se genera la geometr´ ıa en una base de datos, el resultado supone que la base de datos incremente su tama˜ no. Para evitar esto, se suelen emplear algoritmos de compresi´ on de datos sobre la informaci´ on. Esta soluci´ on es la que est´ a implementada sobre el programa Google Earth. Es una soluci´ on que obtiene los mejores costes computacionales en tiempo de dibujado ya que no se ha de realizar ning´ un proceso,
2.8 Renderizaci´ on de terrenos 39 con la desventaja de aumentar el peso de los datos a transmitir e inflexibilizar la representaci´ on. Debido a su bajo coste, esta soluci´ on se emplea durante este proyecto para realizar dos de los programas de prueba de representaci´ on de terrenos. Si la geometr´ ıa se genera durante la carga de datos, los datos que se transmiten al programa no aumentan de tama˜ no al ser los mismos datos originales sin incluir geometr´ ıa. La desventaja de este m´ etodo es que requiere de un procesado con un coste temporal durante la carga, esto generar´ a una latencia que se ha de suplir mediante el procesado en un hilo no bloqueante y cach´ es para mejorar la experiencia. La mayor ventaja de este m´ etodo es que la imagen representable no es ´ unica y puede ser cambiada en tiempo de ejecuci´ on cambiando los datos de entrada. Esta es la soluci´ on que est´ a presente en programas como GvSig. Finalmente, realizar el proceso durante el tiempo de dibujado, aporta la posibilidad de evitar la generaci´ on de geometr´ ıa que no es visible adem´ as de evitar el tiempo de preproceso. En este caso el proceso de conversi´ on se realiza en la propia tarjeta gr´ afica en cada pase de dibujado. La ventaja de este m´ etodo es que se realiza la conversi´ on de las zonas visibles y dicha conversi´ on puede ser realizada con el nivel de detalle que se ajuste mejor al rendimiento y al punto de visi´ on actual. En este art´ ıculo, se muestra el uso de esta forma de representar terreno para representar terrenos con mallas de detalle variable y su impacto en el rendimiento. Para la creaci´ on del programa de pruebas de terrenos tridimensionales creados en tiempo de dibujado, este trabajo se basa en la t´ ecnica de desplazamiento de v´ ertices. El art´ ıculo [USK06] sirve de resumen del estado actual del arte de dicha t´ ecnica. Otro trabajo importante a mencionar es [Kry05] con su implementaci´ on de la t´ ecnica para el renderizado de agua. A diferencia del trabajo [Don05] solo realizaremos la t´ ecnica a nivel de v´ ertices en vez de realizarla por p´ ıxel. Debido a que la t´ ecnica realiza el c´ alculo de la geometr´ ıa en tiempo de renderizado, es necesario implementar el c´ alculo de normales, o su lectura si ya est´ an pregeneradas. Para el c´ alculo de las normales en tarjeta, se ha empleado el trabajo [Mik10], debido a las limitaciones actuales por el coste de los c´ alculos en coma flotante, empleamos una simplificaci´ on de la t´ ecnica de c´ alculo de Bump Mapping para el c´ alculo de las normales. En la plataforma Android, ya se han desarrollado una serie de trabajos sobre la representaci´ on de terreno. En [SP09] se compara la eficiencia de emplear un renderizador local en contra de uno remoto, mientras que en [HW09] se plantea un posible dise˜ no para la representaci´ on de modelos planetarios.
40 Antecedentes
3 An´ alisis del problema A continuaci´ on se realizar´ a un an´ alisis de la problem´ atica de visualizar interactivamente escenas tridimensionales en los dispositivos que emplean Android como sistema operativo. Se describen los problemas que supone migrar a la plataforma una librer´ ıa, OpenSceneGraph(OSG), y las soluciones que se han planificado emplear en este proyecto. Finalmente se presenta la planificaci´ on del trabajo con un diagrama de Gantt se˜ nalando las tareas que se van a realizar y su planificaci´ on estimada. 3.1. La problem´ atica de la representaci´ on interactiva en Android La visualizaci´ on interactiva de escenas es un problema sin soluci´ on ´ optima sea, o no, un dispositivo embebido. Una visualizaci´ on interactiva obliga a responder al usuario en un tiempo suficientemente corto como para que no note que el mundo deja de responder a sus ´ ordenes. Esto limita inicialmente la tasa de representaci´ on que se debe alcanzar como m´ ınimo a diez frames por segundo. Aunque esta tasa parece lo suficientemente peque˜ na como para poder ajustarse a ella en cualquier situaci´ on, siempre existe un punto en el que una escena ser´ a incapaz de visualizarse en ese l´ ımite. En cualquier escena, si su detalle, n´ umero de elementos o requisito de memoria es amplificado terminar´ a por ser imposible su representaci´ on con una tasa interactiva. 41
48 An´ alisis del problema Versi´ on ABI. Nivel API 3 3 4 4 5 5 6 7 8 8 9 9 10 11 12 13 Tabla 3.1: Correspondencia entre las versiones API y las versiones ABI. son, en mayor medida, juegos y aplicaciones que emplean sus propias IGU, esto es debido a que, aunque podamos implementar actividades nativas, si necesitamos acceder a algunas de las caracter´ ısticas del framework deberemos pasar a trav´ es de un puente JNI, si bien, en futuras versiones, es posible que se expongan parte de esas funcionalidades para su uso desde un programa nativo. La lista de APIs que se pueden emplear desde la capa nativa de Android se encuentran en la siguiente tabla junto al n´ umero de API m´ ınima necesaria. La librer´ ıa OSG se ha de compilar, obligatoriamente, para ejecutarse en el nivel nativo y se ha de llamar siguiendo las dos posibilidades que se ha comentado en este punto. La versi´ on m´ ınima requerida de la API es la versi´ on cinco, ya que es la primera que incluye la compatibilidad con las dos versiones de la API OpenGL ES. Sin embargo, es recomendable fijar, como versi´ on objetivo, la versi´ on 2.1 o 2.2 ya que son versiones que incluyen muchos cambios en la API para la gesti´ on de eventos, el uso de teclado virtual, etc. Crear una aplicaci´ on para una u otra versi´ on supone optar a distribuirla a un 96.7 % de los dispositivos o al 81.5 % como se puede comprobar en la tabla: 3.3, siendo una decisi´ on entre un mayor grado de desarrollo de Android o una mayor cuota de mercado posible. La implementaci´ on de las librer´ ıas nativas de C en Android, no es la implementaci´on est´andar de Linux. En este sistema operativo se emplea una librer´ ıa espec´ ıfica llamada Bionic que busca ser una implementaci´ on simplificada de las librer´ ıas de C, lo que significa que no incluye todos los m´ etodos que existen en la implementaci´ on
3.2 La creaci´ on de una aplicaci´ on basada en OSG sobre Android 49 APIs Librer´ ıa Nivel m´ ınimo Entorno de ejecuci´ on de C libc 3 Entorno de ejecuci´ on de C++ libstdc++ 3 Librer´ ıa Matem´ atica libm 3 Librer´ ıa de enlazado din´ amico libdl 3 Loggin liblog 3 Zlib libz 3 OpenGL ES 1.1 libGLESv1 CM 4 OpenGL ES 2.0 libGLESv2 5 JNI Graphics libjnigraphics 8 EGL libEGL 4 OpenSL ES libOpenSLES 9 Native Framework libandroid 9 Tabla 3.2: Listado de APIs presente en la capa Nativa Android y la versi´ on m´ ınima requerida. Plataforma Nivel API Distribuci´ on Android 1.5 3 1.3 % Android 1.6 4 2.0 % Android 2.1 7 15.2 % Android 2.2 8 55.9 % Android 2.3 9 0.6 % Android 2.3.2 Android 2.3.3 10 23.7 % Android 2.3.4 Android 3.0 11 0.4 % Android 3.1 12 0.7 % Android 3.1 13 0.2 % Tabla 3.3: Distribuci´ on de las cuota de mercado Android dependiendo de la versi´ on del sistema operativo obtenido de: [goo11d] en Julio de 2011. est´ andar. Esto se ve especialmente en la implementaci´ on de la librer´ ıa de gesti´ on de hilos, pThreads, donde falta una parte de los m´ etodos. Debido a que OSG depende, de ella para la ejecuci´on de hilos, los m´etodos que no existen podr´ıan generar un problema que solo ser´a visible durante la realizaci´on del trabajo
50 An´ alisis del problema OSG es una librer´ ıa que requiere dos caracter´ ısticas especiales del lenguaje C++: Excepciones y RTTI. Son funciones del lenguaje que no pertenec´ ıan a la especificaci´ on inicial y que han sido a˜ nadidas posteriormente en la librer´ ıa STL. En las librer´ ıas nativas de Android se ofrece una versi´ on no est´ andar y muy limitada de la STL que no tiene ninguna de esas caracter´ ısticas. Con el avance en las versiones del NDK, se han incluido tambi´ en dos versiones m´ as de la STL: una versi´ on limitada de STLport y una versi´ on est´ atica de GNU STL. La versi´ on limitada de STLport contiende la mayor parte de caracter´ ısticas y estructuras de C++ a excepci´ on de ambas caracter´ ısticas. En contra la versi´on est´atica de la GNU STL presenta toda la implementaci´on completa de STL incluyendo ambas caracter´ ısticas. Esta librer´ ıa fue incluida por primera vez en la versi´ on cinco del NDK, siendo el mes de Diciembre de 2010 cuando realmente se pudo comenzar el desarrollo de este trabajo trabajo. Finalmente, el uso de la compilaci´on nativa a˜nade un nivel mayor de complejidad porque el programa final debe incluir la versi´on compilada para el procesador apropiado. Esto deber´ a ser soportado en la compatibilizaci´ on de OSG dando la posibilidad de optar entre las diferentes arquitecturas y optimizaciones que est´ an soportadas actualmente. 3.3. Gesti´ on de la memoria en Android Uno de los puntos m´ as habituales para convertirse en cuello de botella es en la memoria de los dispositivos embebidos. La falta de memoria es un problema conocido que se ha ido reduciendo en la presente generaci´ on de dispositivos. Los dispositivos de la actual generaci´ on llegan a tener 512Mbytes e incluso 1Gbyte reduciendo, parcialmente, la problem´ atica. Sin embargo, la falta de memoria, no es el ´ unico problema que podemos tener con la memoria. Las memorias empleadas en estos dispositivos suelen ofrecer una latencia muy alta que obligar´ a a tener en cuenta si es preferible realizar c´ alculos matem´ aticos o realizar lecturas sobre posiciones de memoria que ya tengan los resultados. Esto se estudiar´a durante el desarrollo del trabajo durante el programa de prueba de representaci´on de terrenos generados en tiempo de renderizado. Pensando en la gesti´ on de la memoria, hay algunos detalles que deben tenerse en cuenta en Android. La memoria en Android se divide en dos pilas con un comportamiento diferenciado. Por un lado est´ a la pila de memoria de las aplicaciones en Dalvik
3.4 Garantizar la compatibilidad entre dispositivos 51 y por otro lado est´ a la pila de memoria nativa. La plataforma adem´ as incluye el uso de un recolector de basura que act´ ua, ´ unicamente, en la pila de memoria de Dalvik. La caracter´ ıstica m´ as curiosa es que el sistema no busca liberar la memoria de los programas que salen de ejecuci´ on ante la posibilidad de que puedan volver a entrar en ejecuci´ on. As´ ı pues, la memoria de un dispositivo Android intenta estar ocupada en su totalidad y ´ unicamente se libera espacio en la memoria cuando otra actividad con m´ as prioridad la requiere. Teniendo en cuenta estas condiciones, ser´a necesario emplear la metodolog´ıa de los punteros de referencia que se emplea en la librer´ıa OSG. Esta metodolog´ ıa evitar´ a que tengamos p´ erdidas de memorias que, en un dispositivo donde la traza se ha de realizar externamente, resultan muy dif´ ıciles de encontrar. Debido a la gran variabilidad de memoria seg´ un los dispositivos, las optimizaciones para paliar el consumo de memoria deber´an ser escalables. De esta manera un mismo programa ser´ a capaz de ajustar la representaci´ on de una escena dependiendo de los recursos presentes en vez de optar por emplear la calidad de dibujado al peor caso posible. 3.4. Garantizar la compatibilidad entre dispositivos La variabilidad del hardware compatible con la plataforma Android es muy elevada. Actualmente existen cerca de un centenar de dispositivos diferentes que emplean alguna versi´ on del sistema operativo. El uso de una m´ aquina virtual combinado con una serie de niveles de API intentan garantizar la compatibilidad de las aplicaciones. Aun cuando emplean una m´ aquina virtual para asegurar esto, es imposible evolucionar las herramientas para dar m´ as soporte y utilidades a los desarrolladores y a la vez, mantener una compatibilidad total con las versiones m´ as viejas. As´ ı pues en Android las roturas de compatibilidades no vienen dadas por la versi´ on del sistema operativo. Estas vienen por los cambios que se realizan sobre la API. Leyendo los documentos de las diferentes versiones del SO, vemos como los cambios en muchas versiones son ´ unicamente para mejorar la compatibilidad, velocidad o estabilidad. En algunas de las versiones vemos que existe un cambio en la API que a˜ nade nuevas funcionalidades. Cuando se desarrolla una aplicaci´ on, el programador puede emplear todo el conjunto de posibilidades de una API o solo un subconjunto, adem´ as puede utilizar una versi´ on vieja de acceso a datos o una moderna. Esto es lo que determinar´ a el requisito
52 An´ alisis del problema m´ ınimo de API que necesitar´ a nuestra aplicaci´ on para ser ejecutado, de esta manera, pueden existir diferentes versiones del SO que son compatibles con el mismo nivel de API. Versi´ on del S.O. Nivel API Nombre 1.0 1 BASE 1.1 2 BASE 1 1 1.5 3 CUPCAKE 1.6 4 DONUT 2.0 5 ECLAIR 2.0.1 6 ECLAIR 0 1 2.1.X 7 ECLAIR MR1 2.2.X 8 FROYO 2.3 9 GINGERBREAD2.3.1 2.3.2 2.3.3 10 GINGERBREAD MR1 2.3.4 3.0.X 11 HONEYCOMB 3.1.X 12 HONEYCOMB MR1 3.2 13 HONEYCOMB MR2 Tabla 3.4: Correspondencia de versiones Android con el nivel API y los nombre de versi´ on Por destacar algunas diferencias importantes, el nivel tres de la API es el m´ ınimo para poder ejecutar una aplicaci´ on con partes creadas para ejecutarse de forma nativa independiente de la m´ aquina Dalvik. La memoria m´ axima que se pod´ ıa emplear en los dispositivos era de 256Mbytes hasta el nivel ocho cuando se elimin´ o esa restricci´ on. La inclusi´ on de un compilador JIT para aumento del rendimiento de las aplicaciones tambi´ en aparece en el nivel ocho, as´ ı como las primeras tags de requisitos m´ ınimos. Recientemente los niveles a partir del nueve incluyen el soporte para actividades nativas y optimizaciones dependiente de nuevos tipos de pantalla. Junto al sistema de versi´ on, se han implementado una serie de marcadores que pueden a˜ nadirse, como condiciones, al archivo de manifiesto de una aplicaci´ on, lo que permite incluir condiciones m´ ınimas para que una aplicaci´ on pueda ser instalada. Algunas de las restricciones que podemos emplear discriminan los dispositivos por
3.5 La creaci´ on de un paquete Third-Party 53 modelos concretos, presencia de librer´ ıas, compatibilidad con extensiones de OpenGL o la posibilidad de emplear texturas comprimidas de un formato determinado. Figura 3.4: Muestra de c´ odigo con restricciones en el archivo de manifiesto. En la figura: 3.4 se puede ver un ejemplo de restricci´ on sobre un archivo de manifiesto que discrimina el dispositivo exigiendo que sea capaz de emplear la compresi´ on ETC1 y la extensi´ on de texturas paletizadas. Siguiendo esta idea de especializaci´ on, se pueden emplear los cambios introducidos en la API de Honeycomb (3.X) que introduce nuevas posibilidades para distribuir las aplicaciones de forma especializada y concreta para cada dispositivo. Esta opci´ on se emplear´ a en el trabajo ya que permite realizar versiones espec´ ıficas adaptadas a emplear una mayor o menor memoria dependiendo de la memoria disponible en el dispositivo. Durante el trabajo se deber´an especificar claramente las restricciones hardware para evitar que el programa final sea instalado en un dispositivo incompatible. Ser´ a conveniente definir la API gr´ afica usada, las extensiones requeridas y las compresiones de texturas que deben ser soportadas en el dispositivo. 3.5. La creaci´ on de un paquete Third-Party La librer´ ıa OSG est´ a especializada ´ unicamente en la gesti´ on y representaci´ on de elementos gr´ aficos, es decir, por si sola es incapaz de abrir muchos tipos de archivo. Para gestionar la apertura de archivos, OSG tiende a depender en una serie de librer´ ıas que ya est´ an especializadas en la gesti´ on de tipos de archivos concretos. Sin estas librer´ ıas, OSG ´ unicamente soporta algunos formatos de archivos cuya decodificaci´ on ha sido implementada en el plugin sin depender de ninguna librer´ ıa. Si bien, OSG se puede emplear sin estos elementos, una de las grandes ventajas de la librer´ ıa es, precisamente, que se encargaba de gestionar la apertura de los archivos y ponerlos a disposici´ on del programador de forma transparente y no invasiva. Sin esta
54 An´ alisis del problema caracter´ıstica, el desarrollador se queda limitado a unos pocos formatos compatibles que no son los habituales en una aplicaci´on. Por ello, es necesario realizar un paquete que a˜ nada el mayor n´ umero posible de estas dependencias para que el desarrollo de aplicaciones con OSG en Android sea atractivo de cara a los desarrolladores. Las principales librer´ ıas a tener en cuenta para ser incluidas son: Curl - Librer´ ıa para el env´ ıo y recepci´ on de datos por red. Freetype - Librer´ ıa para la representaci´ on de fuentes de texto. Gdal - Librer´ ıa para la gesti´ on de bases GIS. giflib - Librer´ ıa para el uso de im´ agenes gif. libjpeg - Librer´ ıa para el uso de im´ agenes jpeg. libpng - Librer´ ıa para el uso de im´ agenes png. libtiff - Librer´ ıa para el uso de im´ agenes tiff. zlib - Librer´ ıa para el uso de archivos comprimidos. Para realizar este paquete, se generar´ an una serie de scripts que gestionen la compilaci´ on. Muchas de estas librer´ ıas se encuentran implementadas en el propio sistema operativo Android, pero no se encuentran expuestas para su uso por el programador. No forman parte de la ABI nativa y por lo tanto las versiones pueden cambiar con el tiempo, por ello lo correcto es incluir tu propia compilaci´ on de la librer´ ıa junto al programa que la utilice para evitar incompatibilidades en el enlazado. 3.6. Filtrado de eventos de entrada t´ actil En Android, la implementaci´ on de la gesti´ on de la entrada t´ actil se deja a conveniencia de la empresa que fabrica el dispositivo. As´ ı pues, la entrada que recibe el programador por parte del usuario, aunque cumple el est´ andar de eventos de Android, puede contener ruido que distorsione el gesto que recibe el programa. El ruido en la entrada puede estar formado por diferencias de muestreo que hacen que la aplicaci´ on reciba un movimiento sin que el dedo se haya movido. Otro ruido
3.7 Integraci´ on del sistema de compilado NDK con la librer´ ıa OSG 55 muy habitual ocurre cuando se detecta incorrectamente el n´ umero de punto de presi´ on provocando que, para el programador, los puntos de presi´ on se hayan invertido. Para asegurar una experiencia de usuario correcta, es necesario filtrar estos ruidos a nivel de aplicaci´ on, ya que aparecer´ an en algunos dispositivos y, en principio, no lo podemos detectar sin comprobarlo f´ ısicamente. Para resolver este problema, aplicaremos una t´ecnica de filtrado a partir de una serie de muestreos previos siguiendo el trabajo [Biz10]. Se utilizar´ a una lista de muestras que se ir´ an actualizando y que a˜ nadir´ an un peque˜ no retraso en la respuesta a cambio de obtener un funcionamiento correcto de cara al usuario. 3.7. Integraci´ on del sistema de compilado NDK con la librer´ıa OSG El NDK emplea sus propios scripts de compilaci´ on, integrarlos directamente sobre OSG supondr´ ıa obligar a que existieran dos cadenas de compilaci´ on, lo cual duplicar´ ıa el trabajo de mantener los archivos cuando se realizan modificaciones. Para soportar otras plataformas OSG emplea CMake como generador de scripts para compilar en cada plataforma cuando el usuario quiere compilar la librer´ ıa. CMake actualmente no soporta la generaci´on de scripts para el NDK de Android, pero dada su naturaleza de lenguaje de scripting, se puede programar sobre los scripts de CMake. Para integrar la compilaci´ on Android en OSG, se emplear´ a la opci´ on de compilaci´ on cruzada que est´ a presente en CMake, para ello se generar´ a un fichero con los datos de la toolchain del compilador, fuentes y librer´ ıas que se encuentran en el NDK. Desde la versi´ on n´ umero 5, es posible generar un directorio independiente con la estructura correcta para ser usado como toolchain para una compilaci´ on cruzada. 3.8. Planificaci´ on del proyecto Las siguientes figuras presentan la planificaci´ on del proyecto. El trabajo ha sido dividido en veinticuatro tareas incluyendo la planificaci´ on inicial, la escritura de un art´ ıculo y la escritura de la memoria final del proyecto.
56 An´ alisis del problema Figura 3.5: Diagrama de Gantt de la planificaci´ on del proyecto p´ agina: 1/6
3.8 Planificaci´ on del proyecto 57 Figura 3.6: Diagrama de Gantt de la planificaci´ on del proyecto p´ agina: 2/6
64 Desarrollo guaje en la programaci´ on nativa, sin embargo la implementaci´ on de las librer´ ıas de C no corresponde a la est´ andar. Android ha reimplementado la mayor parte de librer´ ıas de C en una llamada Bionic. El objetivo de esta librer´ ıa era crear una implementaci´ on eficiente y que fuese lo m´ as simple posible, a cambio no tiene implementados todos los m´ etodos que se encuentran en la de referencia. Otra limitaci´ on que imponen las librer´ ıas de Android viene debida a la implementaci´ on de la librer´ ıa STL. Hasta la versi´ on cinco del Native Development Kit (NDK) no pod´ ıamos contar con una versi´ on est´ andar de la GNU STL. Google ofrec´ ıa una simplificada con un soporte m´ ınimo. En la versi´ on 5 a˜ nadi´ o el soporte para emplear una librer´ ıa STL independiente (STLport) y la GNU STL, sin embargo, el uso de ambas librer´ ıas tiene limitaciones. La versi´ on de STLport en Android, todav´ ıa no tiene soporte para RTTI o las excepciones de C++. Por su parte, la librer´ ıa GNU STL ´ unicamente se puede enlazar de forma est´ atica, lo que conlleva un sobrecoste en el tama˜ no de las aplicaciones cuando varias librer´ ıas comparten su uso. El proceso de adaptaci´ on de la librer´ ıa tuvo tres fases principales: Compilaci´ on de la librer´ ıa mediante los scripts Android NDK e integraci´ on en el sistema de compilaci´ on CMake de la librer´ ıa OSG. Generaci´ on de los programas de prueba. Creaci´ on de la documentaci´ on y programas de ejemplo para la comunidad OSG. 4.2. Integraci´ on de un sistema de compilado Android NDK en la librer´ıa OpenSceneGraph Para este trabajo, inicialmente, se crearon archivos de script siguiendo la sintaxis de los ficheros de compilaci´ on .mk del NDK de Android, as´ ı como crear un fichero por cada librer´ ıa y plugin de OSG. Cada uno de esos ten´ ıa la estructura siguiente. #ANDROID m a k e f i l e osg
4.2 Integraci´ on de un sistema de compilado Android NDK en la librer´ ıa OpenSceneGraph 65 LOCAL PATH := /home/jizquierdo/ repositorio OpenSceneGraph/src/osg include $ (CLEAR VARS) LOCAL CPP EXTENSION := cpp LOCAL LDLIBS := −lOpenThreads −lGLESv1 CM −l d l LOCAL MODULE := osg LOCAL SRC FILES := AlphaFunc . cpp AnimationPath . cpp . . . LOCAL C INCLUDES := /home/jizquierdo/ repositorio OpenSceneGraph/include /home/jizquierdo /repositorio OpenSceneGraph/android build gles1/ include LOCAL CFLAGS := −DANDROID −DOSG LIBRARY STATIC LOCAL CPPFLAGS := −DANDROID −DOSG LIBRARY STATIC C´odigo 4.1: Fragmento de c´ odigo de un archivo de script para una librer´ ıa de OSG. Analizando los elementos del script: LOCAL_PATH: Directorio de referencia sobre el que se buscar´ an el resto de archivos. include $(CLEAR_VARS): Incluye el script NDK de limpiar variables. Limpia cualquier variable excepto LOCAL_PATH. LOCAL_CPP_EXTENSION: Define la extensi´ on de los archivos. LOCAL_LDLIBS: Define las librer´ ıas que deber´ an enlazarse con la librer´ ıa actual.
66 Desarrollo LOCAL_MODULE: Define el nombre de la librer´ ıa. LOCAL_SRC_FILES: Lista de los archivos que se han de compilar para esta librer´ ıa. LOCAL_C_INCLUDES: Lista de directorios con las cabeceras. LOCAL_CFLAGS/LOCAL_CPPFLAGS: Definiciones que se incluyen para todos los archivos. include $(BUILD_STATIC_LIBRARY): Incluye el script que configura esta librer´ ıa como est´ atica. Con todas las librer´ ıas que forman OSG preparadas con su script de compilaci´ on NDK, ´ unicamente falt´ o a˜ nadir los scripts principales para compilar los distintos m´ odulos de la librer´ ıa. El script inicial est´ a formado por dos archivos: Android.mk y Application.mk #ANDROID m a k e f i l e in s r c LOCAL PATH := $ ( c a l l my−dir ) SRC ROOT := $ (LOCAL PATH) include /home/jizquierdo/repositorio OpenSceneGraph/3 rdparty/ z l i b /Android .mk ... include /home/jizquierdo/repositorio OpenSceneGraph/ android build gles1/src/osgPlugins/pvr/Android .mk C´odigo 4.2: Fragmento de c´ odigo del archivo principal ”Android.mk”. Como se puede ver en el extracto del archivo principal, podemos distinguir las siguientes ´ ordenes: LOCAL_PATH: Variable que guarda el directorio actual obtenido mediante $(call my-dir)
4.2 Integraci´ on de un sistema de compilado Android NDK en la librer´ ıa OpenSceneGraph 67 SRC_ROOT: Define el directorio de archivos de c´ odigo mediante la variable $(LOCAL_PATH) include: Lista de los archivos de cada librer´ ıa. #ANDROID APPLICATION MAKEFILE APP BUILD SCRIPT := $ ( c a l l my−dir )/Android .mk APP PROJECT PATH := $ ( c a l l my−dir ) APP OPTIM := rel eas e APP PLATFORM := android−5 APP STL := g n u s t l s t a t i c APP CPPFLAGS := −fexceptions −f r t t i APP ABI := armeabi armeabi−v7a APP MODULES := z l i b OpenThreads osg osgDB osgUtil osgGA osgText osgViewer osgAnimation osgFX osgManipulator o sg Par ti c le osgPresentation osgShadow osgSim osgTerrain osgWidget osgVolume C´odigo 4.3: Fragmento de c´ odigo del archivo principal ”Application.mk”. APP_BUILD_SCRIPT: Variable que indica donde se encuentra el archivo Android.mk. APP_PROJECT_PATH: Variable que indica al compilador la ruta sobre la que se trabaja. La informaci´ on del directorio se obtiene con: $(call my-dir) APP_OPTIM: Variable que indica al compilador si debe compilarlo con o sin s´ ımbolos de debug. APP_PLATFORM: Variable que indica al compilador la versi´ on de plataforma. APP_STL: Configura la STL que se va a emplear. APP_CPPFLAGS: Configuraciones de C++.
68 Desarrollo APP_ABI: Arquitecturas para las que se realiza la compilaci´ on. APP_MODULES: Lista de librer´ ıas que se han de compilar para este proyecto. 4.2.1. Problemas presentados durante la compilaci´ on Los primeros intentos de compilaci´ on, evidenciaron una serie errores. Algunos de estos ya se hab´ ıan considerado y detectado como tales durante la fase de an´ alisis: Errores por las diferencias en la librer´ ıa pThreads. Errores por la falta de soporte para los tipos de car´ acter ancho (wchar). Definiciones de cabeceras. Definici´ on de tipos GL. Como se ha dicho anteriormente, la implementaci´ on de las librer´ ıas de C no es completa, la siguiente lista detalla algunos de los m´ etodos que, existiendo en la especificaci´ on en Linux y siendo requeridos por OSG, no aparecen en la implementaci´ on de Android. pThreads testcancel pThreads cancel pThreads setcancelstate pThreads setcanceltype Tal y como se indica en la documentaci´ on de Google: pthread cancel ( ) will ∗not∗be supported in Bionic , because doing t h i s would involve making the C l ib ra ry s i g n i f i c a n t l y bigger for very l i t t l e be ne fit .
4.2 Integraci´ on de un sistema de compilado Android NDK en la librer´ ıa OpenSceneGraph 69 Es decir, las instrucciones cancelaci´ on de hilos no ser´ an implementadas debido al aumento de tama˜ no que provocar´ ıa en la librer´ ıa y el poco beneficio de su implementaci´ on. Por lo tanto, no es factible incorporar la funcionalidad de dichos elementos. La librer´ ıa OSG, emplea para abstraer la gesti´ on de hilos la librer´ ıa OpenThreads (OT). Esta tiene implementaciones dependientes para cada sistema operativo, y una de ellas es la de pThreads, el problema surge por la falta de dichos m´ etodos. Tras estudiar cuidadosamente el uso de los comandos de cancelado de OT por parte de OSG, se pudo concluir que no se empleaba la cancelaci´ on a lo largo de todo el c´ odigo, lo que permiti´ o emplear el siguiente procedimiento: Generar rutas vac´ ıas que ser´ an empleadas, o no, en tiempo de compilaci´ on mediante el uso de una constante de plataforma (ANDROID). Esto se generar´ a mediante macros de precompilaci´ on introducidas en el c´ odigo de la librer´ ıa OT. Es cierto que esa soluci´ on no es factible para todo programa que necesite la operaci´ on de cancelaci´ on de hilos, pero el presente trabajo ´ unicamente se ha centrado en la compatibilidad de la librer´ ıa OSG, no en el uso general de la librer´ ıa OT para otras aplicaciones. Toda aplicaci´on que quiera portarse a Android, deber´a replantear su uso de la cancelaci´on de hilos ya que, como est´a publicado en la documentaci´on oficial; ”jam´as“ se incorporar´a la operaci´on de cancelaci´on de hilos en la librer´ıa Bionic. Los errores debido a la falta de soporte para los tipos de caracteres anchos, caracteres que necesitan m´ as de un byte, son debidos a que wchar no se encuentra realmente recogido en todas las versiones de C, por ello, Google no los ha incorporado. El prop´ osito de los caracteres anchos es la representaci´ on de caracteres en codificaciones diferentes de ANSI (UTF16/UTF32), en la librer´ ıa ´ unicamente afectan para el uso de cadenas que no empleen ASCII en la base de datos (osgDB). Existen dos soluciones posibles para este problema. Por un lado, el programador puede usar una versi´ on modificada del NDK que incluye el soporte para wchar, esta soluci´ on es desaconsejable por los problemas de compatibilidad que puedan aparecer en el futuro. Desde el inicio del proyecto, se ha buscado seguir lo m´ as cercanamente posible a los est´ andares de Google. Recurrir a versiones modificadas ser´ıa algo que podr´ıa hacer que la librer´ıa dejase de poder compilarse con el tiempo. Nuestra soluci´on sigue el mismo patr´on que la soluci´on ya implementada para OSG en algunas plataformas compatibles con Linux sin wchar. Creamos una redefinici´on de tipo sobre un char, si bien esto no da las funciones reales, es una soluci´ on que ha sido aceptada por la comunidad de OSG, delegando la vigilancia de usar caracteres ASCII en la base de datos de OSG a los programadores.
70 Desarrollo Los problemas que aparecieron debido a las cabeceras, se deben a la selecci´ on de cabeceras dependiendo de la plataforma objetivo. Estos cambios fueron menores y repartidos a lo largo de diversos archivos. Consist´ ıan en incluir en las condiciones de uso la variable ”ANDROID“. Esta es la raz´ on por la cual en los scripts de compilaci´ on se incluye la l´ ınea: LOCAL_CPPFLAGS := -DANDROID. Al a˜ nadir esa flag al compilador, incluimos una constante que es usada como definici´ on. lo que permite realizar condiciones de precompilaci´ on espec´ ıficas para Android. Finalmente el ´ ultimo error que encontramos se debe a los tipos de OpenGL. OSG realiza redefiniciones de tipos y de constantes OpenGL, evita propagar los archivos de OpenGL, debido a que pueden haber cambios por plataforma y versi´ on, propagando ´ unicamente las definiciones y constantes que ´ el crea. Ha sido necesario crear una ruta de elecciones para la plataforma Android que definiese exclusivamente los tipos de OpenGL siguiendo la especificaci´ on de OpenGL ES 1.0 y 2.0 que emplean los mismos tipos. La inclusi´ on de estos cambios y la cadena de scripts de compilaci´ on NDK permiten generar los archivos binarios para ser enlazados de forma est´ atica con nuestras aplicaciones. En el punto actual del desarrollo, ´ unicamente se ha permitido emplear la compilaci´ on de los componentes de OSG como librer´ ıas est´ aticas. Esto se debe a dos razones: La librer´ ıa STL contra la que se enlazan las librer´ ıas OSG es est´ atica, si cada m´ odulo se compilara para ser din´ amico incluir´ ıa para si las partes que requiere de la librer´ ıa STL. Esto supone que los binarios finales tendr´ ıan un peso muy superior al incluir elementos de c´ odigo repetido al no poder compartir de forma din´ amica la librer´ ıa STL. En este momento, al ser compiladas de forma est´ atica, ´ unicamente se introducen los m´ etodos usados de la STL cuando se compila el programa final. La carga de librer´ ıas din´ amica en OSG est´ a creada pensando en un sistema de sobremesa donde las librer´ ıas han sido instaladas en un lugar determinado. En nuestro caso, los m´ etodos de apertura y la situaci´ on de los elementos de la librer´ ıa variar´ an de dispositivo a dispositivo. Aun as´ ı, es posible emplear la librer´ ıa OSG de forma est´ atica, siempre y cuando empleemos las macros de definici´ on de m´ odulos y plugins para que el n´ ucleo de OSG
4.2 Integraci´ on de un sistema de compilado Android NDK en la librer´ ıa OpenSceneGraph 71 Figura 4.1: Imagen del primer programa funcional de OSG en Android dibujando un tri´ angulo RGB. detecte que puede usarlos ya que se encuentran en su c´ odigo. Con esto es posible obtener nuestros primeros resultados visibles como se observa en la figura 4.2.1
72 Desarrollo 4.2.2. Integraci´ on de los scripts NDK en los scripts CMake En la ´ ultima fase del proyecto, se busc´ o una forma de integrar de forma sencilla y poco intrusiva los scripts de compilaci´ on. OSG es una librer´ ıa con m´ as de 400 archivos de c´ odigo diferente, cada vez que se introducen cambios significativos como modificaciones de nombre, nuevos archivos, nuevas opciones; se han de retocar los diferentes archivos de script CMake que ya posee OSG, si a˜ nadimos una segunda secuencia de compilado ´ unicamente para Android, esto supone el doble de trabajo, adem´ as, los scripts de Android deben ser retocados en mayor o menor medida cuando el usuario desee ajustar algunos elementos. Por lo tanto se requiere de un m´ etodo que permita reajustar de forma sencilla todos los scripts cuando se ajustan los scripts de CMake. A la vez es necesario que podamos dar posibilidad a que los usuarios puedan definir sus opciones de plataformas de destino, versiones de NDK, etc. Recordemos que OSG emplea CMake como sistema de scripts para asegurar la generaci´ on autom´ atica de scripts de compilaci´ on en cada plataforma. Compilar para Android tiene una serie de particularidades: Es una compilaci´ on cruzada, se realiza fuera de la plataforma destino. Aunque actualmente Google emplee una versi´ on de Gcc con una estructura de archivos similar a la de Linux, esto puede cambiar sin previo aviso, lo que har´ ıa in´ util el uso (todav´ ıa experimental) de los scripts de compilaci´ on cruzada que puede generar CMake. El primer intento de unificaci´ on se realiz´ o a˜ nadiendo un archivo para obligar a CMake a emplear una toolchain diferente a la del sistema operativo origen, esto permite realizar la compilaci´ on cruzada directamente con CMake. Esta aproximaci´ on hubo de ser descartada tras comprobar que, con la versi´ on NDK r5, CMake emit´ ıa falsos positivos en sus comprobaciones durante la compilaci´ on cruzada. Ante esta tesitura se decidi´ o abordar un sistema que permitiese generar autom´ aticamente los scripts de NDK a partir de los scripts de CMake cuando el usuario lo ejecutase en su plataforma. CMake es un lenguaje de scripting con la capacidad de programar sobre ´ el, esto permite extender las operaciones del programa sin necesidad de integrar nuevas reglas de generaci´ on de archivos en su c´ odigo fuente. De esta manera, se pueden incluir elementos y realizar operaciones para las que no estaba dise˜ nado originalmente. Para este trabajo, se emplear´ a esta capacidad para hacer que el lenguaje genere los archivos de script NDK a partir de unos scripts modelos dise˜ nados para tal prop´ osito. Cuando CMake ejecuta los contenidos del script, crea los archivos copiando la estructura
4.2 Integraci´ on de un sistema de compilado Android NDK en la librer´ ıa OpenSceneGraph 73 de los archivos modelos e insertando las definiciones necesarias para la compilaci´ on: nombres de archivos a compilar, opciones de compilaci´ on, nombre del m´ odulo, dependencias, etc. Para realizar esto, se cre´ o una macro que permit´ ıa crear el archivo de script NDK final de una librer´ ıa. La macro usa, como estructura modelo de c´ odigo el fragmento: 4.1. Los diversos valores son rellenados por los el contenido de las variables que emplea CMake para generar los scripts de compilaci´ on normalmente. El funcionamiento de esta se puede ver en el siguiente fragmento: 4.4 MACRO(SETUP ANDROID LIBRARY LIB NAME) foreach ( arg ${TARGET LIBRARIES}) set(MODULE LIBS ”${MODULE LIBS} −l$ {arg}” ) endforeach ( arg ${TARGET LIBRARIES}) foreach ( arg ${TARGET SRC}) st r in g (REPLACE ”${CMAKE CURRENT SOURCE DIR}/” ”” n f ${arg}) set(MODULE SOURCES ”${MODULE SOURCES}${n f }” ) endforeach ( arg ${TARGET SRC}) #SET(MODULE INCLUDES ”${CMAKE SOURCE DIR}/ i n c l u d e i n c l u d e ”) GET DIRECTORY PROPERTY( loc in clude s INCLUDE DIRECTORIES) foreach ( arg ${loc includes}) IF (NOT ”${arg}” MATCHES ”/usr/include ” AND NOT ” ${arg}” MATCHES ”/usr/ l o c a l /include ” ) set(MODULE INCLUDES ”${MODULE INCLUDES}${ arg}” ) ENDIF ( ) endforeach ( arg ${loc includes}) GET DIRECTORY PROPERTY( l o c d e f i n i t i o n s
80 Desarrollo El mecanismo de paquete es usado actualmente para instalar ´ unicamente las partes que el dispositivo destino pueda emplear. Como se comenta en el siguiente punto, al desarrollar en nativo, se compila para diferentes arquitecturas. Sin embargo cuando se instala un paquete, ´ unicamente se copian las librer´ ıas que corresponden a la arquitectura del dispositivo. Esta forma de proceder ha sido extendida en la actualidad en el mercado de Google. Se ha incluido soporte para que una ´ unica aplicaci´ on tenga diferentes paquetes para tratar casos espec´ ıficos como el uso, o no, de compresi´ on de texturas. Una aplicaci´ on, as´ ı pues, debe estar formada por la estructura expuesta con los diversos archivos de configuraci´ on adem´ as del c´ odigo propio de la aplicaci´ on, ya que Android requiere de dichos archivos para configurar apropiadamente el entorno de ejecuci´ on de la aplicaci´ on, por lo tanto esto ha de cuidarse especialmente en las aplicaciones que se desarrollar´ an en este trabajo. Centr´ andonos m´ as espec´ ıficamente en el c´ odigo ejecutable, las aplicaciones de Android no son monol´ ıticas, se encuentran fraccionadas en actividades. Citando la definici´ on de Google “Una aplicaci´ on Android se compone de una serie de actividades vagamente relacionadas”. Una actividad es un proceso del programa que encapsula, a la vez, la interfaz gr´ afica del proceso y su funcionalidad, y est´ a intr´ ınsecamente relacionada con la interfaz del usuario. Son procesos que deben ser visibles y ofrecer respuesta (o permitir la comunicaci´ on) a los eventos generados por el usuario. A diferencia de un proceso com´ un de los sistemas de sobremesa como Unix o Windows, la visibilidad es uno de los factores m´ as importantes para decidir el estado en el que se debe encontrar una actividad. Tenemos que tener en cuenta que las aplicaciones en Android est´ an pensadas en el uso normal de un tel´ efono m´ ovil. Un usuario normal espera poder emplear su agenda diaria en su tel´ efono y, si recibe una llamada poder contestar a la llamada sin que la aplicaci´ on le interrumpa o sea visible. Sin embargo, atender una llamada no significa que el usuario quiera cerrar lo que estaba haciendo, muchas veces la coger´ a sin salvar los datos; por lo tanto el comportamiento que desear´ ıa el usuario es que la aplicaci´ on permanezca a la espera. De esa manera, el usuario, si lo desea, la puede devolver a ejecuci´ on desde el punto en el que la dej´ o en espera. Hasta ahora se ha hablado ´ unicamente de las actividades, Dado que existe una noci´ on de estado en la propia aplicaci´ on y ´ unicamente se emplea el concepto de que un programa est´ e ejecutando la actividad X en un punto determinado, esto implica que el ciclo de vida no es a nivel de aplicaci´ on sino a nivel de actividad. Este ciclo se
4.3 Creaci´ on de las aplicaciones de Test 81 puede ver en la ilustraci´ on: 4.3.1 Una actividad creada por el usuario se crea extendiendo la clase Activity de Android, la cual, tiene una serie de m´ etodos que se llaman autom´ aticamente cuando el sistema reconoce un cambio de estado para la actividad. Dichos m´ etodos pueden ser reimplementados para cada que cada actividad realice los ajustes necesarios para su comportamiento. La vida de una actividad transcurre entre su creaci´ on y su destrucci´ on. Estas se producen con las llamadas a “onCreate” y “onDestroy”. Durante la creaci´ on, la actividad crear´ a todos los elementos que necesite para su estado interno de ejecuci´ on, servicios, hilos, etc. En su destrucci´ on, liberar´ a todos los recursos que haya ocupado. El tiempo de vida que el usuario percibe es aquel que comienza en “onStart” hasta que llega a “onStop”. En este per´ ıodo, la actividad es visible por el usuario, sin embargo no es necesario que tenga el foco visual, esta actividad puede estar paralizada en un segundo plano. Finalmente el tiempo de vida que la actividad realmente es controlada por el usuario abarca desde “onResume” hasta “onPause”. La pausa y la reanudaci´ on son algunos de los momentos m´ as habituales de una programa. Es com´ un que una actividad se quede a la espera de una respuesta de otra actividad o se suspenda el dispositivo. Hasta ahora se ha hablado ´ unicamente de las actividades. Como se ha dicho, una actividad necesita tener una representaci´ on visual y responder ante los eventos. Esto significa que en ning´ un momento el hijo principal de ejecuci´ on de la actividad puede bloquear la entrada de eventos. Cuando la actividad no es capaz de responder al sistema durante un tiempo, la cantidad var´ ıa dependiendo de la implementaci´ on, Dalvik aborta la actividad por un error ANR (Activity Not Responding). Existen determinadas aplicaciones que, debido a sus requisitos, C´ alculos complejos, carga de archivos, transmisi´ on de datos, tienden a ocasionar una espera demasiado larga provocando el error ANR. Por ello en Android existe el soporte de hilos (Threads) desde el framework Android. Adicionalmente, Android incluye los servicios, a diferencia de los Threads, los servicios funcionan desde el mismo hilo de ejecuci´ on que la actividad que los ha invocado, esto implica que no pueden resolver el error ANR, ya que su prop´ osito es crear tareas en el sistema operativo. Estas se ejecutar´ an en segundo plano sin que el usuario tenga constancia de ellas. Una de sus grandes utilidades es que diferentes actividades pueden hacer uso de dichos servicios si se encuentran presentes. Es muy importante tener en cuenta el ciclo de las actividades as´ ı como el error
82 Desarrollo Figura 4.3: Diagrama del ciclo de vida de una actividad en Android.
4.3 Creaci´ on de las aplicaciones de Test 83 ANR ya que son conceptos b´ asicos de la plataforma. Si no se cumplen los requisitos de cambios de estado, guardado de estado actual, etc las aplicaciones que se buscan desarrollar en este trabajo ser´ an incapaces de convivir correctamente con el resto de aplicaciones en la plataforma. En este trabajo, no se van a emplear todas las posibilidades que est´ an presentes en la plataforma. Hay que prestar una atenci´ on especial al error ANR y se debe procurar inicializar la biblioteca OSG en un hilo para evitar el bloqueo al iniciar las aplicaciones en Android. Despu´ es de la inclusi´ on de la Native Activity en la versi´ on 2.3 de Android, las aplicaciones de OSG sobre Android pueden tener dos estructuras diferentes. La principal diferencia que existe entre ambas estructuras es el uso, o no del framework nativo. Las ventajas de este m´ etodo ya han sido discutidas, sin embargo hay que comentar tambi´ en que si el desarrollador desea usar la GUI u otros elementos de la API que todav´ ıa no han sido expuestos a nivel nativo, debe emplear un puente JNI para comunicarse con el framework superior de Dalvik. Una aplicaci´ on puramente nativa, sigue de igual manera el ciclo de vida expuesto anteriormente. Las ´ unicas diferencias reales con una actividad de Android no nativa son: el uso del lenguaje C/C++ y la imposibilidad de emplear todo el framework de Dalvik, ya que este no se encuentra totalmente expuesto al desarrollador para su uso en el nivel nativo. Una de las ventajas que tienen las aplicaciones totalmente nativas es la generaci´ on de un contexto gr´ afico desde el nivel nativo. Hasta la aparici´ on de esta posibilidad, la parte Dalvik era la due˜ na del contexto EGL y no pod´ ıa ser transmitido para incorporarlo en OSG. Por el contrario, una aplicaci´ on que no sea puramente nativa, debe emplear una actividad Java que controle y encapsule todos los eventos de entrada. En el momento de inicio de la actividad, ha de crearse un contexto mediante EGL, debido a que este se encuentra en el nivel no nativo y no puede ser compartido con la parte nativa de la aplicaci´ on OSG, adem´ as la clase que gestiona el contexto, debe encapsular las llamadas de renderizaci´ on y cambios de representaci´ on. Las figuras 4.5 y 4.4 representan una modelo b´ asico de estructura de aplicaci´ on OSG para Android. La figura de la versi´ on parcialmente nativa, es la que se encuentra implementada, con variaciones, en los prototipos y pruebas de este trabajo. Debido al coste econ´ omico de los dispositivos necesarios para hacer tests con una aplicaci´ on enteramente nativa, la estructura presentada es un esbozo que sigue los patrones de dise˜ no marcados por Google. Su funcionamiento no ha sido comprobado f´ ısicamente. Como se puede ver en la figura: 4.5 la actividad principal se genera como Java. Esta actividad se comunica con una clase derivada de GLSurfaceView (EGLview) que se
84 Desarrollo Figura 4.4: Diagrama de clases de la estructura de una aplicaci´ on OSG en Android usando NativeActivity. encarga de realizar la configuraci´ on del contexto gr´ afico y de registrar la funci´ on de renderizado. Para realizar las llamadas a OSG utilizan la clase osgNativeLib, esta clase contiene los m´ etodos expuestos mediante el puente JNI. Ya en el nivel nativo, podemos ver como los m´ etodos nativos emplean la clase osgViewerAndroid para realizar sus operaciones. En contraposici´ on, la versi´ on puramente nativa representada en: 4.4 ´ unicamente tiene una clase general con los m´ etodos a registrar para su uso por parte de la NativeActivity, estos a su vez, pueden acceder a la clase osgViewerAndroid para gestionar la representaci´ on.
4.3 Creaci´ on de las aplicaciones de Test 85 Figura 4.5: Diagrama de clases de la estructura de una aplicaci´ on OSG en Android.
86 Desarrollo 4.3.2. Generaci´ on de un paquete de librer´ıas third party para OSG Para la creaci´ on de los programas de tests anteriores, es necesario que la librer´ ıa OSG sea capaz de cargar y representar tipos de texturas y modelos complejos que no se encuentran soportados por la propia librer´ ıa de OSG, para ello, la librer´ ıa emplea una serie de plugins que se encargan de la gesti´ on de dichos archivos, la carga o el guardado, y el plugin oportuno lo introduce como un elemento del grafo de escena. Aunque muchos de los plugins y librer´ ıas de terceros se emplean para los formatos, algunas de las librer´ ıas son empleadas para opciones complejas alejadas de la gesti´ on de un tipo de archivo. La librer´ ıa Curl, por ejemplo, permite realizar peticiones Http para la transferencia de archivos. La librer´ ıa Zlib por ejemplo da la opci´ on de cargar modelos que se encuentren dentro de un archivo comprimido de forma directa y la librer´ ıa Freetype se encarga de generar la representaci´ on de las fuentes que deseemos representar. Figura 4.6: Primera prueba de funcionamiento del plugin de representaci´ on de texturas con formato PNG. Sin estas librer´ ıas OSG seguir´ ıa siendo funcional, pero quedar´ ıa lastrado al tener que prescindir de muchas opciones muy empleadas en el desarrollo de aplicaciones. En la figura 4.6 se puede observar el uso de la librer´ ıa libpng y su plugin en OSG para realizar la representaci´ on de la textura sobre el tri´ angulo del primer programa OSG en Android. Las librer´ ıas integradas en el paquete son:
4.3 Creaci´ on de las aplicaciones de Test 87 Curl - Librer´ ıa para el env´ ıo y recepci´ on de datos por red. Freetype - Librer´ ıa para la representaci´ on de fuentes de texto. Gdal - Librer´ ıa para la gesti´ on de bases GIS. giflib - Librer´ ıa para el uso de im´ agenes gif. libjpeg - Librer´ ıa para el uso de im´ agenes jpeg. libpng - Librer´ ıa para el uso de im´ agenes png. libtiff - Librer´ ıa para el uso de im´ agenes tiff. zlib - Librer´ ıa para el uso de archivos comprimidos. El paquete generado es una estructura de carpetas que incluye directorios preparados para compilar, conjuntamente con OSG, los c´ odigos fuente de las librer´ ıas integr´ andolas en la estructura de compilaci´ on de OSG Android. Tambi´ en se incluye un directorio que incluye las librer´ ıas compiladas listas para usarse en cualquier tipo de aplicaci´ on basada en Android. Las librer´ ıas han sido preparadas una a una con scripts NDK generados por los listados de archivos a compilar y con las opciones b´ asicas. 4.3.3. Pruebas funcionales Para comprobar las funcionalidades y el rendimiento de OSG, se han creado una serie de casos de control. Partimos de un visor b´ asico que tiene activadas todas las librer´ ıas principales de OSG y un subconjunto de plugins que cubren: jpeg, png, Freetype, curl, osg, osg2. La estructura de la aplicaci´ on sigue las directrices b´ asicas que han sido tratadas en el punto: 4.3.1. Debido a las diferencias existentes entre las dos API gr´ aficas de OpenGL ES, se han creado dos visores para recoger las estad´ ısticas en ambos casos. La estructura de la aplicaci´ on era id´ entica en ambos casos. Las diferencias que existen entre las dos aplicaciones son: La versi´ on OpenGL ES con la que fue compilada la librer´ ıa OSG. El uso de shaders para representar los modelos de las pruebas, esto es debido a las normas de funcionamiento que impone la versi´ on 2.0 de la API gr´ afica.
88 Desarrollo Debido a que existen diferencias significativas si se usa un shader complejo, para este estudio se han empleado los shaders de referencia que tiene publicada la Kronos ARB, estos programas replican la funcionalidad de la tuber´ ıa de procesado fija, computando la iluminaci´ on por v´ ertices de forma an´ aloga a la versi´ on 1.0 de la API. Figura 4.7: Prueba de funcionamiento del modelo ship de OSG con los efectos de part´ ıculas. Los modelos de prueba a representar est´ an divididos en dos grupos. Tenemos un conjunto de modelos b´ asicos de bajo detalle poligonal y uno de modelos de alta resoluci´ on poligonal. La tabla 4.1 tiene las caracter´ ısticas de las escenas a representar. El conjunto de modelos de baja resoluci´ on proviene de los modelos que se usan en las aplicaciones de prueba de OSG que emplean una serie de caracter´ ısticas usadas de forma habitual. El conjunto de modelos de alta resoluci´ on est´ a formado por los modelos generados con medici´ on l´ aser de Standford. El prop´ osito de los tests de baja resoluci´ on es probar caracter´ ısticas generales de funcionamiento y en el caso de los tests de alta resoluci´ on probar el rendimiento puro sin optimizaciones. En la ilustraci´ on 4.7 se puede observar el renderizado tridimensional de un modelos (ship.osg) con un efecto de part´ ıculas en sus motores. 4.3.4. Prototipos de representaci ´ on tridimensional de terreno Para comprobar las posibilidades de su uso en el campo GIS y en aplicaciones comerciales, se han realizado tres prototipos funcionales. Los dos primeros, se basan en la representaci´ on de terrenos que han sido generados de forma est´ atica y el tercero en
4.3 Creaci´ on de las aplicaciones de Test 89 Baja resoluci´ on T´ ecnicas Alta resoluci´ on N´ umero de pol´ ıgonos Cow Environmental Mapping Bunny 69.451 Cessna Modelo comprimido Horse 96.966 Cessna Fire Part´ ıculas Hand 654.666 Dumptruck Modelo en red Dragon 871.414 Fountain Part´ ıculas Happy 1.087.716 Lz Nodos de Terreno, Billboards Morphing Morphing Tabla 4.1: Listado de los diferentes modelos de prueba y sus caracter´ ısticas rese˜ nables. la generaci´ on de geometr´ ıa tridimensional en tiempo de dibujado mediante el empleo de programas shader. Los prototipos de representaci´ on con terrenos pregenerados, representan dos casos habituales de uso en el marco de aplicaciones. Por un lado, tenemos una representaci´ on de terreno gruesa a nivel planetario; el programa trabaja sobre una base de datos que contiene todo el planeta tierra. Ha sido generada mediante Virtual Planet Builder (VPB) de forma esf´ erica con una profundidad de 8 niveles de detalle y un tama˜ no de 5Gbytes. Para su generaci´ on se han empleado las im´ agenes ortogr´ aficas, ”Blue Marble“ de la NASA y el mapa de alturas global Lansat con precisi´ on de 5km/p´ ıxel. El segundo ejemplo busca representar una secci´ on menor de terreno de alta calidad. El ejemplo representa una zona planar limitada entre los t´ erminos de Anna y Enguera situada en la parte septentrional del Macizo del Caroig. La base de datos ha sido generada con siete niveles de detalle y un tama˜ no de 256Mbytes. Los datos empleados para su elaboraci´ on han sido obtenidos del Plan Nacional de Ortograf´ ıa (PNOA). Estos prototipos han sido generados empleando la versi´ on 1.x de OpenGL ES debido a que la pregeneraci´ on de la escena no incluye los shaders para representar el terreno por lo que deber´ ıamos modificar el grafo de escena cada vez que un elemento fuese a˜ nadido al grafo de escena. El prototipo de representaci´ on de terrenos con geometr´ ıa generado en tiempo real, representa una secci´ on detallada de terreno. Los datos de esta representaci´ on forman parte de los archivos LSAS de Standford y representan la zona del Gran Ca˜ n´ on en los Estados Unidos de Am´ erica. En este prototipo se comprueban los diferentes rendimientos seg´ un el tipo de t´ ecnica que se emplea para generar la geometr´ ıa. M´ as espec´ ıficamente, se han comprobado las diferencias de rendimiento el uso, o no, de VertexBufferObjects, un modelo de transmisi´ on de datos a la tarjeta gr´ afica de alto
96 Desarrollo Redirecci´ on de la salida est´ andar de errores hacia el Logcat de Android.
5 Resultados En este apartado, se detallar´ an los resultados de los estudios realizados sobre la portabilizaci´ on de la librar´ ıa al sistema operativo Android. En primer lugar se detallar´ an las condiciones de las pruebas y, seguidamente, se expondr´ an los resultados de los test de funcionamiento. 5.1. Caracter´ısticas de los dispositivos de pruebas Durante este estudio, se han empleado tres modelos f´ ısicos diferentes para obtener unos datos fiables. Los modelos empleados en este estudio son: HTC Nexus Archos 70i tablet Samsung Galaxy S I-9000 En la tabla 5.1 se encuentran detallas las caracter´ ısticas de procesador, resoluci´ on y memoria de los diferentes dispositivos. La versi´ on del sistema operativo empleada durante las pruebas siguientes es la versi´ on 2.2, debido a su mayor estabilidad en comparaci´ on con la versi´ on 2.1. Aunque durante el transcurso de este proyecto se ha comprobado el funcionamiento por 97
98 Resultados Modelo HTC Samsung Galaxy S I-9000 Archos 70i Tablet Procesador Qualcomm QSD8250 1Ghz ARM Cortex-A8 1Ghz ARM Cortex-A8 Adreno 200 PowerVR SGX540 Resoluci´ on 480x800 480x800 800x480 Memoria 512Mbytes 512Mbytes 256Mbytes Tabla 5.1: Caracter´ ısticas t´ ecnicas de los dispositivos publicadas por sus empresas una serie de voluntarios de la comunidad OSG en diferentes modelos y versiones, los resultados aqu´ ı presentados son ´ unicamente de los dispositivos con los que se ha podido trabajar directamente. De acuerdo a las pruebas realizados por los usuarios de la comunidad OSG, se puede afirmar que la compatibilizaci´ on funciona correctamente con las versiones 2.3 y 3.1 con lo cual, se puede afirmar que la soluci´ on presentada en este trabajo ha alcanzado un nivel aceptable de funcionamiento de cara al desarrollo de futuras aplicaciones. 5.2. Resultados modelos de baja resoluci´ on Los tests de funcionamiento son una muestra de control de varias t´ ecnicas empleadas de forma com´ un en los gr´ aficos. Las t´ ecnicas que han funcionado correctamente empleando la API OpenGL ES 1.0 son las siguientes: Carga de ficheros comprimidos Part´ ıculas (ilustraci´ on: 5.1) Carga de ficheros en red Nodos Terrain Billboards Morphing
5.2 Resultados modelos de baja resoluci´ on 99 La caracter´ ıstica: “Environmental Mapping” no ha funcionado correctamente. Esto es debido a que no se encuentra soportada en OpenGL ES como una caracter´ ıstica principal de la API, est´ a soportada como una extensi´ on opcional y todav´ ıa no ha sido integrada, en esta forma, en la librer´ ıa OSG. Figura 5.1: Aplicaci´ on OSG sobre Android representando el modelo “cessnafire.osg” que emplea un fuego generado con la t´ ecnica de part´ ıculas. El rendimiento empleando la API 1.0 se puede ver en la tabla: ??. La tasa de frames por segundo es aceptable para la mayor parte de casos. ´ Unicamente se ve un repunte negativo en la t´ ecnica de morphing, debido a la cantidad de c´ alculos en coma flotante que requiere. Se puede notar tambi´ en como, debido limitaciones impuestas por el driver, el m´ ovil Samsung nunca supera un umbral de frames por segundo, esto es algo habitual para reducir el consumo de bater´ ıa en estos dispositivos. En el caso de la API OpenGL ES 2.0, hay que recordar que la situaci´ on cambia debido al uso de Shaders. La librer´ ıa OSG emplea un generador de Shaders para emular la tuber´ ıa de renderizado fijo, sin embargo, los shaders pregenerados provocan un error de compilaci´ on en un dispositivo real a pesar de cumplir el est´ andar GLSL. Esto se debe a que, en OpenGL ES 2.0, existe una modificaci´ on al est´ andar que no est´ a reflejada en la especificaci´ on GLSL. En el libro [GSM08] se comenta este cambio que obliga, por norma, a emplear un valor de precisi´ on para toda variable uniforme de un pro-
100 Resultados Modelo HTC Samsung Galaxy S I-9000 Archos Cow 20.3 fps 52.8 fps 64.8 fps Cessna 4.3 fps 53.0 fps 59.7 fps Cessna Fire 20.2 fps 53.5 fps 53.8 fps Dumptruck 3.9 fps 55.3 fps 68.0 fps Fountain 45.8 fps 53.7 fps 40.0 fps Lz 42.2 fps 51.0 fps 62.9 fps Morphing 4.9 fps 20.9 fps 17.6 fps Tabla 5.2: Estad´ ısticas de frames por segundo de los modelos testeados sobre Android con OpenGL ES 1.0 grama shader. Actualmente los shaders pregenerados no incluyen esta caracter´ ıstica y por ello no pueden ser utilizados. Aun as´ ı, es posible emplear OSG de forma normal siempre que el programador genere sus propios shaders de forma correcta y no dependa de los autogenerados por OSG.En la figura: 5.2 vemos el resultado de emplear un shader Cartoon sobre el modelo de la vaca de OSG. Como se puede ver se realiza el dibujado correctamente empleando las instrucciones del shader. Figura 5.2: Aplicaci´ on OSG sobre android representando el modelo “cow.osg” sobre OpenGL ES 2.0 empleando un shader de tipo Cartoon.
5.3 Resultados modelos de alta resoluci´ on 101 En la tabla: 5.2 se encuentran las estad´ ısticas de frames por segundo de esta prueba, Si los comparamos con los resultados de la tabla: 5.3, el rendimiento alcanzado en ambos casos es similar. Modelo HTC Samsung Galaxy S I-9000 Archos Cow 21.3 fps 53.8 fps 65.5 fps Cessna 4.7 fps 54.0 fps 60.5 fps Cessna Fire 18.6 fps 53.5 fps 54.7 fps Dumptruck 4.7 fps 55.3 fps 67.1 fps Fountain 47.3 fps 53.7 fps 41.0 fps Lz 48.3 fps 53.7 fps 72.7 fps Morphing 5.0 fps 21.1 fps 16.8 fps Tabla 5.3: Estad´ ısticas de frames por segundo de los modelos b´ asicos sobre Android con OpenGL ES 2.0 5.3. Resultados modelos de alta resoluci´ on Ha resultado imposible hacer un estudio de rendimiento con la versi´ on 1.X de OpenGL ES. La representaci´ on de modelos con una geometr´ ıa monol´ ıtica sin el uso de VertexBufferObjects(VBO) ´ unicamente ha llegado a funcionar con el modelo de alta resoluci´ on m´ as peque˜ no, ”Bunny“. La tasa de frames obtenida se presenta en la tabla: 5.4. Como se puede ver, el HTC ha sido incapaz de ejecutarlo lanzando una excepci´ on del driver gr´ afico. La tableta Archos y el m´ ovil Samsung han sido capaces de representarlo con una tasa excepcionalmente baja y el resto de modelos han provocado, de la misma manera una excepci´ on en los driver gr´ aficos de ambos. Modelo HTC Nexus Archos 70i Samsung Galaxy S I-9000 Bunny Error driver 2fps 3fps Tabla 5.4: Tasa de frames por segundo de los modelos de alta resoluci´ on sobre OpenGL ES 1.X
102 Resultados Figura 5.3: Aplicaci´ on OSG en Androi representando el modelo de alta resoluci´ on “El Budha feliz”, que est´ a formado por m´ as de un mill´ on de pol´ ıgonos, de forma monol´ ıtica sin optimizaciones. La prueba realizada sobre OpenGL ES 2.0 ha obtenido unos mejores resultados. Se han conseguido representar todos los modelos. Esto supone en el caso del modelo ”Budha feliz“ la ocupaci´ on de 40Mbytes de memoria, una ocupaci´ on muy alta de memoria que, en muchos modelos, situar´ ıa a la aplicaci´ on en el borde de ser cerrada por el sistema operativo por consumo excesivo de memoria. Aun as´ ı, como se puede ver en la figura: 5.3 es posible mover un modelo monol´ ıtico, sin optimizaciones geom´ etricas o de nivel de detalle, que supera el mill´ on de pol´ ıgonos empleando ´ unicamente la potencia pura de los dispositivos actuales. Sin embargo, como se puede observar en la tabla: 5.5 el rendimiento resultante todav´ ıa es muy bajo, por ello es aconsejable el uso de las optimizaciones y particiones geom´ etricas para obtener una tasa de dibujado buena en las escenas complejas.
5.4 Resultados de la representaci´ on de terrenos precalculada 103 Modelo HTC Samsung Galaxy S I-9000 Archos Bunny 12.1 fps 34.7 fps 16.7 fps Horse 6.9 fps 19.5 fps 11.4 fps Hand 1.5 fps 9.5 fps 7.7 fps Dragon 1.0 fps 11.7 fps 7.1 fps Happy 0.7 fps 8.7 fps 6.7 fps Tabla 5.5: Estad´ ısticas de frames por segundo de los modelos de alta resoluci´ on sobre Android con OpenGL ES 2.0 5.4. Resultados de la representaci´ on de terrenos precalculada Los test sobre terrenos, empleando bases de datos pregeneradas, han resultado contundentes. Cuando no emple´ abamos el regulador de memoria, los programas de prueba aumentaban r´ apidamente su consumo de memoria hasta llegar a los l´ ımites que ofrec´ ıan los dispositivos. Esto obligaba al sistema operativo a cerrarlas por consumo excesivo de memoria aunque las escenas empleaban los nodos PagedLod para realizar las cargas de secciones por demanda, el consumo de memoria crec´ ıa exponencialmente. Para solucionar este problema se hab´ ıa creado un regulador de la carga del grafo de escena. El regulador permite configurarse con una serie de par´ ametros de funcionamiento. Per´ ıodo de muestreo de la memoria, tama˜ no m´ aximo de nodo y los l´ ımites superior inferior de la ocupaci´ on deseada. Esto permite escalar la optimizaci´ on seg´ un el modelo exacto que lo ejecuta. Par´ ametro Valor Per´ ıodo de muestreo de memoria 5 fps Tama˜ no m´ aximo de nodo 0.5 Mbytes Ocupaci´ on m´ ınima 20 Mbytes Ocupaci´ on m´ axima 30 Mbytes Tabla 5.6: Par´ ametros del regulador de nodos para terrenos pregenerados.
104 Resultados Figura 5.4: Imagen del programa de representaci´ on de terrenos pregenerados. En la imagen se puede ver una imagen a distancia de la tierra mientras se representan las estad´ ısticas de la aplicaci´ on Para emplear el regulador, se han fijado los par´ ametros tal y como se muestran en la tabla: 5.6. Los resultados en el funcionamiento y la estabilidad del programa han sido satisfactorios y no se ha generado ning´ un error por falta de memoria durante los vuelos de prueba. En la figura: 5.4 se puede ver representado el consumo de memoria durante un vuelo de un minuto en el programa de representaci´ on de terreno planetario. Como se puede observar, cuando el punto de vista se acerca lo suficiente y expande los nodos descendientes, se produce un repunte de uso de memoria por la carga de nuevos nodos a representar y la no eliminaci´ on de los padre que no se representan en ese momento. Esta explosi´ on en el gasto de memoria termina sobrepasando el l´ ımite superior fijado durante la prueba, esto hace que reaccione el regulador de memoria y reajuste las distancias de visualizaci´ on de cada nodo Lod. Esto obliga al grafo de escena a revisar el nuevo estado de la escena y eliminar aquellos nodos que no se emplean en el dibujado y no tienen descendientes liberando, en este proceso, memoria ocupada. Como consecuencia de este m´ etodo, la expansi´on de nodos ser´a m´as profunda en la zona cercana al punto de visi´on del usuario, dejando el resto de zonas con un menor nivel de detalle. Como se puede ver en la tabla: 5.7 el rendimiento del programa con un terreno reducido de alta calidad es superior al programa con un terreno de grandes dimensiones y baja calidad. A´ un as´ ı, el rendimiento en ambos es aceptable para llegar a funcionar
5.4 Resultados de la representaci´ on de terrenos precalculada 105 Figura 5.5: Estad´ ısticas de consumo de memoria de nuestro programa con base de datos pregenerada. Las gr´ afica muestra la variaci´ on de la ocupaci´ on durante un minuto. en tiempo interactivo, aunque con el modelo HTC se puede ver que el rendimiento termina siendo bajo. La imagen: 5.4 ha sido capturada sobre el programa que representa el modelo del planeta tierra. La imagen: 5.6 viene del programa que representa el ´ area cercana al pueblo Anna, situado en La canal de Navarr´ es. Par´ ametro HTC Samsung Galaxy S I-9000 Archos Modelo planetario tierra 8fps 35.2fps 17.3fps Secci´ on terreno Anna 12fps 42.4fps 23.7fps Tabla 5.7: Estad´ ısticas de los ejemplos de representaci´ on de terrenos.
112 Conclusiones y trabajo futuro han implementado una serie de funciones y macros en CMake que permiten generar los archivos de compilaci´ on NDK Android desde los scripts CMake originales. Estos cambios sobre los ficheros CMake tambi´ en han sido integrados en la rama principal de desarrollo. OSG es una librer´ ıa que, opcionalmente, depende de una serie de librer´ ıas de terceros para gestionar la apertura y el guardado de determinados tipos de fichero. Para poder probar todas las funcionalidades, se ha realizado la compatibilizaci´ on de una serie de librer´ ıas b´ asicas (libJpeg, libPng, libtiff, Freetype, Curl, Gdal, etc) creando, con ello, un paquete de librer´ ıas externas para emplear en Android que ha sido publicado en la p´ agina de la librer´ ıa OSG. Finalmente se han presentado una serie de programas de prueba, as´ ı como su estructura, que permiten comprobar las distintas caracter´ ısticas del grafo de escena. Estos programas han servido para estudiar las posibilidades de optimizaci´ on y escalado de escenas empleando OSG. Tambi´ en se ha presentado un algoritmo de balanceado del grafo de escena. Este algoritmo carga y descarga nodos dependiendo de la ocupaci´ on actual de la memoria por parte del programa. De acuerdo a los datos obtenidos en los resultados, todas las caracter´ ısticas soportadas por la API funcionan correctamente. Las ´ unicas que no est´ an disponibles son aquellas que no est´ an soportadas actualmente en las API de OpenGL ES. Las pruebas de representaci´ on de terreno, muestran la idoneidad de emplear OSG para optimizar y escalar la representaci´ on de la escena dentro de los l´ ımites de nuestra plataforma objetivo. Adicionalmente, se ha presentado a la comunidad OSG una serie de aplicaciones Android que sirven de ejemplo para integrar OSG en el desarrollo de una aplicaci´ on, as´ ı como la documentaci´ on oportuna para realizar una compilaci´ on de OSG para Android. Las l´ ıneas de trabajo futuro pasan por mejorar la integraci´ on de OSG con la plataforma Android. Oficialmente, en la ´ ultima versi´ on todav´ ıa no existe una implementaci´ on din´ amica de la librer´ ıa STL est´ andar. Esto supone un coste espacial prohibitivo, cada componente de OSG tendr´ ıa que contener parte de la STL y muchas partes de c´ odigo quedar´ ıan replicadas dentro de la librer´ ıa con el incremento de tama˜ no que supondr´ ıa para los ejecutables. Es necesario tambi´ en incluir un sistema de carga de librer´ ıas din´ amicas siguiendo los est´ andares de Android. A diferencia de Linux, la instalaci´ on de las librer´ ıas no se
Conclusiones y trabajo futuro 113 realiza sobre el sistema. Dado que algunas librer´ ıas basadas en OSG no permiten la compilaci´ on est´ atica, avanzar en esta l´ ınea de trabajo supondr´ ıa una mejora importante. Otra vertiente de trabajo pasa por modificar algunas partes de c´ odigo de la librer´ ıa OSG para permitir la representaci´ on de algunos elementos gr´ aficos sin emplear la tuber´ ıa fija. Al contrario que las versiones de sobremesa de la API gr´ afica, las versiones para dispositivos embebidos o tienen tuber´ ıa fija o tienen tuber´ ıa programable. Por ejemplo, ser´ ıa muy interesante trabajar en la representaci´ on de las estad´ ısticas OSG. Aunque las estad´ ısticas se pueden obtener mediante llamadas de c´ odigo, no se pueden representar como si ocurre cuando se puede emplear la tuber´ ıa fija. Un punto que se ha quedado sin desarrollar en este trabajo ha sido la programaci´ on de Actividades totalmente nativas mediante la “NativeActivity”. Aunque en el trabajo se ha incluido una estructura te´ orica de aplicaci´ on y se han comentado las posibilidades que ofrecen, no se ha publicado ninguno de los ejemplos, ya que no se ha podido disponer de un dispositivo compatible para las pruebas de funcionamiento. Finalmente, entrando en la representaci´ on de terreno, este proyecto solo ha cubierto una parte muy reducida y que deber´ ıa ser ampliada estudiando m´ as en profundidad la representaci´ on de terrenos con las nuevas capacidades de estos dispositivos. En esta tesitura ser´ ıa interesante estudiar la implementaci´ on de librer´ ıas basadas en OSG que se est´ an empleando actualmente en aplicaciones GIS como osgVP y osgEarth.
114 Conclusiones y trabajo futuro
7 Agradecimientos Deseo agradecer a mi director de proyecto, Javier Lluch, por haber hecho posible este trabajo. Tambi´ en he de agradecer especialmente a mi codirector de proyecto, Jordi Torres, que me ha ayudado continuamente a centrar los objetivos de este proyecto. Quiero hacer una menci´ on especial a Rafa Gait´ an cuya ayuda y conocimientos sobre la librer´ ıa OSG han sido muy importantes para agilizar algunas partes de este proyecto. Por otra parte quiero agradecer a mis compa˜ neros del Instituto AI2. Durante nueve meses se han convertido en un entorno familiar y profesional donde he podido trabajar y aprender junto a un grupo de trabajo con una gran cantidad de desarrollos a sus espaldas. Especialmente quiero agradecer la compa˜ n´ ıa, los consejos y las risas de Leo Salom, Mar´ ıa Ten y Jes´ us Zarzoso. Tambi´ en quiero dar las gracias a mi familia que me han apoyado durante todo el trayecto de mi educaci´ on y en especial la figura de mi padre que ha tenido que soportar y corregir las repetidas lecturas de este trabajo. Finalmente quiero dar las gracias a Isabel Mar´ ıa Graci´ an, mi compa˜ nera de vida y mi correctora particular. 115
116 Agradecimientos
Bibliograf´ıa [AMHH08] Tomas Akenine-M¨ oller, Eric Haines, and Natty Hoffman. Real-Time Rendering 3rd Edition. A. K. Peters, Ltd., Natick, MA, USA, 2008. [Biz10] Andrea Bizzotto. Touchscreen-Based Used Interaction, 2010. [Cam06] Javier Lluch Rafa Gait´ an Miguel Escriv´ a Emilio Camahort. Multiresolution 3d rendering on mobile devices. 2006. [Cas07] Ignacio Casta˜ no. High Quality DXT Compression using CUDA, 2007. [Cat10] Ken Catterall. Migration to OpenGL ES 2.0, 2010. [CG02] Chun-Fa Chang and Shyh-Haur Ger. Enhancing 3d graphics on mobile devices by image-based rendering. In IEEE Third Pacific-Rim Conference on Multimedia (PCM 2002), 2002. [DD04] Florent Duguet and George Drettakis. Flexible point-based rendering on mobile devices. IEEE Computer Graphics and Applications, pages 57–63, July/August 2004. [Don05] William Donnelly. Per-Pixel Displacement Mapping with Distance Functions, 2005. [Dub11] Patrick Dubroy. Google IO 2011 conference: Memory Management for Android Apps, 2011. [ESC00] Jihad El-Sana and Yi-Jen Chiang. External memory view-dependent simplification. In EuroGraphics ’2000, volume 19, 2000. [For11] James Forshaw. Webgl - a new dimension for browser exploitation. Technical report, Context, 2011. 117
118 BIBLIOGRAF´ IA [FSJ11] James Forshaw, Paul Stone, and Michael Jordon. Webgl – more webgl security flaws. Technical report, Context, 2011. [Gal11] Dan Galpin. Google IO 2011 conference: Bringing C and C++ Games to Android, 2011. [GBO09] Mikael Gustavsson, Kristof Beets, and Erik Olsson. Optimizing Your first OpenGL ES Application, 2009. [goo10] Google IO 2010http://www.google.com/events/io/2010, 2010. [goo11a] Google - http://developer.android.com/ndk, 2011. [goo11b] Google - http://developer.android.com/sdk, 2011. [goo11c] Google IO 2011http://www.google.com/events/io/2011, 2011. [goo11d] Google Stadistics - http://developer.android.com/resources/dashboard/platformversions.html, 2011. [GSM08] Dan Ginsburg, Dave Shreiner, and Aaftab Munshi. OpenGL ES 2.0 Programming Guide, 2008. [HW09] Bin HU and Jingnong WENG. Component-based virtual globe visualization engine design. Computational Intelligence and Software Engineering, 2009. [Ima92] Imagination Technologies, http://www.imgtec.com/powervr/powervrtechnology.asp. PowerVR, 1992. [Khr92] Khronos Group, http://www.khronos.org/opengl/. OpenGL ES - The Industry’s Foundation for High Performance Graphics, 1992. [Khr04] Khronos Group, http://www.khronos.org/opengles/. OpenGL ES - The Standard for Embedded Accelerated 3D Graphics, 2004. [Kry05] Yury Kryarchko. Using Vertex Texture Displacement for Realistic Water Rendering, 2005. [Ler04] Pierre Leroy. Pocket GL, 3D library for Pocket PC. http://pierrel5.free.fr/, 2004. [LGCV05] Javier Lluch, Rafael Gait´ an, Emilio Camahort, and Roberto Viv´ o. Interactive three-dimensional rendering on mobile computer devices. In ACE
BIBLIOGRAF´ IA 119 ’05: Proceedings of the 2005 ACM SIGCHI International Conference on Advances in computer entertainment technology, pages 254–257, New York, NY, USA, 2005. ACM. [Mic92] Microsoft, http://msdn.microsoft.com/en-us/directx/. DirectX, 1992. [Mik10] Morten S. Mikkelsen. Bump Mapping Unparametrized Surfaces on the GPU, 2010. [Nvi] Nvidia: http://developer.nvidia.com/gpu-accelerated-texturecompression. GPU Accelerated Texture Compression. [OSG] OSG Community: http://www.openscenegraph.org. OpenSceneGraph. Open Source high performance 3D graphics toolkit. [SP09] Marjan Sterk and Mariano Agust´ ın Cecowski Palacio. Virtual globe on the android – remote vs. local rendering. Sixth International Conference on Information Technology: New Generations, 2009. [SZL02] Andrea Sanna, Claudio Zunino, and Fabrizio Lamberti. A distributed architecture for searching, retrieving and visualizing complex 3d models on personal digital assistants. Internet Technology, 3(4):235–244, 2002. [USK06] Tam´ as Umenhoffer and L´ aszl´ o Szirmay-Kalos. Displacement Mapping on the GPU - State of the Art, 2006.