documento final de tesis entrega final de ciclo terminal

93
Documento Final de Tesis Entrega Final de Ciclo Terminal II OpenGL en Dispositivos Móviles Presentado por: Carlos Eduardo Oviedo Presentado a: Harold Cruz Facultad de Ingeniería Departamento de Sistemas y Computación Universidad de los Andes Bogotá, Febrero 04 de 2005

Upload: others

Post on 19-Jul-2022

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Documento Final de Tesis Entrega Final de Ciclo Terminal

Documento Final de Tesis

Entrega Final de Ciclo Terminal II

OpenGL en Dispositivos Móviles

Presentado por: Carlos Eduardo Oviedo

Presentado a: Harold Cruz

Facultad de Ingeniería Departamento de Sistemas y Computación

Universidad de los Andes

Bogotá, Febrero 04 de 2005

Page 2: Documento Final de Tesis Entrega Final de Ciclo Terminal

AGRADECIMIENTOS

Harold Cruz Ingeniería de Sistemas, Universidad de los Andes. Director de tesis.

A la mi director de tesis por su apoyo incondicional y la oportunidad brindada para la realización de este trabajo.

Page 3: Documento Final de Tesis Entrega Final de Ciclo Terminal

LISTA DE FIGURAS

Pág.

Figura 1. Rotación en 2 dimensiones (pivote en el origen) 26

Figura 2. Rotación en 2 dimensiones (pivote arbitrario) 27

Figura 3. Proyección en paralela 34

Figura 4. Proyección en perspectiva 35

Figura 5. Instalación SuperWaba en POSE (Pantalla 1) 39

Figura 6. Instalación SuperWaba en POSE (Pantalla 2) 39 Figura 7. Instalación SuperWaba en POSE (Pantalla 3) 39

Figura 8. Instalación de aplicaciones en POSE 40

Figura 9. Instalación SuperWaba en PC 42 Figura 10. GuiBuilder Instalado (Pantalla 1) 46

Figura 11. GuiBuilder Instalado (Pantalla 2) 46

Figura 12. Deshabilitando opciones POSE 48

Figura 13. Estructura de directorios del Proyecto 53

Figura 14. Diagrama de Paquetes 61

Figura 15. Diagrama del paquete GL 62

Figura 16. Diagrama del paquete SYS 64

Figura 17. Diagrama del paquete UTIL 66

Figura 18. Diagrama del paquete TESTS 68

Figura 19-21. Instalación MobileGL sobre POSE 71

Figura 22. Modelo Jerárquico 72

Figura 23. Imagen del Robot 73

Figura 24. Estructura de directorios del proyecto 74

Figura 25. Diagrama de clases Caso de Estudio 79

Figura 26. Instalación MobileGL (Pantalla 1) 81

Figura 27. Instalación MobileGL (Pantalla 2) 81

Figura 28-32. Demo MobileGL 82

Figura 33. Demo MobileGL con OpenGL 83

Page 4: Documento Final de Tesis Entrega Final de Ciclo Terminal

1

Tabla de contenido

I. Introducción 3

II. Objetivo 5

III. Alcance 6

IV. Estado del Arte 8

1. MiniGL 8

2. TinyGL 9

3. Pocket GL 10

4. OpenGL ES 10

V. Marco Teórico 11

1. OpenGL 11

1.1. Estructura de un Programa en OpenGL 12

1.2. Sintaxis de los Comandos/Constantes OpenGL 12

1.3. OpenGL como una Máquina de Estados 14

1.4. Animación en OpenGL 18

1.5. Operaciones Básicas de OpenGL 18

1.6. Transformaciones en OpenGL 21

2. Conceptos Gráficos 24

2.1. Traslación 25

2.2. Rotación 26

2.3. Escalamiento 28

2.4. Representación de Matriz y Coordenadas Homogéneas 29

2.5. Transformaciones Geométricas Tridimensionales 31

2.6. Métodos de Despliegue Tridimensional 33

3. SuperWaba 37

3.1. Instalación en Dispositivos Palm OS 38

3.2. Instalación en Windows CE/Pocket PC 40

3.3. Instalación en Computadores de Escritorio 42

Page 5: Documento Final de Tesis Entrega Final de Ciclo Terminal

2

3.4. Prueba de Instalación de SuperWaba 44

3.5. Desarrollo de una Aplicación en SuperWaba 46

3.6. Warp y ExeGen 48

3.7. IDEs y SuperWaba 50

VI. MobileGL 52

1. Estructura de Directorios del Proyecto 52

2. Funciones Implementadas 54

3. Diagrama de Clases de la Librería 61

3.1. Diagrama de Paquetes 61

3.2. Diagrama del Paquete GL 62

3.3. Diagrama del Paquete SYS 64

3.4. Diagrama del Paquete UTIL 65

3.5. Diagrama del Paquete TESTS 67

4. Compilación y Ejecución 69

5. Instalación 70

VII. Caso de Estudio 72

1. Descripción del Modelo Jerárquico a Implementar 72

2. Estructura de directorios del Caso de Estudio 74

3. Funciones Implementadas 75

4. Diagrama de Clases del Caso de Estudio 78

5. Compilación y Ejecución 80

6. Instalación 81

VIII. A Futuro 84

IX. Conclusiones 86

X. Glosario 87

XI. Referencias 88

Page 6: Documento Final de Tesis Entrega Final de Ciclo Terminal

3

I. Introducción

Son doce años los que consolidan OpenGL como el ambiente de preferencia para el desarrollo de aplicaciones gráficas en dos y tres dimensiones. Pero OpenGL es más que un ambiente de desarrollo; es una interfaz de programación de aplicaciones (API por sus siglas en inglés) adoptada actualmente por la mayoría de la industria. Las facilidades que ofrece para el desarrollo de aplicaciones altamente portables convierten a OpenGL en una especificación irresistible de implementar tanto para fabricantes de hardware como para desarrolladores de software. Pero las ventajas que ofrece OpenGL son muchas además de la anteriormente presentada; para los desarrolladores, un conjunto extenso de complejas funciones de visualización agilizan la labor de construcción del software, facilitando la codificación de un gran número de tareas. Esto a su vez reduce el tiempo que tarda el producto en entrar al mercado, lo que beneficia de igual manera al usuario final. El usuario también se ve beneficiado al recibir un software con gráficos más reales e interfaces de usuario más amigables y completas. Tal vez una de las limitantes más graves que tiene OpenGL es la dependencia a un hardware especial que soporte muchas de las funciones que ofrece. A pesar de que este tipo de hardware es incorporado desde varios años ya a los equipos tradicionales y que usualmente manejamos (computadores de escritorio para ser más precisos), hay una nueva generación de dispositivos que progresivamente se han ido apoderando del mercado y que no poseen el hardware necesario para tomar ventaja de las facilidades que ofrece OpenGL. Los beneficios recibidos por los usuarios desde la aparición de la tecnología móvil son incontables; comunicación prácticamente ilimitada entre usuarios de la tecnología, información cada vez más disponible (sin importar el lugar de ubicación de la persona), y la facilidad que ofrecen estos dispositivos para el desarrollo de tareas que normalmente se realizan en equipos ligados a un escritorio son algunos de ellos. Pero estos dispositivos móviles están lejos de ser perfectos; una menor capacidad de procesamiento de información, menor cantidad de memoria disponible y menor resolución de pantalla son algunas de las falencias que hacen casi imposible que estos equipos ofrezcan la misma calidad de gráficos que los dispositivos de escritorio. Lo que se propone en el presente trabajo es la integración de dos elementos altamente útiles y populares para lograr un producto novedoso y de alta calidad; la llegada de OpenGL al mundo móvil abrirá las puertas a una nueva generación de aplicaciones compatibles con este tipo de dispositivos. La

Page 7: Documento Final de Tesis Entrega Final de Ciclo Terminal

4

utilidad que alcanzarían estos equipos sería inmensamente superior a la que actualmente poseen, así como la productividad de las personas que hacen uso de los mismos. En secciones siguientes se analizarán algunas alternativas consideradas para el desarrollo del proyecto, presentando posteriormente aquella que ofrece los mayores beneficios. Se presentarán las herramientas utilizadas y una descripción detallada del procesó seguido. Se concluirá con el listado de resultados obtenidos y conclusiones del trabajo.

Page 8: Documento Final de Tesis Entrega Final de Ciclo Terminal

5

II. Objetivo

El objetivo principal de este trabajo es la integración de OpenGL al mundo móvil, particularmente a las asistentes personales digitales o PDA (por sus siglas en inglés). Es claro que el hardware de este tipo de equipos es ciento por ciento diferente a aquel presente en un computador de escritorio, por lo que la manera a seguir para lograr el objetivo es a través de software; siendo OpenGL una interfaz de software para un hardware de gráficas, el trabajo propuesto en este documento tiende a seguir el mismo lineamiento. La librería gráfica móvil propuesta consta de una serie de interfaces, diferenciándose de OpenGL en que estas interfaces trabajan sobre una capa de software, no hardware. El software sobre el cuál trabajan estas interfaces es conocido como SuperWaba, y brevemente puede ser reducido como una máquina virtual (similar a las máquinas virtuales para Java) dirigida principalmente a dispositivos móviles de tipo PDA. Hay que hacer la salvedad de que es posible instalar SuperWaba en un computador de escritorio, pero esto se debe ver solo como una manera de facilitar el desarrollo y depuración de aplicaciones móviles basadas en este software. Tanto OpenGL como SuperWaba tienen una sección dentro del documento dedicada exclusivamente a su profundización y detalle, ya que ambas juegan un papel fundamental en la elaboración del presente trabajo. Es necesario entender como funciona OpenGL debido a que la librería gráfica móvil trata de simular en lo posible tanto las funciones que ofrece como su modo de operar. Por su parte, sin unas buenas bases en SuperWaba difícilmente se podrá apreciar en su plenitud el trabajo presentado a continuación.

Page 9: Documento Final de Tesis Entrega Final de Ciclo Terminal

6

III. Alcance

El extenso número de funciones y operaciones permitidas por OpenGL es proporcional al grado de complejidad del proyecto. El ideal sin ninguna duda sería el de migrar toda la interfaz a los dispositivos móviles, algo que se podría conseguir si se contara con varios años de trabajo y un número mayor de personas involucradas en el proyecto. Desafortunadamente este no es el caso del presente trabajo, por lo que es de suma necesidad el acotar el alcance del mismo para asegurar que su desenlace arroje unos resultados concretos y satisfactorios. La metodología de desarrollo más apropiada para un tipo de proyecto como el que se especifica en el presente documento es la de desarrollo por etapas o desarrollo en espiral; es una técnica común en el mundo de la ingeniería de software y consiste en dividir el proyecto en varias fases, cada una con unos objetivos claros y concretos. Después de cada fase se realizan las pruebas necesarias y se elabora un postmortem que describe el proceso de desarrollo durante la fase, detallando aquellas tareas exitosas y puntualizando en los errores que pudieron haber impedido la obtención de todos los objetivos pactados para la etapa. Para este proyecto el gran objetivo es el desarrollo de una librería gráfica móvil que simule en su totalidad a OpenGL (tanto en funciones ofrecidas como en su modo de operar). Teniendo en cuenta que nada más el número de funciones que ofrece esta interfaz es del orden de 1201, y que la complejidad de la mayoría de estas es bastante elevada, el plan a seguir es el de categorizar las funciones y separar su implementación y migración en distintas etapas de desarrollo. La primera etapa del proyecto es la que se propone desarrollar en el presente trabajo. Las funciones a las que se le ha dado prioridad inicialmente son aquellas que tienen que ver con las transformaciones de modelo-vista. Este es un concepto que será tratado en la sección dedicada a OpenGL, pero que por ahora puede entenderse como un conjunto de operaciones que determinan la ubicación y forma de los objetos que componen la escena. El total de funciones a implementar entonces suman catorce, y son listadas a continuación para dar al lector una breve idea de lo que es OpenGL y lo que será la librería gráfica móvil a implementar:

• glBegin

1 Tomado de: Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html

Page 10: Documento Final de Tesis Entrega Final de Ciclo Terminal

7

• glEnd • glClear • glClearColor • glGetFloatv • glGetError • glVertex3f • glFlush • glColor3f • glPolygonMode • glRotatef • glTranslatef • glPushMatrix • glPopMatrix

La siguiente etapa podría dedicarse a la incorporación de funciones relacionadas con las transformaciones de proyección, estas no son un grupo tan numeroso de operaciones pero la complejidad que implican amerita su separación en otra fase distinta. Esta y las siguientes etapas bien pueden convertirse en tema para futuros trabajos de grado; de esta manera continuamente se estaría robusteciendo la librería, acercándose cada vez al objetivo principal que es el de lograr migrar OpenGL al mundo móvil.

Page 11: Documento Final de Tesis Entrega Final de Ciclo Terminal

8

IV. Estado del Arte

En esta sección se presentará lo que a la fecha existe en cuanto a trabajos relacionados con el área gráfica en dispositivos móviles. Se concentrarán esfuerzos en el detalle de aquellos proyectos directamente orientados al desarrollo de librerías gráficas sobre este tipo de equipos. Vale la pena anotar que el número de proyectos encontrados no es muy grande. El listado de estos es presentado a continuación:

• MiniGL • TinyGL • Pocket GL • OpenGL ES

1. MiniGL Es una librería que pretende llevar OpenGL al mundo móvil, restringiendo su alcance a la plataforma Palm OS. La mayor ventaja de la librería es tal vez el hecho de que es libre y puede ser descargada y utilizada bajo la licencia LGPL (GNU Lesser General Public Licence). miniGL es un proyecto que lleva alrededor de 4 años, y en sus 4 versiones han logrado los siguientes resultados2:

• versión 1.0: provee un conjunto básico de funciones para el dibujo de objetos alambrados utilizando primitivas GL_POLYGON y GL_LINES. Tanto las proyecciones ortográficas como en perspectiva son soportadas.

• versión 2.0: adiciona el soporte a las primitivas GL_TRIANGLES, GL_QUADS y GL_QUAD_STRIP. Además de esto incorporan soporte inicial de fuenes de luz difusa, dobles buffers y el comienzo de soporte a color basado en escalas de grises de cuatro bits.

• versión 3.0: soporte completo de luces (difusa, especular y de ambiente). Incorporan el tipo de sombreado Gouraud. Además de esto empiezan a agregar soporte a z-buffer para poder determinar cuando un polígono oculta o no a otro.

• versión 4.0: separan el código de la librería en un archivo prc.

2 Tomado de: DSBox | miniGL http://www.dsbox.com/minigl.html

Page 12: Documento Final de Tesis Entrega Final de Ciclo Terminal

9

Hasta el momento han implementado un total de 27 funciones. El listado de las mismas puede ser consultado a continuación3:

• glLoadMatrix glBegin • glMultMatrix glEnd • glLoadIdentity glFlush • glClearColor glVertex2f • glClear glVertex3f • glColor3f glShadeModel • glColor4f glRotatef • glOrtho glScalef • glViewport glTranslatef • gluOrtho2D glPopMatrix • gluPerspective glPushMatrix • glEnable glMatrixMode • glDisable glNormal3f • glLightfv

Algunas de las desventajas de la librería son:

• La librería solo ha sido probada bajo el sistema operativo Linux. • Se restringe su uso a la plataforma Palm OS.

2. TinyGL Es una implementación de un subconjunto de funciones OpenGL. Es una implementación 100% software4 (mismo caso para la librería gráfica móvil a desarrollar en este proyecto). Según sus autores es una librería más rápida que OpenGL debido a que no es totalmente compatible con la misma. Las transformaciones y el mapeo de texturas se realizan de una manera un poco diferente. La página web oficial de la librería [16] no es muy clara en cuanto al número de métodos implementados. tinyGL debe tener aproximadamente el mismo tiempo de desarrollo que miniGL, y el número de versiones que han sacado de la misma ha sido 5. Según el log de cambios son dos los autores 3 Tomado de: DSBox | miniGL http://www.dsbox.com/minigl.html 4 Tomado de: TinyGL : a Small, Free and Fast Subset of OpenGL* http://fabrice.bellard. free. fr/TinyGL/

Page 13: Documento Final de Tesis Entrega Final de Ciclo Terminal

10

principales del proyecto. Una de las desventaja es el hecho de que no es muy claro sobre que tipo de dispositivos es capaz de funcionar la librería. 3. Pocket GL Es una librería gráfica en tres dimensiones para C/C++ y que sirve para programar gráficos para dispositivos Pocket PC5. Entre sus características están las siguientes:

• Soporta objetos con texturas o modelos alambrados de los mismos. • Proyección en perspectiva. • Transparencia alfa. • Utiliza matemática de punto fijo para operaciones matriciales y de

vértices. • Soporta luces. • Trabaja con triángulos, cuadriláteros y arreglos de vértices.

La última versión de la librería salió hace poco más de un año y entre las grandes desventajas que presenta es que el acceso a la misma no es gratis. Se puede obtener una versión de demostración que no incluye tutoriales ni código fuente de la librería. 4. OpenGL ES Es un API que permite desarrollar gráficos en dos y tres dimensiones sobre sistemas embebidos (celulares, PDAs y demás dispositivos electrónicos de tamaño reducido). Ofrece un subconjunto de funciones encontradas en la versión OpenGL que se encuentra en los computadores de escritorio. Al igual que OpenGL, OpenGL ES es una especificación mas no una implementación, por lo que es necesario buscar algún producto basado en OpenGL ES y trabajar sobre éste6. Una de las grandes desventajas es el bajo número actual de implementaciones del estándar; la única implementación encontrada hasta el momento es la ofrecida por la compañía Hybrid Graphics7, pero es una versión comercial.

5 Tomado de: Pocket GL (ARM & Mips) on PocketGear.com http://www.pocketgear.com/software_detail.asp?id=1858 6 Tomado de: OpenGL ES Overview http://www.khronos.org/opengles/index.html 7 Tomado de: Hybrid Graphics - OpenGL ES API Framework http://www.hybrid.fi/main/esframework/index.php

Page 14: Documento Final de Tesis Entrega Final de Ciclo Terminal

11

V. Marco Teórico

La presente sección es tal vez una de las más importantes por lo que representa para el proyecto; agrupa las bases y fundamentos que hicieron del mismo una realidad. Es de vital importancia para el lector la comprensión y entendimiento de lo que a continuación se enuncia, ya que de esta manera se garantizarán el mínimo de conceptos requeridos al momento de detallar la librería gráfica móvil desarrollada y expuesta en este trabajo. Si este no es el caso, de seguro no se sacará el mejor provecho a este texto y la comprensión de la librería móvil se hará infinitamente más complicada. En las siguientes secciones se tratarán los siguientes temas:

• OpenGL: es la base de todo el proyecto. El objetivo principal es lograr migrar esta interfaz de hardware al mundo de los dispositivos móviles, restringiendo el conjunto de equipos a las asistentes personales digitales.

• Conceptos Gráficos: conjunto de técnicas y metodologías comunes en el mundo de la computación gráfica. Es necesario conocerlas debido a que son los fundamentos tanto de OpenGL como de la librería gráfica móvil a desarrollar.

• SuperWaba: es la herramienta de desarrollo que apoya todo el proceso de implementación de la librería gráfica móvil. Es importante conocerla en detalle para entender de una mejor manera la forma en que se construyó la librería (en su primera etapa).

Una vez comprendidos los temas anteriormente descritos se procede a detallar la librería gráfica móvil implementada, seguido de la descripción de su respectivo caso de estudio. 1. OpenGL OpenGL es una interfaz en software a un hardware dedicado a gráficos. La interfaz consta de 120 funciones diferentes que pueden ser utilizadas para especificar objetos y operaciones que permitan la elaboración de aplicaciones interactivas en tres dimensiones. Algunas otras características de OpenGL se enuncian a continuación8: 8 Tomado de: Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html

Page 15: Documento Final de Tesis Entrega Final de Ciclo Terminal

12

• Es capaz de trabajar en un ambiente distribuído, en donde una máquina (cliente) emite los comandos OpenGL para dibujar en pantalla y otra máquina (servidor) es la que procesa y realiza las operaciones (los resultados de las llamadas a funciones OpenGL se ven remotamente, en la máquina servidora).

• Fue diseñado para poder ser implementado en cualquier plataforma de hardware. Para hacer esto fue necesario excluir de OpenGL funciones relacionadas con la manipulación de ventanas y captura de entradas de usuario (a pesar de esto hay paquetes como glut u glaux que facilitan este tipo de operaciones y que pueden ser obtenidos fácilmente a través de Internet).

• No provee comandos para describir objetos tridimensionales complejos; para realizar esto se debe construir el objeto a partir de las primitivas que ofrece OpenGL para dibujar puntos, líneas y polígonos (entre otras cosas).

• Ofrece funciones para alcanzar efectos de sombreado, iluminación, esconde objetos que en la escena se encuentren ocultos por otros y efectos de profundidad (visión en perspectiva) entre otros.

1.1. Estructura de un Programa en OpenGL Para entender la manera en que la librería gráfica móvil opera es importante conocer la manera en que se estructuran los programas en OpenGL, ya que de manera muy similar se estructurarán los programas que operen con MobileGL. A pesar de que las incontables operaciones que ofrece OpenGL le agregan complejidad a los programas que puedan ser desarrollados utilizando esta interfaz, la estructura básica de cualquier programa es algo sencilla y de alguna manera estándar (común entre todos los programas que hacen uso de OpenGL). Básicamente la estructura de estos programas sigue la siguiente forma: • Inicializar ciertos estados que rigen la manera en la que OpenGL dibuja los

objetos en escena. Algunos de estos estados son el color del fondo de la escena y el color con el que serán dibujados los objetos de la misma.

• Colocar y dibujar los objetos que componen el mundo (la escena). 1.2. Sintaxis de los Comandos/Constantes OpenGL Para hacer menos traumático el porte de una aplicación OpenGL a la librería gráfica móvil, la sintaxis de los comandos y constantes para MobileGL es

Page 16: Documento Final de Tesis Entrega Final de Ciclo Terminal

13

identica a la que se utiliza en OpenGL. Es éste entonces el motivo de dedicarle una sección a detallar la nomenclatura de las funciones que hacen parte de OpenGL. En la sección de Alcance se listaron las funciones a implementar en esta etapa del proyecto. Se pudo apreciar entonces que todas las funciones empezaban con el prefijo gl, y cada palabra que compone la función era capitalizada. Es precisamente esta la nomenclatura que sigue OpenGL al momento de nombrar sus funciones. De una manera parecida procede con las constantes que utiliza; todas sin excepción empiezan con el prefijo GL, capitalizando cada letra de la palabra y separando palabras distintas con el caracter '_'. Además de estos prefijos, OpenGL utiliza una serie de sufijos que determinan tanto el tipo como el número de argumentos que la función recibe. Estos sufijos son de la manera <numero_argumentos><tipo_argumentos>. El número de argumentos varía entre 2 y 4, mientras que el conjunto de tipos de datos que soporta OpenGL es más extenso y se lista a continuación9: • b: booleano, definido en OpenGL como GLbyte. • s: corto (short), definido en OpenGL como GLshort. • i: entero (largo), definido en OpenGL como GLint o GLsizei. • f: flotante, definido en OpenGL como GLfloat o GLclampf. • d: doble, definido en OpenGL como GLdouble o GLclampd. • ub: entero sin signo de 8 bits o caracter sin signo, definido en OpenGL

como GLubyte o GLboolean. • us: entero corto sin signo (de 16 bits), definido en OpenGL como

GLushort. • ui: entero sin signo (de 32 bits), definido en OpenGL como GLuint,

GLenum o GLbitfield. Para hacer mayor claridad en el tema, un ejemplo ilustrativo es el siguiente: glVertex2f(2.0, 1.0); glVertex2i(2, 1); Las dos funciones mencionadas a continuación tienen como propósito el especificar un vértice a dibujar en pantalla. En realidad ambas desarrollan la misma tarea y difieren únicamente en el tipo de argumentos que reciben (la primera recibe flotantes mientras la segunda recibe enteros). El número 2 en el sufijo indica que la función recibe únicamente dos argumentos.

9 Tomado de: Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html

Page 17: Documento Final de Tesis Entrega Final de Ciclo Terminal

14

Para efectos del proyecto y debido a que el lenguaje de programación Java no soporta el mismo número de tipos de datos soportados por OpenGL, las funciones con las que se trabajará excluyen los tipos de datos sin signo (aquellos que comienzan por u y que fueron enunciados anteriormente). Para concluir con esta sección es pertinente hacer una última salvedad; el sufijo de las funciones puede incluir además una v que determina que el tipo de parámetro aceptado es un vector de longitud igual al número de parámetros que aceptaría la función en condiciones normales (sin la v). Algunas funciones en OpenGL aceptan todo tipo de parámetros, mientras otras solo unos cuantos. Para evitar ambigüedades en este tema, la documentación de la librería deja explícitamente citados los diferentes tipos de datos y números de argumentos con los que trabaja una función.

1.3. OpenGL como una Máquina de Estados OpenGL se considera una máquina de estados debido a la manera como realiza sus operaciones; durante toda la ejecución de un programa, OpenGL mantiene una colección de estados que se mantienen con los mismos valores hasta que el programa decida cambiarlos haciendo uso de algunas de las funciones que ofrece OpenGL10. Variables como el color con los que se dibujarán los vértices, el modo de interpretar los vértices al momento de armar los objetos geométricos, las características de los materiales, iluminación y sombreado representan algunos de los estados mantenidos por OpenGL. Algunos de estos estados son habilitados haciendo uso de unas funciones preestablecidas, mientras que para otros esto se puede conseguir haciendo uso de las funciones glEnable y glDisable. Si el programa no modifica ninguno de los valores de las variables de estado, sus valores por defecto serán utilizados. Para consultar estos valores es necesario hacer uso de la función glGet*, concretamente de sus variantes glGetFloatv, glGetDoublev, glGetIntegerv y glGetBooleanv. Para efectos de la librería gráfica a desarrollar, los estados que se incorporaron en esta etapa son los siguientes: • GL_CURRENT_COLOR: color actual utilizado para dibujar los vértices de

los objetos geométricos de la escena. Su valor por defecto es (1, 1, 1, 1) o el color blanco, y se puede utilizar tanto glGetIntegerv como glGetFloatv para obtener su valor.

10 Tomado de: Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html

Page 18: Documento Final de Tesis Entrega Final de Ciclo Terminal

15

• GL_MODELVIEW_MATRIX: matriz de almacenamiento de transformaciones de modelo y de vista. Su valor por defecto es la matriz de identidad y puede ser consultado mediante la función glGetFloatv.

• GL_MODELVIEW_STACK_DEPTH: profundidad de la pila de matrices de modelo-vista. Su valor por defecto (y único e inmodificable) es 16 y puede ser consultado por medio de la función glGetIntegertv.

• GL_MATRIX_MODE: la pila de matrices sobre la cuál recaen todas las operaciones efectuadas. Su valor por defecto es GL_MODELVIEW, lo que indica que inicialmente la pila de matrices de modelo-vista es la que recibe todas las transformaciones realizadas. Su valor puede ser obtenido por medio de la función glGetIntegerv.

• GL_POLYGON_MODE: el modo de rasterización de los polígonos. En este caso hay una diferencia entre OpenGL y la librería gráfica móvil a desarrollar. Para OpenGL el valor por defecto es GL_FILL, lo que indica que el interior de los polígonos es rellenado. El relleno de polígonos (sobretodo en 3 dimensiones) es una labor bastante compleja, existiendo a la fecha algunos algorítmos que intentan desarrollar la labor. Debido a que esta es la primera etapa del proyecto y que la prioridad es lograr la migración e implementación de las transformaciones de modelo-vista, la librería gráfica móvil a desarrollar toma este valor como GL_LINE, siendo este junto con GL_POINT los únicos soportados para este estado. Este valor puede ser consultado haciendo uso de la función glGetIntegerv.

• GL_COLOR_CLEAR_VALUE: color con el es limpiado el buffer de color. Su valor por defecto es (0, 0, 0, 0) o el color negro, y puede ser consultado haciendo uso de la función glGetFloatv.

• GL_DOUBLEBUFFER: varible que especifica si la aplicación se encuentra trabajando con dos buffers o con uno. Este tipo de buffers hace referencia a aquellos que almacenan los píxeles de la escena. Cuando hay dos buffers, mientras se despliega la escena usando la información del buffer principal, la misma escena puede estar repintandose en el buffer secundario. Al finalizar el proceso de pintada en el buffer secundario, los datos de los buffers se intercambian para poder desplegar la escena recien pintada (y el proceso se repite así hasta que el programa termine su ejecución). En el caso de que un programa se encuentre trabajando con dos buffers, esta variable almacenará el valor booleano verdadero; en el caso contrario, el valor falso será almacenado. Para consultar este valor se puede utilizar la función glGetBooleanv.

Además de los estados anteriormente mencionados, OpenGL mantiene uno muy especial en el cual almacena el error generado por la última operación ejecutada. Esta variable se consulta de una manera diferente, razón por la cual es tratada aparte de las demás. Para OpenGL, la manera de procesar un error se resume a continuación: • Inicialmente la variable con tiene el valor GL_NO_ERROR, lo cual indica

que hasta el momento no se ha presentado ningún error.

Page 19: Documento Final de Tesis Entrega Final de Ciclo Terminal

16

• Para el caso en el que un llamado a una función de la librería genera un error, hay dos maneras de proceder; si la variable de error contiene el valor GL_NO_ERROR, este valor es remplazado por uno de los códigos de error que define OpenGL y que corresponde al error presentado; si este no es el caso y la variable de error ya ha registrado un error, este valor se preserva hasta que el programa haga una llamada a la función glGetError (función utilizada para obtener el valor de la variable de error). Esta función seguirá retornando todos los errores que se han presentado hasta llegar a retornar GL_NO_ERROR cuando no hay más errores por reportar.

Debido a lo anterior, la práctica recomendada es la de llamar a glGetError hasta que esta función retorne el valor GL_NO_ERROR. Para efectos de la librería gráfica móvil a desarrollar, los códigos de error manejados son idénticos a los utilizados por OpenGL y se describen a continuación: • GL_INVALID_ENUM: error que se presenta cuando la función espera un

conjunto de constantes simbólicas con base en los cuales va a operar, pero el valor recibido se encuentra fuera del rango de las constantes válidas para la función. Este es el caso de glMatrixMode, función que acepta los parámetros GL_MATRIXMODE, GL_PROJECTION y GL_TEXTURE. Si algún valor distinto de estos le es especificado a la función, este tipo de error será reportado por la librería gráfica.

• GL_INVALID_VALUE: error que se presenta cuando se le especifica a una función un valor inválido. Cada función en su documentación especifica los valores que esta preparada a recibir; si se especifica un valor fuera de este rango, este error será registrado por la librería gráfica. Este es el caso de la función glClear, que acepta una combinación lógica de valores GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT y GL_STENCIL_BUFFER_BIT. Esto quiere decir que la función está preparada a recibir cada valor por separado o una combinación de los mismos haciendo uso del operador lógico '|'. Si un valor diferente es especificado, este error quedará registrado.

• GL_INVALID_OPERATION: error que se presenta cuando una operación es llamada mientras la librería se encuentra en un estado donde este tipo de operación no es permitida. El ejemplo clásico es el del par de funciones glBegin y glEnd. Este tipo de funciones delimitan la especificación de un conjunto de vértices que conforman una primitiva a dibujar en pantalla. En la documentación de la librería se especifica el conjunto de funciones que pueden ser llamadas entre un llamado a glBegin y glEnd. Si cualquier otra función distinta a las especificadas es llamada, este error será registrado por la librería gráfica.

• GL_STACK_OVERFLOW: error que se produce cuando la operación a efectuar causaría un desbordamiento de pila. Por lo general este error se presenta al tratar de salvar algún estado (haciendo uso de la función glPushMatrix o glPushAttrib ) cuando la pila correspondiente al estado se encuentra llena.

Page 20: Documento Final de Tesis Entrega Final de Ciclo Terminal

17

• GL_STACK_UNDERFLOW: error que se produce cuando la operación a efectuar intenta obtener un valor de una de las pilas de la librería y la pila correspondiente se encuentra vacía.

• GL_OUT_OF_MEMORY: error que se produce cuando el sistema no dispone de memoria suficiente para ejecutar el comando.

Para todos los casos de error exceptuando GL_OUT_OF_MEMORY la forma de proceder es la de reportar el error ocurrido e ignorar la operación. Para este último caso de error, el estado de la librería gráfica es indefinido. Antes de concluir la sección es importante dejar detallada la manera que ofrece OpenGL para guardar estos estados y reestablecerlos a futuro. Para efectos de la librería gráfica móvil a desarrollar, únicamente serán descritos aquellos estados incorporados a esta librería. Se debe hacer claridad sobre el hecho de que hay dos diferentes tipos de variables de estados: unas variables son matrices (o arreglos que son interpretados como matrices) y otras son variables comunes y corrientes. Para salvar el estado de una matriz (de la matriz que se encuentra en el tope de la pila que recibe todas las transformaciones que se estén ejecutando) basta con llamar a la función glPushMatrix. Si la variable de estado que se quiere guardar no es de tipo matriz, la manera a proceder es haciendo un llamado a la función glPushAttrib y especificando uno de los siguientes argumentos (o una combinación de los mismos haciendo uso del operador lógico '|'): • GL_COLOR_BUFFER_BIT: guarda el modo de color que se esta

utilizando (RGBA o modo índices). • GL_CURRENT_BIT: guara el color con el que se están dibujando los

vértices de las primitivas. • GL_POLYGON_BIT: guarda el modo en el que se están dibujando los

polígonos en pantalla. • GL_TRANSFORM_BIT: guarda la constante simbólica que indica el tipo de

la pila de matrices sobre la cual recaen todas las operaciones de transformación actualmente.

Para restablecer los valores almacenados se llama a glPopMatrix si la variable de estado es una matriz o glPopAttrib si no lo es. Hasta este punto se han mencionado varias constantes y funciones, sin llegar al punto de profundizar hasta el más mínimo detalle. Esto se debe a que en una sección futura se detallará la librería gráfica móvil a desarrollar, la cual es el pilar del presente trabajo. En esa sección se estudiará cada una de las funciones implementadas, detallando los parámetros que reciben y los códigos de error que pudiesen llegar a generar.

Page 21: Documento Final de Tesis Entrega Final de Ciclo Terminal

18

1.4. Animación en OpenGL El proceso que sigue OpenGL para llegar a una escena animada es similar al que utilizan los teatros de cine; se tiene un conjunto de imágenes desplegadas a razón de segundo transcurrido (en un principio el número de imágenes desplegadas era de 16 por segundo, luego se incrementó este número a 24 y en la actualidad se suele hacer con 48 imágenes). En el caso de OpenGL, cada imagen a desplegar debe haber sido completamente dibujada primero11. Para facilitar el proceso, OpenGL ofrece la posibilidad de trabajar con dos buffers. El principal es el que contiene los datos a desplegar en pantalla mientras que en el secundario se va dibujando la siguiente imagen a desplegar. Una vez se termine el proceso de dibujo, los datos de los dos buffers son intercambiados para así desplegar la imagen recientemente dibujada. Para conseguir el efecto de animación, la imagen de la escena actual es re-dibujada únicamente con un conjunto distinto de transformaciones. El dibujo sucesivo de escenas transformadas es lo que realmente consigue el efecto de animación en OpenGL. 1.5. Operaciones Básicas de OpenGL En el nivel más alto de abstracción hay tres operaciones básicas12: limpieza de la ventana, dibujo de objetos geométricos y dibujo de objetos tales como imágenes, mapas de bits y fuentes de caracteres. Para efectos de la librería gráfica a desarrollar y por ser esta la primera etapa, los temas que se abarcarán en el presente trabajo son los dos iniciales. El último tema le agrega complejidad al proyecto, lo cual se traduce en más tiempo y/o personas involucradas en el proyecto. Es un aspecto importante de OpenGL sin ninguna duda, pero puede ser postergado para futuras etapas de desarrollo. Retomando el tema de operaciones básicas, la primera que todo programa (que desee trabajar con OpenGL) debe procesar es la de limpiar la ventana donde se realizará el dibujo de la escena. Esto en términos concretos se reduce a limpiar el área de memoria utilizada para dibujar la última imagen

11 Tomado de: Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html 12 Tomado de: Chapter 2 - OpenGL Programming Guide (Addison-Wesley Publishing Company http://rush3d.com/reference/opengl-redbook-1.1/chapter02.html

Page 22: Documento Final de Tesis Entrega Final de Ciclo Terminal

19

desplegada. Si esto no se realiza la nueva imagen se sobrepondrá a la anterior, evitando que se produzcan los resultados deseados. Para realizar esta tarea en OpenGL basta con hacer una llamada a las siguientes funciones13: • glClearColor: establece el color al que será limpiado el buffer de color. En

OpenGL esta función recibe cuatro valores del tipo GLclampf, pero por razones que se discutirán en un futuro la librería gráfica móvil acepta valores de tipo flotante. Cada uno de los valores corresponde al porcentaje de rojo, amarillo, verde y alfa que contendrá el color a utilizar para la limpieza del buffer de color [4].

• glClear: limpia el buffer(s) especificado(s). En OpenGL hay cuatro buffers que pueden ser limpiados; el buffer de color, el buffer de plantillas, el buffer de profundidad y el buffer de acumulación. Debido al alcance planteado para el presente proyecto, el único buffer que realmente es limpiado en la librería gráfica móvil es el buffer de color. Esto no quiere decir que la función reciba distintos valores a aquella presente en OpenGL; acepta los mismos, la diferencia radica en el comportamiento y manera de operar de la función (hace caso omiso cuando se especifica una constante simbólica a la que la función reaccionaría limpiando los buffers distintos al de color). Si se desea limpiar el buffer de color con un valor distinto a aquel utilizado por defecto (color negro), se debe hacer una llamada primero a glClear (esto aplica igualmente para los otros tres buffers, con la diferencia de que la función a llamar es diferente y no son tratadas en este documento a razón de que se encuentran ausentes de la primera implementación de la librería gráfica móvil) [4].

La segunda operación básica a tratar en esta sección es el dibujo de los objetos geométricos que harán parte de la escena final. En OpenGL (al igual que en la librería gráfica móvil), el dibujar un objeto implica por una parte especificar las propiedades de color, sombreado, iluminación, etc. con las que será dibujado el objeto; una vez especificadas estas propiedades se puede continuar con la enumeración de los vértices que harán parte de la figura. Para esta primera etapa del proyecto la única propiedad de color que podrá ser especificada para los objetos es el color de los mismos. Esto se debe a que para esta etapa solo se implementará el modo de dibujo de polígonos como unión de líneas (no rellenados), lo que hace innecesario por el momento la incorporación de propiedades como iluminación y sombreado. Una vez leída la sección dedicada a la librería gráfica móvil el lector estará dotado de más herramientas para comprender de una mejor manera lo que en este párrafo se ha enunciado.

13 Tomado de: Chapter 2 - OpenGL Programming Guide (Addison-Wesley Publishing Company http://rush3d.com/reference/opengl-redbook-1.1/chapter02.html

Page 23: Documento Final de Tesis Entrega Final de Ciclo Terminal

20

Para asignar el color de los objetos OpenGL ofrece la función glColor, la cuál contiene unas 16 variantes (8 de ellas reciben tres parámetros de diferentes tipos, mientras que las 8 restantes reciben 4). Aquellas funciones de tres parámetros reciben los porcentajes de color rojo, verde y azul, valores que se deben encontrar entre el rango 0 y 1. El parámetro adicional que reciben aquellas de cuatro argumentos representa el valor alfa. Debido a que SuperWaba no permite especificar este valor al momento de asignar colores de dibujo (al menos este es el caso en su última versión, 4.5a), estas funciones no fueron implementadas en la librería gráfica móvil. Las funciones que si fueron implementadas en esta librería suman un total de cinco, ya que los tipos de datos sin signo tampoco son soportados por SuperWaba. Más acerca de esta plataforma en una siguiente sección. Una vez asignado el color con el que serán dibujados los objetos en la escena se puede proceder a describir la serie de puntos o vértices que harán parte de los mismos. OpenGL ofrece una función especial para esta tarea, glVertex; el total de sus variantes suma 24, pero aquellas implementadas para la librería gráfica móvil únicamente suman un total de 16. Aquellas excluidas deben esto a que reciben, además de los tres argumentos para cada una de las coordenadas x, y y z, un parámetro w que se denomina la coordenada euclidiana y que será estudiada en la sección dedicada al repaso de los conceptos gráficos utilizados para construir la librería gráfica móvil. Las funciones que sí fueron implementadas permiten la especificación de vértices tanto en dos como tres dimensiones. Más acerca de esto en la sección dedicada a la librería gráfica móvil. El dibujo de los objetos geométricos depende en gran parte de que es lo que se quiere dibujar; puntos, líneas y polígonos son las opciones disponibles en OpenGL y cualquier figura de mayor complejidad se debe armar a partir de estas primitivas. Antes de continuar es preciso hacer una aclaración y dejar claros algunos términos. Un punto para la librería gráfica no es infinitamente pequeño (definición matemática) sino representado como un píxel; una línea no es infinitamente delgada ni se extiende al infinito por ambos lados, es un conjunto de puntos que conforma un segmento de línea; un polígono en OpenGL debe ser simple o convexo, significando que para cualquier dos puntos que hagan parte del polígono la línea que los une debe hacer parte del mismo. Para dibujar un punto, una línea o un polígono basta con delimitar la zona de dibujo haciendo uso de las funciones glBegin y glEnd ofrecidas por OpenGL; entre estas dos funciones van los llamados a la función glVertex, la cual vimos en párrafos anteriores es la encargada de especificar los vértices que componen el objeto. glBegin necesita un parámetro que va a determinar el tipo de objeto a ser dibujado, una constante simbólica que bien puede ser una de las siguientes:

Page 24: Documento Final de Tesis Entrega Final de Ciclo Terminal

21

• GL_POINTS: trata a cada vértice como un único punto. El vértice n define el punto n y se dibujan N puntos.

• GL_LINES: trata cada par de vértices como un segmento de línea independiente. Los vértices 2n-1 y 2n definen el segmento de línea n y se dibujan N/2 segmentos de línea.

• GL_LINE_STRIP: dibuja un conjunto de segmentos de línea interconectados desde el primer vértice hasta el último. Los vértices n y n+1 definen el segmento de línea n y se dibujan N-1 segmentos de línea.

• GL_LINE_LOOP: opera de la manera similar a GL_LINE_STRIP, con la diferencia de que cierra el circuíto (dibuja un segmento de línea que conecta al último vértice con el primero). Por lo anterior, N líneas son dibujadas.

• GL_TRIANGLES: trata a cada tripleta de vértices como un triángulo independiente. Los vértices 3n-2, 3n-1 y 3n definen el triángulo n y se dibujan N/3 triángulos.

• GL_TRIANGLE_STRIP: dibuja un grupo interconectado de triángulos. Se define un triángulo para cada vértice que contenga dos antecesores. Para n impar, los vértices n, n+1 y n+2 definen un triángulo; para n par, los vértices n+1, n, n+2 definen un triángulo. Independientemente de si n es par o impar, el número de triángulos dibujado es del orden de N-2.

• GL_TRIANGLE_FAN: dibuja un grupo interconectado de triángulos. Funciona de manera similar a GL_TRIANGLE_STRIP, con la diferencia de que en este caso no se hace distinción entre la paridad o imparidad del número de vértices especificados (se dibujan N/2 triángulos).

• GL_QUADS: trata a cada cuarteto de vértices como un cuadrilátero independiente. Los vértices 4n-3, 4n-2, 4n-1 y 4n definen un cuadrilátero y se dibujan N/4 cuadriláteros.

• GL_QUAD_STRIP: dibuja un grupo interconectado de cuadriláteros. Se define un cuadrilátero por cada pareja de vértices especificada después de una primera pareja. Los vértices 2n-1, 2n, 2n+2 y 2n+1 definen un cuadrilátero.

• GL_POLYGON: dibuja un polígono convexo. Todos los vértices especifican la frontera (borde) del polígono.

Se pueden especificar tantos vértices como se deseen para dibujar los objetos de la escena, y en el caso en que se especifique un número incompleto de vértices para alguno de los casos, el total real de figuras dibujadas será inferior al normal especificado por el caso. Para puntualizar más sobre este detalle, el número mínimo de vértices que se debe especificar para cada una de las figuras a dibujar es el siguiente: 1 para puntos, 2 para líneas, 3 para triángulos y polígonos y 4 para cuadriláteros. 1.6. Transformaciones en OpenGL

Page 25: Documento Final de Tesis Entrega Final de Ciclo Terminal

22

Toda aplicación gráfica en OpenGL debe de manera directa o indirecta tratar con algún tipo de transformaciones, ya sea aquellas relacionadas con el modelo (objetos de la escena), la vista en perspectiva, o simplemente las transformaciones de las coordenadas de los objetos relativas al mundo de la escena a aquellas directamente ligadas a la ventana que desplegará la misma. Este tema es verdaderamente importante y sutilmente diferente para OpenGL y la librería gráfica móvil. A continuación se detallará un poco más el concepto de transformaciones, puntualizando (cuando aplique) en las diferencias entre una y otra librería. En OpenGL el proceso que traduce las coordenadas de un vértice de cómo fueron originalmente especificadas a coordenadas de ventana es el siguiente14:

1. Se especifican las coordenadas de un vértice haciendo uso de la función glVertex.

2. Haciendo uso de funciones de transformación de modelo (a ser listadas a continuación) se construye una matriz de modelo-vista que luego es aplicada a las coordenadas de cada uno de los vértices que componen los objetos de la escena.

3. Haciendo uso de funciones de transformación especiales se define el campo visual para la escena y la manera en que serán proyectados cada uno de los objetos que componen la misma en pantalla. Estas otras funciones de transformación se agrupan en una matriz de proyección, la cual es aplicada a cada uno de los vértices que componen los objetos de la escena.

4. En este punto se tienen unas coordenadas a las cuales se le ha aplicado tanto la matriz de modelo-vista como la matriz de proyección. Luego de esto se procede a hacer una transformación (vértice) que resulta en nuevos vértices proyectados de un mundo en 3 dimensiones a un mundo en 2 dimensiones. Esto da como resultado que por cada vértice se tienen unas nuevas coordenadas de dispositivo normalizadas. La manera en que OpenGL realiza esta conversión no es clara ni especificada, pero en una sección futura estudiaremos el algoritmo utilizado para librería gráfica móvil y con cierta seguridad podemos afirmar que es el mismo al utilizado por OpenGL.

5. El último proceso realizado por OpenGL es el de convertir (por vértice) estas coordenadas normalizadas a coordenadas de ventana. En este paso es realmente donde se define que píxeles de la ventana se verán afectados para reflejar la escena (tridimensional) a dibujar en pantalla.

14 Tomado de: Chapter 2 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter02.html

Page 26: Documento Final de Tesis Entrega Final de Ciclo Terminal

23

La librería gráfica móvil a desarrollar en el presente trabajo realiza todas estas operaciones exceptuando la tercera. La razón de este comportamiento es sencilla de comprender, y aunque totalmente lógica, es importante que por compatibilidad de la librería con OpenGl este paso sea agregado en futuras versiones de la misma. OpenGL aplica las transformaciones de proyección para determinar que objetos serán o no mostrados en la escena. Las transformaciones de proyección definen el volumen visual o el campo visible por el observador de la escena, y al realizar estas comparaciones OpenGL ahorra trabajo al no tener que dibujar aquellos objetos que no son visibles según este tipo de transformaciones. La librería gráfica no realiza este paso debido a que dentro de sus funciones a implementar no se encuentran algunas como gluPerspective, glFrustrum o glOrtho; las dos primeras definen una vista con proyección en perspectiva, mientras que la útima defne una vista con proyección ortogonal. Este tipo de vistas será discutido en la sección dedicada a los conceptos gráficos, pero por el momento es suficiente con conocer que el propósito de estas funciones es definir una matriz de proyección que será aplicada a todos los vértices de los objetos de la escena para determinar cuales serán visibles y cuales no se dibujarán. El que la librería gráfica móvil no realice este paso no determina que todos los objetos independientemente de sus coordenadas serán visibles en la escena; las transformaciones de perspectiva y el paso a coordenadas de ventana compensan un poco la ausencia de una matriz de transformación en el sentido en que ayudan a controlar que objetos se encuentran visibles y cuales no. Las desventajas reales que mantiene esta versión de la librería con respecto a OpenGL son las siguientes:

• El campo visual de la escena no es dinámico y siempre será el rectángulo delimitante de las dimensiones de la ventana, con unos límites para el eje z fijados al momento del desarrollo de esta librería (es posible que esto no sea muy claro en estos momentos, pero de seguro se entenderá luego de haber leído la sección dedicada a la librería gráfica móvil).

• Todos los vértices de los objetos son dibujados indistintamente de si el objeto se encuentra visible o no. Esta es tal vez la desventaja más grande e impacta directamente la eficiencia de la librería (para escenas pequeñas no es un problema grave, pero para aquellas con un número grande de objetos puede convertirse esto en un dolor de cabeza). Por razones de eficiencia es importante entonces que para la siguiente versión se incorpore la matriz de proyección, ahorrando así esfuerzos innecesarios en el dibujo de vértices ocultos.

Las funciones ofrecidas por OpenGL para realizar transformaciones de modelo-vista y que fueron implementados en la librería gráfica son las siguientes:

Page 27: Documento Final de Tesis Entrega Final de Ciclo Terminal

24

• glTranslatef: realiza una traslación sobre los ejes x, y y z. Una traslación puede verse como un desplazamiento, el cual se hace a nivel de vértice.

• glRotatef: realiza una rotación sobre un eje especificado. Aunque esto es real para OpenGL, la librería gráfica solo permite rotaciones sobre los ejes bien definidos (x, y y z).

• glScalef: realiza una escalación por coordenada basada en el punto fijo (0, 0) o el origen del sistema de coordenadas. OpenGL permite escalar sobre cualquier punto fijo pero por consideraciones de tiempo esto por ahora no es posible.

Además de estas dos funciones hay otra más que sirve para asignar a la matriz de transformaciones de modelo-vista la matriz de identidad. No se detalla en este caso debido a que todavía no se ha detallado la manera en la que la librería agrupa este tipo de transformaciones para luego aplicárselas a los vértices que componen los objetos de la escena. La razón de agrupar las transformaciones va directamente ligada al grado de eficiencia que se quiere alcanzar la librería; en la sección de conceptos gráficos se detallará en profundidad este tema. Con esto se concluye el tema de OpenGL; el resto de anotaciones referentes a la librería gráfica estarán dirigidas a la librería gráfica móvil a desarrollar como proyecto de grado. 2. Conceptos Gráficos Muchas aplicaciones necesitan una manera de alterar o manipular los objetos de la escena, no simplemente colocarlos. Algunas otras necesitan cierto dinamismo; necesitan del movimiento de algunos de sus elementos, necesitan de animación. La forma para conseguir esto en cualquier librería gráfica es a través de las transformaciones geométricas. Una transformación geométrica es una operación que altera las descripciones de las coordenadas de un objeto15. Las transformaciones básicas son la traslación, rotación y escalamiento. Otras transformaciones como la reflexión y el recorte no fueron consideradas para esta versión de la librería gráfica móvil, debido a que el soporte que OpenGL ofrece para estas tampoco es muy claro. Además de haber diferentes tipos de transformaciones, su campo de acción también varía; hay transformaciones que operan en mundos bidimensionales y tridimensionales. Primero se procederá con el estudio de aquellas dirigidas a objetos en dos dimensiones, extendiendo luego estos conceptos a objetos tridimensionales. Esto se debe a que tanto las transformaciones en dos dimensiones como en tres dimensiones siguen la misma filosofía (con 15 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 5 – Transformaciones geométri cas bidimensionales

Page 28: Documento Final de Tesis Entrega Final de Ciclo Terminal

25

algunas diferencias mínimas claro esta), y para efectos didácticos es más simple el entender y detallar como funcionan estas transformaciones sobre objetos de únicamente dos coordenadas. 2.1. Traslación Una traslación permite cambiar la posición de un objeto a lo largo de la trayectoria de una línea recta. La traslación (como cualquier transformación) se hace a nivel de cada uno de los vértices que componen el objeto. Para trasladar un punto (x,y) una distancia dt a la posición (x’, y’) basta con agregar unas distancias de traslación16: x’ = x + tx, y’ = y + ty donde (tx, ty) se denomina el vector de traslación o vector de cambio. Modificando un poco la representación de estas ecuaciones para adaptarlas al modelo matricial, las nuevas ecuaciones de traslación quedarían de la siguiente manera: P = [x1] P’ = [x’1] T = [tx] y P’ = P + T [x2] [x’2] [ty] Esta forma de ecuación de traslación obliga a que a cada vértice se le sume el vector de traslación. Si las transformaciones permitidas por una librería gráfica fueran únicamente traslaciones, esta representación no tendría problema alguno. El inconveniente aparece cuando hay que tomar en cuenta transformaciones del estilo de rotación o escalamiento, y cuando el número de este tipo de transformaciones es considerable en un programa gráfico; en estos casos la manera a proceder es la de aplicar una por una las traslaciones a los vértices de los objetos, algo bastante ineficiente y hasta cierto punto inaceptable. Una vez estudiado el tema de coordenadas homogéneas se replanteará esta ecuación para hacer más eficiente la aplicación de múltiples transformaciones sobre los vértices de los objetos que componen la escena. Una última aclaración antes de seguir con el siguiente tipo de transformaciones es la siguiente: el decir que la traslación se le aplica a cada uno de los vértices que componen el objeto no es del todo correcta; la traslación se aplica a aquellos vértices que delimitan al objeto. Luego de esto se procede a redibujar el objeto en la nueva posición. Este tipo de transformaciones son conocidas como transformaciones e cuerpos rígidos ya

16 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 5 – Transformaciones geométri cas bidimensionales

Page 29: Documento Final de Tesis Entrega Final de Ciclo Terminal

26

que mueven el objeto sin deformarlo. Luego de haber estudiado la rotación se notará que este es otro tipo de transformación del mismo estilo. 2.2. Rotación Una rotación permite cambiar la posición de un objeto a lo largo de la trayectoria de una circunferencia en el plano xy17. Para generar una rotación (bidimensional) basta con especificar un ángulo de rotación Ø y la posición (xr, yr) del punto de rotación o punto pivote entorno al cual se gira el objeto. Para definir una rotación en sentido opuesto a las manecillas del reloj se debe especificar un ángulo de rotación positivo; lo contrario sucederá al especificar un ángulo negativo (o mayor a 180 grados). En dos dimensiones esta transformación también puede ser descrita como una rotación sobre un eje de rotación que es perpendicular al plano xy y pasa a través del punto pivote. Para simplificación de los cálculos, las ecuaciones presentadas a continuación asumen que el punto pivote se encuentra en el origen del sistema de coordenadas. Luego se generalizará la idea a puntos de pivote aleatorios. La siguiente ilustración ayudará a comprender las ecuaciones presentadas a continuación.

Figura 1 Al aplicar algunas reglas de trigonometría podemos derivar las ecuaciones que nos darán la rotación desde el punto (x,y) al punto (x’,y’) usando como punto pivote (0,0): x’ = rcos(ø + Ø) = rcosøcosØ – rsenøsenØ, y’ = rsen(ø + Ø) = rcosøsenØ + rsenøcosØ donde Ø es el ángulo de rotación, r es la distancia desde el punto pivote al punto a rotar y ø es el ángulo entre el segmento de distancia r y el eje x. Tomando las coordenadas polares del punto (x, y) podemos reescribir les ecuaciones de rotación de la siguiente manera:

17 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 5 – Transformaciones geométri cas bidimensionales

Page 30: Documento Final de Tesis Entrega Final de Ciclo Terminal

27

x = rcosø y = rsenø x’ = xcosØ – ysenØ y’ = xsenØ + ycosØ Utilizando la representación matricial, las ecuaciones de rotación quedan de la siguiente manera: P = [x1] P’ = [x’1] R = [cosØ -senØ] y P’ = R . P [x2] [x’2] [senØ cosØ] Para generalizar el concepto a puntos de pivote arbitrarios utilizaremos la siguiente ilustración:

Figura 2 Siguiendo el mismo razonamiento trigonométrico, las nuevas ecuaciones de rotación quedan de la siguiente manera: x’ = xr + (x- xr)cosØ - (y- yr)senØ y’ = yr + (x- xr)senØ + (y- yr)cosØ La representación matricial puede adaptarse para incluir los nuevos valores que generalizan la ecuación de rotación para cualquier punto pivote. Debido al excedente de complejidad agregada con esta generalización, la librería gráfica móvil a desarrollar asume la rotación con respecto a un pivote ubicado en el origen del sistema de coordenadas. Al igual que una traslación, una rotación es una transformación de cuerpo rígido; mueve un objeto sin deformarlo.

Page 31: Documento Final de Tesis Entrega Final de Ciclo Terminal

28

2.3. Escalamiento Una transformación de escalamiento altera el tamaño de un objeto 18. Para lograr esto, cada uno de los vértices del mismo debe ser multiplicado por un factor de escalamiento tanto en su coordenada x como en su coordenada y. Las primeras ecuaciones de escalamiento quedan entonces de la siguiente forma: x’ = x*sx y’ = y*sy Adaptando estas ecuaciones a la representación matricial, podemos reformular las ecuaciones de escalación para presentarlas de esta manera a continuación: P = [x1] P’ = [x’1] S = [sx 0] y P’ = S . P [x2] [x’2] [0 sy] Para reducir el tamaño de un objeto basta con multiplicar las coordenadas del objeto por un factor de escalamiento menor a 1; lo contrario sucede si este mismo valor supera esta cantidad. Si el factor de escalamiento es igual a 1, el tamaño del objeto no es afectado. Antes de continuar es preciso detallas los distintos casos de escalamiento existentes; una escalamiento uniforme mantiene las proporciones relativas del objeto y se presenta cuando tanto sx como sy son iguales tanto en magnitud como en signo; una escalamiento diferencial se presenta cuando los factores de escalamiento para x y y tienen un valor distinto. La transformación de escalamiento es algo distinta a las dos anteriormente descritas. Además de modificar la posición del objeto, modifica el tamaño del mismo. El reducir el tamaño de un objeto implica también el acercarlo al origen del sistema de coordenadas. De igual manera, el agrandar un objeto implica el alejarlo del origen del sistema de coordenadas. El punto con respecto al cual se realiza la escalamiento se denomina punto fijo, y es posible tener un punto fijo diferente al origen del sistema de coordenadas. Al igual que la rotación, el generalizar esto para cualquier punto fijo aumenta la complejidad de la operación por lo cual la librería gráfica móvil a desarrollar no lo considera viable (OpenGL tampoco lo hace). Se presentan estas ecuaciones únicamente por completitud del estudio del tema: x’ = xf + (x – xf)sx y’ = yf + (y – yf)sy o 18 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 5 – Transformaciones geométri cas bidimensionales

Page 32: Documento Final de Tesis Entrega Final de Ciclo Terminal

29

x’ = x*sx + xf(1 – sx) y’ = y*sy + yf(1 – sy) donde (xf, yf) es un punto fijo cualquiera y xf(1 – sx), yf(1 – sy) son constantes para todos los puntos en el objeto. 2.4. Representación de Matriz y Coordenadas Homogéneas Este tema es crucial y su implementación en una librería gráfica impacta directamente la eficiencia y rendimiento de la misma. Las coordenadas homogéneas ayudarán a reformular las ecuaciones matriciales de las transformaciones anteriormente discutidas. De esta manera se facilitará el procesamiento secuencial de múltiples transformaciones. La manera natural de proceder al momento de tratar con múltiples transformaciones es la de aplicar una por una cada transformación a los vértices de los objetos de la escena. Eso implica el cálculo de valores intermedios a partir de las coordenadas originales del vértice para llegar a las coordenadas transformadas del mismo. Un procedimiento más eficiente seria el de combinar primero todas las transformaciones para luego aplicarlas en conjunto a las coordenadas de cada vértice y así obtener e resultado final en un solo paso. Esto sería posible si todas las ecuaciones matriciales de transformación consistieran únicamente de multiplicaciones, pero desafortunadamente este no es el caso de la traslación. Una solución (y la más apropiada por el momento) para este problema en dos dimensiones es el de ampliar las representaciones matriciales de 2*2 a representaciones de 3*3, y ampliar el vector de coordenadas agregándole una más. Las coordenadas cartesianas (x,y) de los vértices pasan entonces a ser coordenadas homogéneas (xh,yh,h), donde x = xh/h, y = yh/h Esto obliga a que el parámetro homogéneo h sea diferente a 0. Con la introducción de coordenadas homogéneas tenemos infinitas posibilidades de representar un punto (x,y). Un caso especial es aquel donde el parámetro homogéneo es igual a 1; para este caso x es igual a xh. Este es de hecho el caso más común, aunque como veremos en un futuro, las formulaciones de transformaciones de vista tridimensionales necesitan un valor de h distinto de cero.

Page 33: Documento Final de Tesis Entrega Final de Ciclo Terminal

30

Entendido el concepto de coordenadas homogéneas podemos proceder a reformular las ecuaciones de traslación, rotación y escalamiento19. Traslación P’ = [x’] T(tx, ty) = [1 0 tx ] P = [x] P’ = T(tx, ty) . P [y’] [0 1 ty] [y] [z’] [0 0 1 ] [1] Rotación P’ = [x’] R(Ø) = [cosØ senØ 0] P = [x] P’ = R(Ø) . P [y’] [senØ cosØ 0] [y] [z’] [ 0 0 1] [z] Escalamiento P’ = [x’] S(sx,sy) = [sx 0 0] P = [x] P’ = S(sx,sy) . P [y’] [0 sy 0] [y] [z’] [0 0 1] [z] Para comprobar la validez de las transformaciones compuestas se presentarán a continuación tres ejemplos de composiciones: dos traslaciones seguidas, dos rotaciones seguidas y dos escalaciones seguidas, cada ejemplo con sus resultados correspondientes. Una vez demostrado esto se utilizará la propiedad asociativa de la multiplicación de matrices para generalizar esto a composiciones de transformaciones de diferentes tipos. Composición de dos traslaciones seguidas T(tx1, ty1) = [1 0 tx1] T(tx2, ty2) = [1 0 tx2] [0 1 ty1] [0 1 ty2] [0 0 1 ] [0 0 1 ] T(tx1, ty1) . T(tx2, ty2) = [1 0 tx1 + tx2] = T(tx1 + x2, ty1 + y2)

[0 1 ty1 + ty2] [0 0 1 ] lo que demuestra que dos traslaciones sucesivas son aditivas. 19 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 5 – Transformaciones geométri cas bidimensionales

Page 34: Documento Final de Tesis Entrega Final de Ciclo Terminal

31

Composición de dos rotaciones seguidas R(Ø1) = [cosØ1 -senØ1 0] R(Ø2) = [cosØ2 -senØ2 0] [senØ1 cosØ1 0] [senØ2 cosØ2 0] [ 0 0 1] [ 0 0 1] R(Ø1) . R(Ø2) = [cosØ1cosØ2 – senØ1senØ2 –senØ1cosØ2 - cosØ1senØ2 0] [senØ1cosØ2 + cosØ1senØ2 cosØ1cosØ2 – senØ1senØ2 0] [ 0 0 1] Sea µ = cosØ1cosØ2 – senØ1senØ2 y ß = senØ1cosØ2 + cosØ1senØ2. R(Ø1) . R(Ø2) = [µ -ß 0] = R(Ø1 + Ø2) [ß µ 0] [0 0 1] lo que demuestra que dos rotaciones sucesivas son aditivas. Composición de dos escalaciones seguidas S(sx1,sy1) = [sx1 0 0] S(sx2,sy2) = [sx2 0 0] [0 sy1 0] [0 sy2 0] [0 0 1] [0 0 1] S(sx1,sy1) . S(sx2,sy2) = [sx1*sx2 0 0 ] = S(sx1* sx2,sy1* sy2) [ 0 sy1*sy2 0 ] [ 0 0 1] lo que demuestra que dos escalaciones sucesivas son aditivas. Para completar la demostración de la efectividad de la composición de transformaciones se utilizará la propiedad asociativa de la multiplicación de matrices. Esta propiedad se resume en lo siguiente: Siendo A, B y C matrices cualquiera, (A.B).C = A.(B.C) Si A = T(tx1, ty1) , B = R(Ø) y C = S(sx1,sy1) y habiendo demostrado que tanto las traslaciones como las rotaciones y escalaciones sucesivas son aditivas, se culmina la demostración de la composición de transformaciones (de igual o diferente tipo). 2.5. Transformaciones Geométricas Tridimensionales Los métodos para las transformaciones geométricas y de modelado de objetos en tres dimensiones se extienden de los métodos bidimensionales al

Page 35: Documento Final de Tesis Entrega Final de Ciclo Terminal

32

incluir las consideraciones para la coordenada z 20 . De las tres transformaciones vistas tal vez la transición menos directa de dos a tres dimensiones la sufre la rotación; en dos dimensiones la rotación siempre se realiza con respecto al eje z. En tres dimensiones no hay tal limitación y la transformación puede realizarse con respecto a cualquier eje arbitrario. La inclusión de la nueva coordenada impacta directamente las ecuaciones matriciales de las transformaciones. Las ecuaciones modificadas son presentadas a continuación. Traslación P’ = [x’] T = [1 0 0 tx] P = [x] y P’ = T.P [y’] [0 1 0 ty] [y] [z’] [0 0 1 tz] [z] [1 ] [0 0 0 1] [1] El cambio de la ecuación matricial únicamente radica en la inclusión de la nueva coordenada y la ampliación de una matriz 3*3 a una 4*4. Rotación Aunque la rotación puede darse con respecto a cualquier eje arbitrario, debido al grado de complejidad que esto le agrega al desarrollo de la librería gráfica móvil, esta posibilidad no fue incluida en la librería. Los casos que si considera la librería gráfica móvil consisten en aquellas rotaciones con respecto a los tres ejes bien definidos (eje x, y y z). Para cada caso hay una ecuación matricial diferente. El primer caso a tratar es la rotación sobre el eje z debido a que ya se detalló en los párrafos dedicados a la rotación en dos dimensiones. Rz(Ø) = [cosØ -senØ 0 0] [senØ cosØ 0 0] [ 0 0 1 0] [ 0 0 0 1] Para obtener las siguientes ecuaciones matriciales de rotación basta con realizar una permutación cíclica de los parámetros de coordenadas x, y y z de la ecuación anteriormente enunciada; se deben realizar las siguientes sustituciones: x -> y -> z -> x Una vez realizadas estas sustituciones obtenemos las siguientes ecuaciones matriciales: 20 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 11 – Transformaciones geométri cas y de modelado tridimensionales

Page 36: Documento Final de Tesis Entrega Final de Ciclo Terminal

33

Rx(Ø) = [1 0 0 0] Ry(Ø) = [ cosØ 0 senØ 0] [0 cosØ -senØ 0] [ 0 1 0 0] [0 senØ cosØ 0] [-senØ 0 cosØ 0] [0 0 0 1] [ 0 0 0 1] y P’ = [x’] , P= [x] y P’ = Rz(Ø).P o [y’] [y] P’ = Rx(Ø).P o [z’] [z] P’ = Ry(Ø).P [1 ] [1] Escalamiento P’ = [x’] S = [sx 0 0 0] P = [x] y P’ = S.P [y’] [0 sy 0 0] [y] [z’] [0 0 sz 0] [z] [1 ] [0 0 0 1 ] [1] El escalamiento, al igual que la traslación, no varía mucho en cuanto a su versión en dos dimensiones; únicamente se le debe agregar una coordenada más a los vértices y ampliar la matriz de transformación de 3*3 a 4*4. El concepto de transformaciones compuestas es igual indistintamente de si las transformaciones actúan sobre un mundo bidimensional o tridimensional, razón por la cual el tema no es retomado en esta sección. 2.6. Métodos de Despliegue Tridimensional A fin de obtener un despliegue de una escena tridimensional que se modeló en coordenadas mundiales, primero se debe establecer una referencia de coordenadas para la “cámara”21. Esta referencia de coordenadas define la posición y orientación para el plano de la película de la cámara, que es el plano que deseamos utilizar para desplegar la vista de los objetos de una escena. De esta manera se transfieren las descripciones de los objetos a las coordenadas de referencia de la cámara y se proyectan sobre el plano de despliegue que se selecciona. La librería gráfica móvil a desarrollar fija la posición y orientación de la cámara desde un principio. Esto se debe a que es la primera versión del proyecto y se le dio prioridad a las transformaciones de modelo vista (en 21 Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 9 – Conceptos tridimensionales

Page 37: Documento Final de Tesis Entrega Final de Ciclo Terminal

34

realidad del modelo), y no a aquellas relativas a la proyección. En próximas etapas del proyecto se debe reconsiderar este planteamiento para incorporar una nueva funcionalidad que habilite el dinamismo de la ubicación de la cámara. En esta sección se detallarán tres maneras distintas de desplegar una escena tridimensional sobre una superficie bidimensional. Este proceso es comúnmente denominado proyección, y los diferentes tipos de proyección considerados por el proyecto son:

• proyección en paralela • proyección ortogonal • proyección en perspectiva

De los tres procesos, aquel a detallar de una manera más profunda es el de proyección en perspectiva, debido a que fue el que se implementó por defecto en la librería gráfica móvil. Para este proceso se describirán las ecuaciones utilizadas para transformar puntos con tres coordenadas a puntos bidimensionales debidamente proyectados. Proyección en Paralela Este tipo de proyección permite la generación de una vista de un objeto sólido por medio de la proyección de puntos encontrados en la superficie del objeto a lo largo de líneas paralelas sobre el plano de despliegue. Al seleccionar diferentes posiciones de vista se puede proyectar los puntos visibles el objeto sobre el plano de despliegue para obtener distintas vistas bidimensionales del mismo. Al utilizar este proceso la imagen de la vista del objeto original no refleja el aspecto tridimensional del mismo. Lo anterior puede verse compensado con el hecho de que este tipo de proyección conserva las propiedades relativas de los objetos. La siguiente ilustración ayudará a la comprensión de la idea recientemente planteada.

Figura 3 De las cuatro figuras la primera es el objeto tridimensional en sí; las otras son proyecciones paralelas del objeto utilizando diferentes puntos de vista.

Page 38: Documento Final de Tesis Entrega Final de Ciclo Terminal

35

La proyección en paralela se realiza haciendo uso de un vector de proyección, el cual va a definir la dirección de las líneas de proyección. Cuando la proyección es perpendicular al plano de visión se tiene una proyección paralela ortogonal. En el caso contrario se tienen una proyección paralela oblicua. OpenGL no ofrece soporte para el segundo tipo de proyecciones y la librería gráfica móvil no implementa ninguna de las dos. Proyección en Perspectiva A diferencia de la proyección en paralela, a través de este método se proyectan puntos hacia el plano de despliegue a lo largo de trayectorias convergentes. El punto de convergencia de las trayectorias es denominado punto de referencia de proyección o centro de proyección. A través de este método lo que se intenta es simular el efecto de distancia entre el observador y los objetos de la escena; aquellos más cercanos al observador aparecerán más grandes que aquellos más distantes. Gracias a esto, las escenas construidas con este tipo de proyección gozan gran realismo. Este tipo de proyección es utilizado además por el ojo humano y los lentes de las cámaras fotográficas. La siguiente ilustración será de gran utilidad al momento de descifrar las ecuaciones que nos permitirán generar proyecciones en perspectiva para los modelos a desarrollar utilizando la librería gráfica móvil.

Figura 4 Según la ilustración el punto de referencia de proyección es zprp y se encuentra situado sobre el eje z. Además hay otro punto zvp sobre el cual se sitúa el plano de proyección. La línea de proyección es aquella que va desde P hasta el punto de referencia de proyección, y el punto (xp, yp, zvp) es el lugar en el que la línea de proyección intercepta el plano de proyección. Bastaría con encontrar el valor de las coordenadas del punto de intersección para lograr la proyección en perspectiva. Una primera aproximación nos daría las expresiones paramétricas para el valor de la línea en el punto de intersección:

Page 39: Documento Final de Tesis Entrega Final de Ciclo Terminal

36

x’ = x – xu, y’ = y – yu y z’ = z – (z – zprp)u El parámetro u varía entre 0 y 1 y la posición de coordenadas (x’, y’, z’) representa cualquier punto a lo largo de la línea de proyección. Analizando el valor de las ecuaciones en las fronteras del rango del parámetro notamos que cuando u es 0 nos encontramos en la posición P. Cuando u es 1 nos encontramos directamente sobre el punto de referencia de proyección, un punto con coordenadas (0, 0, zprp). Conocemos el hecho además de que el valor de z’ cuando nos encontramos sobre el plano de proyección es zvp. Despejando el parámetro u de la ecuación de z obtenemos la siguiente expresión: u = (zvp - z)/(zprp - z) Sustituyendo esta expresión en las ecuaciones para x’, y’ y z’ obtenemos las siguientes nuevas formulaciones: xp = x( zprp - zvp)/(z - zprp) = x(dp)/(z - zprp) yp = y( zprp - zvp)/(z - zprp) = y(dp)/(z - zprp) donde dp es la distancia del plano de visión desde el punto de referencia de proyección. Recordemos que al momento de introducir el concepto de coordenadas homogéneas precisamos en el hecho de que, a pesar de que generalmente el valor del parámetro homogéneo es 1, en la generación de vistas tridimensionales este valor es distinto y depende del punto de referencia de proyección y del lugar donde se fijó el plano de proyección. A continuación se presenta la forma matricial de estas ecuaciones. P = [xh] [1 0 0 0 ] y h = (z - zprp)/dp [yh] [0 1 0 0 ] xp = xh/h [zh] [0 0 zvp/dp - zvp (zprp/ dp)] yp = yh/h [h ] [0 0 1/dp -zprp/ dp ] Librerías gráficas como OpenGL conservan el valor origial de z para procesos de detección de superficies visibles e intensidad (entre otros). Las expresiones anteriormente mencionadas son la base del proceso de proyección en perspectiva implementado por la librería gráfica móvil desarrollada en este proyecto. A manera de anotación curiosa, durante la fase de pruebas de los algoritmos anteriormente detallados se encontró un pequeño error de factorización que alteraba de cierta manera la forma en que los vértices tridimensionales eran proyectados en la ventana del dispositivo. Las nuevas ecuaciones utilizadas para el cálculo de xp y yp son:

Page 40: Documento Final de Tesis Entrega Final de Ciclo Terminal

37

xp = x(dp)/(zprp - z) yp = y(dp)/(zprp - z) Hay varios casos especiales y que se presentan con gran frecuencia cuando se esta tratando con proyecciones en perspectiva. Si el plano de proyección se encuentra sobre el origen de coordenadas entonces las ecuaciones quedan de la siguiente manera: xp =x(zprp/(z - zprp)) = x(1/(z/zprp - 1)) yp =y(zprp/(z - zprp)) = y(1/(z/zprp - 1)) En el caso de la librería gráfica móvil, el plano de proyección se fijo sobre el valor z = 0. Es posible alterar este valor directamente modificando el código de la librería ya que en estos momentos no hay implementación de ninguna función que permita modificar el modo en el que se realiza la proyección en perspectiva. En una futura etapa podría someterse a consideración la integración de una nueva funcionalidad que permita realizar lo anteriormente descrito. Otra situación particular se presenta cuando el punto de referencia de proyección se encuentra situado en el origen de coordenadas de vista. En este caso zprp = 0 y las coordenadas de proyección en el plano de visión son: xp =x(-zvp/z) = x(-1/(z/ zvp)) yp =y(-zvp/z) = y(-1/(z/ zvp)) Este no es el caso de la librería gráfica, aunque de igual manera puede modificarse el punto de referencia de proyección alterando directamente el código de la librería. 3. SuperWaba A pesar de ser muy parecido a, SuperWaba no es Java. Partiendo de esta aclaración podemos entrar en materia; SuperWaba es una plataforma para desarrollo de software sobre dispositivos móviles, particularmente sobre asistentes personales digitales o PDAs. Es compatible en un 99% con Java. De hecho y por el momento utilizan el compilador de código de bytes provisto por las implementaciones de Java de Sun Microsystems. La documentación del API de SuperWaba fue creada utilizando la herramienta javadoc, cosa que la hace muy similar a la documentación del API de Java. Algunos aspectos interesantes de SuperWaba son los siguientes22:

22 Tomado de: SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Page 41: Documento Final de Tesis Entrega Final de Ciclo Terminal

38

• SuperWaba puede correr tanto en dispositivos Palm OS como en

Pocket PC. Aunque esto es cierto, su uso no se limita únicamente a dispositivos móviles; también es capaz de correr sobre computadores de escritorio.

• Contiene su propio interpretador de código de bytes. Aunque es cierto que SuperWaba puede utilizarse en un gran rango de dispositivos, la instalación en cada uno de los mismos es un poco diferente. Para la muestra se presentan algunos de estos casos a continuación. 3.1. Instalación en Dispositivos Palm OS La máquina virtual que se debe instalar consiste en los siguientes archivos: SuperWaba.pdb, SuperWaba.prc y SWNatives.prc. El primero contiene el código de la base de SuperWaba; el segundo contiene el interpretador de código de bytes; el tercero contiene el código de los métodos nativos (aquellos que manipulan y acceden estructuras y componentes del dispositivo). Debido a que el desarrollo del proyecto sobre el cual gira todo este documento está apoyado principalmente en POSE, se enunciará cada uno de los pasos que se siguieron para llevar SuperWaba al emulador23:

1. Descargar el SDK 2. Descomprimir el archivo en C:/, por lo que SW_ROOT equivale a

C:/SuperWabaSDK 3. Debido a que para pruebas se uilizo el ROM

PalmOS412_FullRel_EZ_enUS.rom (el cual trabaja con una versión de Palm OS inferior a la 5), los archivos SuperWaba.prc y SWNatives.prc instalados fueron aquellos que se encontraron bajo la carpeta lib /palm/PalmOS2_3_4.

4. El archivo SuperWaba.pdb, el cual se encuentra bajo la carpeta lib /xplat , es el mismo para todas las versiones de Palm OS y también fue instalado.

23 Tomado de: SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Page 42: Documento Final de Tesis Entrega Final de Ciclo Terminal

39

El proceso fue bastante sencillo y luego de completado el emulador presenta la siguiente imagen

Figura 5 Figura 6 Figura 7 donde se puede apreciar el ícono de SuperWaba. Una última aclaración que es importante que se realice: se debe utilizar el mismo Creator ID al momento de utilizar tanto Warp como ExeGen. Si esto no se hace, el programa seguramente no se podrá ejecutar. Instalación de aplicaciones La instalación de una aplicación SuperWaba sobre la plataforma Palm OS en un proceso bastante sencillo; hay que desarrollar un número de operaciones bastante inferior al número de pasos a seguir para instalar una aplicación sobre la plataforma Pocke Pc o sobre un computador de escritorio. Por razones únicamente económicas no se contó con la posibilidad de apoyar el desarrollo de la librería gráfica con un dispositivo real. Se trabajó con el emulador del dispositivo o bien conocido Palm OS Emulator. Es una herramienta verdaderamente fácil de utilizar y fue fundamental a través de todo el proceso. Para instalar una aplicación SuperWaba sobre Palm OS basta con instalar los archivos .prc y .pdb que la componen. En el emulador lo único que se debe hacer es dar clic con el botón derecho del ratón sobre la superficie del mismo y seleccionar “Install Application/Database”.

Page 43: Documento Final de Tesis Entrega Final de Ciclo Terminal

40

Figura 8 Luego de esto se despliega una ventana que permite seleccionar el(los) archivo(s) a instalar. Gracias a lo fácil que es instalar una aplicación SuperWaba sobre esta plataforma, Palm OS se convirtió en la plataforma piloto tanto para desarrollo como para pruebas de la librería gráfica móvil. 3.2. Instalación en Windows CE/Pocket PC La máquina virtual que se debe instalar consiste en los siguientes archivos 24: SuperWaba.pdb, SuperWaba.exe y MSW.pdb. De los tres solo el primero es 24 Tomado de: SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Page 44: Documento Final de Tesis Entrega Final de Ciclo Terminal

41

igual tanto para dispositivos Palm OS como para aquellos con Windows CE / Pocket PC. El segundo archivo es el equivalente a juntar el Superwaba.prc y SWNatives.prc mencionados anteriormente. El último archivo es necesario debido a que contiene las fuentes utilizadas (por el API/programas que lo utilicen). El archivo SuperWaba.exe a instalar es aquel que se encuentre en el directorio que corresponda al procesador y plataforma del dispositivo que se esta utilizando. Estos ejecutables se encuentran bajo la carrpeta /lib /ce. Instalación de aplicaciones La instalación de una aplicación SuperWaba sobre la plataforma Pocket PC es un poco más complicada y requiere de un número mayor de pasos a realizar. La tarea se complica más si no se cuenta con un dispositivo real, ya que el emulador para Pocket PC no es tan amigable como el de las Palm; se debe contar con herramientas adicionales para instalar las aplicaciones sobre el emulador. Cuando se va a instalar una aplicación SuperWaba sobre la plataforma Pocket PC se deben instalar os archivos .exe y .pdb que componen la misma. El archivo .exe es generado por la herramienta Exegen que vienen con la distribución de SuperWaba. El archivo .pdb es el mismo indistintamente de la plataforma sobre la cual se esté trabajando y es generado por la herramienta Warp que también viene con la distribución de SuperWaba. El ejecutable de la aplicación debe encontrarse bajo el menú principal del dispositivo, idealmente bajo la carpeta /SuperWaba. Para agregar el archivo .pdb se debe crear un nuevo directorio bajo /SuperWaba e incluír el archivo .pdb ahí. El archivo ejecutable sabe donde encontrar las clases de la aplicación debido a que durante el momento de ser generado una opción de la herramienta Exegen fijó el nombre del directorio. Más adelante cuando se detallen estas herramientas se podrá comprender mejor la manera como esto realmente sucede. Un caso especial sucede cuando la aplicación a instalar requiere de librerías adicionales. Para el caso de las librerías globales, su ubicación debe ser la carpeta de instalación de SuperWaba (/SuperWaba). Las librerías locales deben ser colocadas bajo el mismo directorio de la aplicación.

Page 45: Documento Final de Tesis Entrega Final de Ciclo Terminal

42

3.3. Instalación en Computadores de Escritorio Para instalar SuperWaba en un computador de escritorio es necesario tener instalada una versión del JDK de Sun Microsystems. Se recomienda la 1.2.x debido al formato de los archivos .class con el que SuperWaba trabaja25. Es probable que a estas alturas se tenga instalada en el computador una versión mucho superior, por lo que al momento de compilar se debe agregar la siguiente opción en la línea de comandos: -target 1.1. Para instalar SuperWaba en el computador de escritorio basta con crear una nueva carpeta C:\SuperWaba y adicionar ahí el archivo SuperWaba.exe (máquina virtual) encontrado en /lib /win32/ y el archivo SuperWaba.pdb encontrado en /lib /xplat/. Además de esto es requerido que se instale alguno de los archivos que contienen las fuentes a ser utilizadas por los programas a desarrollar bajo esta plataforma. Estos archivos son 5SW.pdb o MSW.pdb. Se debe agregar únicamente uno de los dos a la carpeta de SuperWaba. Después de haber instalado SuperWaba en el computador de escritorio, la imagen al correr la máquina virtual debe ser similar a la presentada a continuación

Figura 9

25 Tomado de: SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Page 46: Documento Final de Tesis Entrega Final de Ciclo Terminal

43

La funcionalidad de la máquina virtual que corre sobre un computador de escritorio es la misma a aquella que corre sobre una Palm o un Pocket PC. Vale la pena aclarar que así como SuperWaba puede ser instalado en los dispositivos móviles anteriormente descritos también puede ser instalado en sus respectivos emuladores.

Instalación de aplicaciones Los pasos requeridos para la instalación de una aplicación sobre el computador de escritorio son bastante similares a aquellos requeridos para la instalación de aplicaciones sobre la plataforma Pocket PC. Se debe crear un directorio para la aplicación bajo el directorio de la instalación de SuperWaba (C:\SuperWaba). El archivo .pdb de la aplicación debe ser colocado ahí, junto con cualquier librería local requerida por el programa. Al igual que en la plataforma Pocket PC, el archivo ejecutable de la aplicación se debe colocar bajo el directorio de instalación de SuperWaba. Además de realizar los pasos anteriores, para correr la aplicación sobre el computador de escritorio debe crearse un archivo .bat que siga la siguiente estructura: <ubicación_vm_sw> <nombre_clase_principal> <directorio_aplicación> <creador_id> Donde

• ubicación_vm_sw: la ruta donde se encuentra la máquina virtual de la aplicación.

• nombre_clase_principal: nombre de la clase principal de la aplicación. • directorio_aplicación: directorio donde se encuentra el .pdb y las

librerías locales de la aplicación. • creador_id: identificador de creación asignado tanto al .pdb como al

.prc/exe. Un ejemplo de tal archivo .bat es el siguiente: c:\SuperWaba\SuperWaba.exe UIGadgets UIGadgets DoHD Esta línea especifica que la máquina virtual de SuperWaba se encuentra en C:\SuperWaba, el nombre de la clase principal de la aplicación es UIgadgets, la carpeta en la que se encuentran las librerías locales y el .pdb de la aplicación es C:\SuperWaba\UIGadgets y el identificador de creación para la aplicación es DoHD.

Page 47: Documento Final de Tesis Entrega Final de Ciclo Terminal

44

3.4. Probar la Instalación de SuperWaba Una vez instalado SuperWaba es bueno probar la instalación para comprobar que no hubo errores en el proceso; esto es útil al momento de estar desarrollando una aplicación propia, ya que si se comprueba que la instalación de SuperWaba fue exitosa se puede reducir el conjunto de posibilidades de error únicamente a la aplicación que se está desarrollando. Para probar la instalación se va a construir e instalar una de las aplicaciones ejemplo que vienen con el SDK de SuperWaba. La aplicación seleccionada es GuiBuilder; una aplicación que facilita la creación de interfaces gráficas utilizando SuperWaba. Instalación de GuiBuilder La versión de SuperWaba con la que se está trabajando en el proyecto es la 4.5ª. Esta versión trae la siguiente estructura de directorios:

• SW_ROOT: directorio raíz

• SW_ROOT/docs: documentación del SDK • SW_ROOT/lib: liberías (entre las cuales se encuentran las que

componen la máquina virtual) • SW_ROOT/samples: ejemplos de aplicaciones desarrolladas usando

SuperWaba • SW_ROOT/src: archivos fuente de SuperWaba • SW_ROOT/utils: clases, jars, prcs útiles para el desarrollo de

aplicaciones • SW_ROOT/vm: archivos fuente de la máquina virtual

Dentro de esta estructura de directorios hay tres archivos particularmente importantes al momento de construir e instalar la aplicación de interés: build.xml, samplesTemplate.xml y build.xml. A pesar de que dos de ellos tienen el mismo nombre, no son el mismo archivo; el primer archivo mencionado contiene tareas para la construcción de componentes SuperWaba basados en Java y se encuentra bajo el directorio raíz; el segundo es una plantilla de archivo para la construcción de cualquiera de los ejemplos y se encuentra bajo SW_ROOT/samples; el tercer archivo es el script de ant propio de la aplicación a construir, y en nuestro caso se encuentra en SW_ROOT/samples/app/GuiBuilder. Las tareas de cada archivo relevantes para la construcción de GuiBuilder son mencionadas a continuación, enunciándose una breve descripción de las mismas:

1. build.xml – Propio de GuiBuilder

Page 48: Documento Final de Tesis Entrega Final de Ciclo Terminal

45

• Importa el archivo samplesTemplate.xml y define como tarea por defecto la tarea build.

2. samplesTemplate.xml – plantilla

• help : despliega una breve ayuda acerca de lo que contiene el archivo

• compile: llama a la tarea app-compile del build.xml inicial (aquel que se encuentra bajo el directorio raíz).

• build: llama a la tarea app-build del build.xml inicial (aquel que se encuentra bajo el directorio raíz).

• run: llama a la tarea app-run del build.xml inicial; esta tarea ejecuta la aplicación como si fuera un applet.

• Emulator: llama a la tarea app-emulator del build.xml inicial; corre la aplicación sobre el emulador.

• device: sube la aplicación (compilada) al dispositivo donde se va a correr.

• Clean: limpia el directorio en donde se almacenan todos los archivos .class.

3. build.xml – script principal de ant

• init: define propiedades útiles al momento de construir un proyecto

- propiedades relevantes al emulador de palm - propiedades relevantes al ofuscador de código - incluye las librerías de SuperWaba al momento de

compilación • test-resolutions: prueba todas las resoluciones en las que

puede correr SuperWaba. • require-build-dir: crea una serie de directorios importantes si

estos no han sido creados con anterioridad. • javadoc: construye la documentación javadoc de SuperWaba. • set-options: asigna opciones de compilación. • compile-libs: compila las librerías de extensión de SuperWaba. • build-libs: construye las librerías de extensión de SuperWaba

(llama a Warp) • build: construye todo (librerías, programas de ejemplo, etc.). • build-samples: construye los programas de ejemplo. • clean: elimina el directorio build (donde se amacenan los

archivos .class entre otros) • app-jopt: ofusca el contenido de un directorio y produce un

archivo .jar como resultado. • app-warp: ejecuta Warp para producir el archivo .pdb . • app-compile: compila una aplicación SuperWaba. • app-build: construye un aplicación SuperWaba. • app-clean: limpia el archivo build de la aplicación.

Page 49: Documento Final de Tesis Entrega Final de Ciclo Terminal

46

• app-emulator: ejecuta el emulador con la aplicación creada. • app-run: ejecuta la aplicación como un applet. • app-device: instala la aplicación en un dispositivo móvil.

Debido a que únicamente se quiere construir una de las aplicaciones que se encuentra bajo el directorio de aplicaciones prueba que viene con el SDK de SuperWaba, y para familiarizarse con SDK y el IDE, se creó un proyecto en Eclipse en donde se incluyeron los archivos fuente de la aplicación GuiBuilder. Se generó un nuevo archivo build.xml para este proyecto, haciendo uso por supuesto de los tres archivos xml anteriormente descritos. La estructura de directorios del nuevo proyecto posee la siguiente forma:

• Game o src

- GuiBuilder o build.xml o build.properties

Al ejecutar el comando ant build aparecerá junto a los archivos y directorios anteriormente mencionados el directorio bin, el cual contendrá los archivos necesarios para la instalación de la aplicación en el emulador (GuiBilder.prc y GuiBuilder.pdb). Además de estos dos archivos, para poder ejecutar la aplicación se necesitan otros dos archivos: XPlatIoUiUtil.pdb, PalmIoBuiltIn.pdb. Estos archivos se pueden encontrar en SW_ROOT/lib /xplat y SW_ROOT/lib /palm respectivamente. Una vez ejecutada la aplicación, la imagen que se debe obtener es la siguiente:

Figura 10 Figura 11 3.5. Desarrollo de una Aplicación SuperWaba El desarrollo de una aplicación en SuperWaba es muy similar a aquel de una aplicación escrita en Java; (luego de haber realizado un buen diseño) se inicia escribiendo el código fuente de la aplicación y luego se compilan los

Page 50: Documento Final de Tesis Entrega Final de Ciclo Terminal

47

archivos que componen la misma. De este punto en adelante las cosas varían un poco diferente para aplicaciones SuperWaba. Además de los archivos .class la aplicación a desarrollar necesita de unos archivos adicionales, entre los cuales se encuentran un archivo .pdb y otro .prc. El archivo .pdb va a contener tanto los archivos .class generados como cualquier bitmap que la aplicación utilice. En cuanto al archivo .prc, éste es el equivalente a los archivos .exe a los que tanto estamos acostumbrados; es el ejecutable de la aplicación y contiene el ícono que esta utiliza (además de otras cuantas cosas). Estos archivos adicionales que requiere una aplicación SuperWaba pueden ser generados utilizando unas herramientas que el mismo API/Lenguaje trae: Warp y ExGen. La primera se utiliza para generar el archivo .pdb mientras que la segunda hace lo correspondiente para el archivo .prc/exe. Ambas herramientas vienen al momento de descargar el SDK de SuperWaba y se encuentran en SW_ROOT/bin, donde SW_ROOT es el directorio raíz de la instalación de SuperWaba (donde se descomprimió el archivo que contenia el SDK). POSE y SuperWaba Si se pretende utilizar SuperWaba con POSE, algunos pasos adicionales deben seguirse (por recomendación de los desarrolladores del API/Lenguaje); se deben deshabilitar las siguientes casillas del menú Settings/Debugging del emulador26:

• Hardware Register Access • Proscribed Function Call • Screen Access

26 Tomado de: SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Page 51: Documento Final de Tesis Entrega Final de Ciclo Terminal

48

Figura 12

3.6. Warp y ExeGen Como se mencionó anteriormente, estas dos herramientas son fundamentales y necesarias durante la última fase de desarrollo de una aplicación SuperWaba. Warp es la herramienta encargada de generar a partir de todos los archivos .class que componen la aplicación el archivo .pdb ; ExeGen se encarga de hacer lo propio con el archivo .prc. A continuación se presenta un listado de opciones útiles al momento de manipular estas dos herramientas desde línea de comandos27.

27 Tomado de: SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki

Page 52: Documento Final de Tesis Entrega Final de Ciclo Terminal

49

Warp Warp es una aplicación desarrollada en Java. Debido a que la extensión que posee es .class, se debe hacer uso de Java para correr la aplicación. La manera de cómo utilizar la herramienta es la siguiente:

java Warp comando [opciones] archivoPdb [archivos] Los comandos que entiende Warp son los siguientes:

• c : crea un nuevo archivo pdb • l : lista los contenidos de un archivo pdb

Las opciones que se pueden utilizar con Warp son las siguientes:

• /? : desplegar la ayuda • /c : sobrescribir y asignar un identificador de creador de base de datos

(Creator ID) • /q : modo silencioso (no genera salidas a menos que sean errores) • /$ : habilitar el atributo de protección de copia de Palm OS • /x : especificar un listado de paquetes/clases que no serán incluidos. • /i : especificar un listado de paquetes/clases que serán las únicas

incluidas.

Además de archivos .class, Warp es capaz de recibir archivos .jar como entrada (en este caso todo lo contenido en el jar – archivos .class y bitmaps – será incluido en el .pdb ). Otro dato importante es el siguiente: si no se especifica un Creator Id, la herramienta generará uno automáticamente y a partir del nombre del archivo .pdb . En el caso de que ningún archivo .class sea especificado, Warp buscará alguno cuyo nombre coincida con el nombre del archivo .pdb a generar. ExeGen Al igual que Warp, ExeGen también es una aplicación Java y por lo tanto debe ser llamada de similar manera:

java ExeGen [options] archivoExeoPrc [clase-ventana-principal] [archivoPdb] Las opciones que acepta la herramienta son las siguientes:

http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Page 53: Documento Final de Tesis Entrega Final de Ciclo Terminal

50

• /? : desplegar la ayuda • /$ : habilitar el atributo de protección de copia de Palm OS • /C : sobrescribir y asignar un identificador de base de datos (Creador

ID) • /H : asignar la altura de la ventana principal de la aplicación • /W : asignar el ancho de la ventana principal de la aplicación • /V : asignar la versión de la aplicación • /E : genera archivos .exe (para Windows CE y Pocket PC) • /I : especifica el prefijo del ícono (nombre del archivo) • /T : asigna el título de la aplicación (para Windows CE y Pocket PC)

Debido a que la herramienta necesita que sea especificado el archivo .pdb , es necesario ejecutar primero Warp antes de llamar ExeGen. Si no se especifica un archivo .pdb , ExeGen buscará uno con igual nombre al del archivo .prc/.exe (esto mismo aplica para el nombre de la clase de la vaentana principal). En el caso en que no se especifiquen extensiones para los archivos que espera la herramienta, estas serán generadas automáticamente. Algunas cosas que se deben tener en cuenta al momento de utilizar Exgen:

1. Si se espefica 0 para /W o /H se utilizarán dimensiones por defecto (las cuales varían según la plataforma en la que se esté ejecutando la aplicación).

2. Bajo la carpeta /utils se enuentran una serie de íconos que pueden ser utilizados por las aplicaciones a desarrollar.

3.7. IDEs y SuperWaba

Son varias las IDEs con las que se puede trabajar para el desarrollo de aplicaciones SuperWaba. Por familiaridad y funcionalidad ofrecida, se escogió Eclipse como la IDE de trabajo para el presente proyecto. Las otras serán brevemente mencionadas, mientras que el trabajo con Eclipse va a ser explorado un poco más a fondo. El listado de IDEs consideradas fue el siguiente:

• NetBeans / Forte • JBuilder 6 • Visual Café • Eclipse • Microsoft Visual J++

Page 54: Documento Final de Tesis Entrega Final de Ciclo Terminal

51

• Tauschke MobileCreator

Eclipse y SuperWaba La versión de Eclipse con la que se va a trabajar es la 3.0. Las dos opciones que ofrece este IDE para el desarrollo de aplicaciones SuperWaba son las siguientes:

1. Creando un proyecto Java y adicionarle el jar de SuperWaba al classpath (entre otras cosas).

2. Instalar el plugin de SuperWaba y crear un proyecto SuperWaba. Para el proyecto se escogió la alternativa del plugin, y los pasos a seguir (en Eclipse 3.0) son los siguientes:

1. Abrir Eclipse 2. Help -> Software Updates -> Find and Install 3. Seleccionar Search for new features to install para buscar el plugin 4. Hacer click en New Remote Site… para adicionar el URL del sitio de

donde se descargará el plugin 5. Darle cualquier nombre al sitio, y digitar http://superwaba-

ide.sourceforge.net en el campo de la dirección. 6. Seleccionar la versión del plugin a instalar. 7. Dar clic en Finís para terminar la operación.

Luego de esto se está listo para empezar el desarrollo de aplicaciones en SuperWaba.

Page 55: Documento Final de Tesis Entrega Final de Ciclo Terminal

52

VI. MobileGL

MobileGL es la librería gráfica móvil de la que tanto hemos hablado a lo largo de este documento. Su nombre se debe precisamente al hecho de que es un proyecto que busca la construcción y desarrollo de una librería gráfica orientada cien por ciento a los dispositivos móviles. Aunque este es el principal objetivo, debido a que SuperWaba todavía no ha sido migrado a dispositivos como teléfonos celulares, el verdader campo de acción de la librería se restringe a las asistentes personales digitales o PDAs. MobilGL pretende en un futuro conseguir lo que OpenGL ha logrado para los computadores de escritorios. Es una labor bastante difícil, más aún si notamos el hecho de que MobileGL trabaja sobre otra capa de software (SuperWaba); OpenGL trabaja directamente sobre el hardware de la máquina, algo que le da más flexibilidad y eficiencia. A pesar de esto, es un proyecto bastante viable y de utilidad tanto en el campo didáctico como en el de desarrollo de aplicaciones más ambiciosas. Los dos pilares en torno a los cuales gira esta librería gráfica móvil son OpenGL y SuperWaba. Ambos fueron ampliamente detallados en secciones anteriores por lo que se asume un buen entendimiento de los mismos. El modo a proceder en este capítulo es el siguiente:

• Estructura de directorios del proyecto • Funciones implementadas • Diagrama de clases de la librería • Compilación y Ejecución • Instalación

1. Estructura de Directorios del Proyecto Desde un principio el ambiente de desarrollo escogido para el proyecto fue Eclipse. En la siguiente imagen se puede apreciar la estructurad de directorios que componen la librería, cada uno de ellos detallado a continuación:

Page 56: Documento Final de Tesis Entrega Final de Ciclo Terminal

53

Figura 13

• MobileGL: directorio raíz de la aplicación. Bajo el se encuentran los

directorios src, deploy, docs, icons y temp, además de los archivos build.xml y build.properties.

• src: directorio que contiene todas las clases que componen la aplicación.

• deploy: directorio con los achivos .pdb , .prc y .exe (para Pocket PC) necesarios para la instalación de la librería.

• docs: directorio con la documentación en html de la librería. • temp: directorio de almacenamiento de contenido temporal (donde se

guarda el archivo .jar generado a partir de las clases que componen la aplicación).

• icons: directorio de almacenamiento de íconos utilizados por la aplicación. En este momento no hay ninguno por lo que el directorio se encuentra vacío.

• build.xml: archivo ant para automatizar el proceso de desarrollo de la librería.

Page 57: Documento Final de Tesis Entrega Final de Ciclo Terminal

54

• build.properties: archivo de propiedades utilizado por el archivo build.xml.

2. Funciones Implementadas El listado de funciones implementadas por MobileGL es presentado a continuación. La mayoría de ellas han sido descritas anteriormente en la sección dedicada a OpenGL, pero aquí se retoman y detallan a un nivel mayor. glBegin Esta función, junto con glEnd, delimita los vértices de una o varias primitivas. La especificación de la función es la siguiente: void glBegin(int mode); donde mode debe ser una de las siguientes constantes:

• GL_LINE_LOOP: dibuja un grupo interconectado de segmentos de línea desde el primer vértice hasta el último, cerrando el circuito. Vértices n y n+1 definen la línea n. La última línea está definida por los vértices N y 1. Se dibujan N líneas.

• GL_LINE_STRIP: dibuja un grupo interconectado de segmentos de línea desde el primer vértice hasta el último. Vértices n y n+1 definen la línea n. Se dibujan N-1 líneas.

• GL_LINES: trata cada pareja de vértices como segmentos de línea independientes. Vértices 2n-1 y 2n conforman la línea n. Se dibujan N/2 líneas.

• GL_POINTS: trata cada vértice como un punto aislado. El vértice n define el punto n. Se dibujan N puntos.

• GL_POLYGON: dibuja un polígono convexo. Vértices 1 hasta N definen el polígono.

• GL_QUAD_STRIP: dibuja un grupo interconectado de cuadriláteros. Se define un cuadrilátero por cada pareja de vértices especificada después de una pareja. Vértices 2n-1, 2n, 2n+2 y 2n+1 definen el cuadrilátero n. Se dibujan N/2 - 1 cuadriláteros.

• GL_QUADS: trata a cada grupo de cuatro vértices como un cuadrilátero independiente. Vértices 4n-3, 4n-2, 4n-1 y 4n definen el cuadrilátero n. Se dibujan N/4 cuadriláteros.

• GL_TRIANGLE_FAN: dibuja un grupo interconectado de triángulos. Se dibuja un triángulo por cada vértice presentado después de dos vértices. Vértices 1, n+1 y n+2 definen el triángulo n. Se dibujan N-2 triángulos.

Page 58: Documento Final de Tesis Entrega Final de Ciclo Terminal

55

• GL_TRIANGLE_STRIP: dibuja un grupo interconectado de triángulos. Se dibuja un triángulo por cada vértice presentado después de dos vértices. Para n impar, vértices n, n+1, y n+2 definen el triángulo n. Para n par, vértices n+1, n y n+2 definen el triángulo n. Se dibujan N-2 triángulos.

• GL_TRIANGLES: trata cada tripleta de vértices como un triángulo independiente. Vértices 3n-2, 3n-1 y 3n definen el triángulo n. Se dibujan N/3 triángulos.

Cada una de los modos de dibujo es implementado por la librería gráfica móvil. Esta función es verdaderamente útil debido a que determina de manera directa la forma en la que serán dibujados los objetos de la escena. La clase que implementa esta función se llama sys.GLStateMachine y será descrita en una futura sección, donde también se detallarán el resto e clases que componen la librería. La implementación de esta función realiza las siguientes tareas:

• Asigna el modo en el cual se están dibujando los objetos. • Traslada el origen del sistema de coordenadas al punto que

corresponde al centro del área de cliente de la ventana. Este punto es diferente a (0,0). En este caso (0,0) representa la esquina superior izquierda de la ventana.

glEnd Delimita junto con glBegin un conjunto de vértices que hacen parte de una o varias primitivas. Su especificación es la siguiente: void glEnd(); glBegin marca el inicio de la especificación de vértices y glEnd marca el fin. La clase que implementa esta función es también sys.GLStateMachine. Además de marcar el final de la especificación de vértices, la implementación de esta función realiza las siguientes tareas:

• Chequea que se haya generado una llamada previa a glBegin. • Según la variable especificada en glBegin, llama a una de las

siguientes funciones para realizar la correcta interpretación de los vértices especificados (dibuja de una manera adecuada las primitivas a las que corresponden los vértices): drawLineLoop(), drawLineStrip(), drawPoints(), drawLines(), drawTriangles(), drawTriangleFan(), drawTriangleStrip(), drawQuads(), drawQuadStrip() o drawPolygon(). Estos métodos hacen parte de la misma clase a la que pertenece glEnd.

Page 59: Documento Final de Tesis Entrega Final de Ciclo Terminal

56

glClear Limpia los buffers dentro del viewport. En OpenGL hay varios buffers, y para cada uno hay una variable de estado que indica el valor al cual serán limpiados de ser llamada esta función. Para el caso particular de la librería solo se tiene en cuenta el buffer de color. Las especificación de esta función es la siguiente: void glClear (int mask); donde mask puede ser una combinación lógica (haciendo uso del operador ‘|’) de los siguientes valores:

• GL_ACCUM_BUFFER_BIT: determina que se debe limpiar el buffer de acumulación.

• GL_DEPTH_BUFFER_BIT: determina que se debe limpiar el buffer de profundidad.

• GL_COLOR_BUFFER_BIT: determina que se debe limpiar el buffer de color.

• GL_STENCIL_BUFFER_BIT: determina que se debe limpiar el buffer de plantillas.

La implementación real de este método valida que la máscara especificada haga referencia a por lo menos una de las constantes anteriormente mencionadas. Si este no es el caso reporta el error e ignora el comando. De ser correcta la máscara ignora todas las constantes diferentes de GL_COLOR_BUFFER_BIT; al toparse con esta constante la librería limpia el buffer de color (lo que representa el redibujar el área cliente de la ventana con el color glClearColor Especifica el valor de limpieza para los buffers de color. Los valores deben encontrarse en el rango [0,1]. El color asignado por esta función es el que va a utilizar glClear al momento de limpiar el buffer de color. Su especificación es la siguiente: void glClearColor (float red, float green, float blue, float alpha); El valor alpha es utilizado en OpenGL más no en la presente librería gráfica móvil debido a que SuperWaba no permite asociar este valor a los colores con los que trabaja. La implementación real de la función únicamente valida que los valores especificados se encuentren en el rango permitido, haciendo los siguientes ajustes en el caso en que esto no suceda:

• Si los valores son mayores a 1, el valor utilizado es 1.

Page 60: Documento Final de Tesis Entrega Final de Ciclo Terminal

57

• Si los valores son menores a 0, el valor utilizado es 0. glGet En la sección dedicada a OpenGL se detallaron algunas variables de estados y se toco el tema de la función glGet. Se enunciaron las diferentes versiones de la función y se detalló que tipo de variables de estado podían ser consultadas con que tipo de funciones. La especificación de cada una de ellas se presenta a continuación, y el listado de las variables de estado que se pueden consultar con las mismas puede ser revisado en la sección previa acerca de OpenGL o en la documentación en html de la librería gráfica móvil. float[] glGetFloatv(int pname); int[] glGetIntegerv(int pname); double[] glGetDoublev(int pname); boolean[] glGetBooleanv(int pname); glGetError Permite consultar el error producido por la última operación gráfica desarrollada. Es probable que se hayan realizado varias operaciones y que más de una haya producido un error; en este caso los errores se acumulan, y una llamada a glGetError siempre devolvería el último error ocurrido. Llegado el caso de no haber más errores por reportar, la función devolverá la constante simbólica GL_NO_ERROR. La siguiente es la especificación de la función: int glGetError(); glVertex La descripción tanto de glBegin como de glEnd fue clara al precisar que este conjunto de funciones delimitaban la especificación de los vértices de una primitiva o conjunto de primitivas. En ese momento no se detalló la manera en que esta especificación de vértices se llevaba a cabo. La manera de hacer esto es a través de una de las tantas versiones de la función glVertex ofrecida por la librería gráfica. Dependiendo de la función a utilizar se especifican valores para 2, 3 o hasta 4 coordenadas. La especificación de las versiones de glVertex implementadas por la librería son las siguientes: void glVertex2d(double x, double y); void glVertex2f(float x, float y); void glVertex2i(int x, int y); void glVertex2s(short x, short y);

Page 61: Documento Final de Tesis Entrega Final de Ciclo Terminal

58

void glVertex3d(double x, double y, double z); void glVertex3f(float x, float y, float z); void glVertex3i(int x, int y, int z); void glVertex3s(short x, short y, short z); void glVertex2dv(final double[] v); void glVertex2fv(final float[] v); void glVertex2iv(final int[] v); void glVertex2sv(final short[] v); void glVertex3dv(final double[] v); void glVertex3fv(final float[] v); void glVertex3iv(final int[] v); void glVertex3sv(final short[] v); Las funciones que reciben dos coordenadas realizan la misma función que aquellas que reciben tres, con la diferencia que para las primeras el parámetro z es establecido a 0. La implementación de los métodos lo único que hace es agregar el vértice especificado a una pila de vértices que será desocupada al momento de dibujar las primitivas. glFlush El propósito de esta función es el de forzar la ejecución de cualquier comando aplicado en un buffer de ejecución. Por defecto en los computadores de escritorio almacenan todos los comandos gráficos y no los ejecutan hasta que explícitamente se de la orden de hacerlo. La manera que ofrece OpenGL para tal ejecución es a través de esta función. La implementación que le da la librería gráfica móvil a esta función es la de únicamente validar que no sea llamada entre un glBegin y un glEnd. De resto no hace más nada debido a que seria ineficiente apilar todos los comandos ejecutados teniendo en cuenta las limitaciones de memoria con las que cuentan los dispositivos hacia los cuales esta orientada la librería. Su especificación es la siguiente: void glFlush(); glColor Esta función le especifica a la librería gráfica el color en el que deben ser dibujados los vértices que componen los objetos de la escena. El número distinto de versiones de esta función suma 32, pero aquellas implementadas por la librería son las siguientes: void glColor3b(byte red, byte green, byte blue); void glColor3d(double red, double green, double blue); void glColor3f(float red, float green, float blue);

Page 62: Documento Final de Tesis Entrega Final de Ciclo Terminal

59

void glColor3i(int red, int green, int blue); void glColor3s(short red, short green, short blue); void glColor3bv(final byte[] v); void glColor3dv(final double[] v); void glColor3fv(final float[] v); void glColor3iv(final int[] v); void glColor3sv(final short[] v); glPolygonMode Esta función, junto con glBegin determina la manera en la que serán dibujados los objetos de la escena. A diferencia de glBegin, esta función no especifica la forma de interpretar los vértices (como líneas, polígonos, etc.) sino la manera en la que serán dibujados los mismos. Hay tres formas de dibujar una figura: dibujar cada uno de los vértices como un punto en pantalla, dibujar la figura alambrada de la figura y rellenar la figura. De las tres la única que no es implementada por la librería es la última, debido a la dificultad que representa el rellenar un polígono cualquiera (hay algoritmos especiales que facilitan esta labor pero no son considerados en esta etapa del proyecto). La especificación de la función es la siguiente: void glPolygonMode(int face, int mode); donde face especifica el tipo de polígonos a las que el modo de dibujo va a aplicar y puede ser una de las siguientes constantes:

• GL_FRONT: especifica un polígono delantero (cara delantera). • GL_BACK: especifica un polígono trasero (cara trasera). • GL_FRONT_AND_BACK: especifica polígonos tanto delanteros como

traseros. El segundo parámetro especifica el modo en el que serán dibujados los polígonos y puede ser una de las siguientes constantes:

• GL_POINT: vértices de polígonos que son marcados como iniciadores de un borde fronterizo son dibujados como puntos. La rasterización de los puntos se ve controlada por atributos como GL_POINT_SIZE y GL_POINT_SMOOTH (estas dos constantes no son implementadas por la librería gráfica móvil debido a que SuperWaba no hace posible el controlar el tamaño de los puntos a dibujar en pantalla).

Page 63: Documento Final de Tesis Entrega Final de Ciclo Terminal

60

• GL_LINE: los bordes fronterizos de los polígonos son dibujados como (segmentos de) líneas. La rasterización de las líneas se ve controlada por atributos como GL_LINE_WIDTH y GL_LINE_SMOOTH (estas dos constantes no son implementadas por la librería debido a que SuperWaba no ofrece soporte nativo para hacer esas operaciones y no son prioridad para esta etapa del proyecto).

• GL_FILL: el interior de los polígonos es rellenado. La rasterización del polígono se ve controlada por atributos como GL_POLYGON_STIPPLE y GL_POLYGON_SMOOTH. El relleno de polígonos no ha sido incorporado a la librería, al igual que estas dos constantes debido a que el manejo de polígonos es un poco primitivo en esta etapa del proyecto.

glRotate Permite multiplicar la matriz actual por una matriz de rotación. Hay dos implementaciones de esta función: void glRotated(double angle, double x, double y, double z); void glRotatef(float angle, float x, float y, float z); Donde angle es el ángulo de rotación y tanto x, y y z determinan el eje de rotación. Para la librería este eje debe ser uno de los ejes de coordenadas bien defindos (x, y o z). glTranslate Permite multiplicar la matriz actual por una matriz de traslación. Hay dos implementaciones de esta función: void glTranslated(double x, double y, double z); void glTranslatef(float x, float y, float z); dode x, y y z especifican la traslación para cada uno de los respectivos ejes de coordenadas. glPushMatrix Esta función es provista por la librería gráfica para salvar el estado de la matriz actual (aquella que se encuentra en el tope de la pila de matrices sobre la cual recaen todas las transformaciones realizadas). La implementación real lo único que realiza es una copia de la matriz actual para luego apilarla junto a las demás; la nueva matriz actual es la copia, por lo que cualquier transformación afecta la copia. Para restablecer el estado a aquel justo en el momento en que se hizo la copia se debe usar la función glPopMatrix. La especificación de glPushMatrix es la siguiente:

Page 64: Documento Final de Tesis Entrega Final de Ciclo Terminal

61

void glPushMatrix(); glPopMatrix Esta función es provista por la librería gráfica para restablecer el estado de la matriz de transformación a un estado anterior. La implementación real lo único que hace es remover la pila matriz que se encuentra sobre el tope de la pila de matrices. La especificación de la función es la siguiente: void glPopMatrix(); 3. Diagrama de Clases de la Librería A continuación se presenta el diagrama de clases de la librería. Además de este diagrama se adjuntan otros diagramas que dan más claridad sobre la manera en la que fue diseñada la librería

3.1. Diagrama de Paquetes

Figura 14

Los paquetes gl y glu contienen interfaces que especifican funciones a ser prestadas por la librería gráfica. Realmente el primero especifica este tipo de funciones; el segundo especifica un conjunto de funciones auxiliares a ser

Page 65: Documento Final de Tesis Entrega Final de Ciclo Terminal

62

implementadas bien sea por la librería gráfica o por otro componente (en la actualidad el paquete glu se encuentra vacío). El paquete tests realiza algunas pruebas sobre clases encontradas tanto en el paquete util como en el gl. Realmente este paquete realiza pruebas sobre clases del paquete sys que implementan interfaces del paquete gl. Para concluir la descripción, el paquete sys hace uso tanto de los paquetes gl y util para desarrollar sus funciones. 3.2. Diagrama del Paquete GL El diagrama de este paquete es presentado en la siguiente página debido al gran tamaño de la imagen.

Page 66: Documento Final de Tesis Entrega Final de Ciclo Terminal

63

Figura 15

Las funciones de la interfaz GLEngine reciben constantes especificadas en la interfaz GLConstants.

Page 67: Documento Final de Tesis Entrega Final de Ciclo Terminal

64

3.3. Diagrama del paquete SYS

Figura 16

En el diagrama no se incluyen aquellas funciones públicas de la clase que únicamente son el resultado de implementaciones de interfaces.

Page 68: Documento Final de Tesis Entrega Final de Ciclo Terminal

65

3.4. Diagrama del paquete UTIL El diagrama del paquete se presenta en la siguiente página debido al gran tamaño de la imagen.

Page 69: Documento Final de Tesis Entrega Final de Ciclo Terminal

66

Figura 17

Page 70: Documento Final de Tesis Entrega Final de Ciclo Terminal

67

En este paquete se encuentran aquellas clases utilizadas al momento de realizar operaciones matemáticas involucradas con matrices y transformaciones. La clase GLMatrix además de encapsular las propiedades de una matriz es capaz de calcular las matrices para las transformaciones de traslación, rotación y escalación dados los parámetros necesarios. Las clases con color rosa pertenecen al paquete sys y aquella de color amarillo pertenece al paquete gl. 3.5. Diagrama del paquete TESTS El diagrama de este paquete se presenta en la siguiente página debido al gran tamaño de la imagen.

Page 71: Documento Final de Tesis Entrega Final de Ciclo Terminal

68

Figura 18

Page 72: Documento Final de Tesis Entrega Final de Ciclo Terminal

69

Estas tres clases desarrollan unas pruebas fundamentales y que aseguran un mínimo y correcto funcionamiento de las clases sobre las cuales la librería basa su funcionamiento. Las clases sometidas a pruebas fueron aquellas involucradas con operaciones matemáticas como la multiplicación de matrices y de vértices. Aquellas operaciones relacionadas con dibujo en pantalla no pudieron probarse debido a que tienen una estricta relación con clases de SuperWaba, plataforma que en su versión actual no ofrece manera para realizar algún tipo de pruebas. La siguiente versión de SuperWaba anunció un paquete que permite realizar pruebas del estilo JUnit sobre sus clases. 4. Compilación y Ejecución La compilación y ejecución de la librería se facilita enormemente debido a un archivo ant desarrollado exclusivamente para la automatización de estos procesos. El nombre del archivo es build.xml y trabaja conjuntamente con otro archivo llamado build.properties, el cual agrupa todas las propiedades con las cuales el script de automatización trabaja. Las tareas de tal archivo se listan a continuación:

• usage: lista todas las tareas disponibles. • init: inicializa las propiedades usadas por este script. • compile-args-check: verifica la existencia de ciertas propiedades de

compilación. • set-options: asigna las opciones al momento de compilar. • compile: ompila la librería. • compile-tests: compila el paquete TESTS. • jar: Empaqueta la aplicación en un archivo .jar. • retroguard: ofusca el contenido del archivo .jar con las clases de la

aplicación. • yguard: ofusca el contenido de un jar usando yGuard. • warp: genera el archivo .pdb a partir del archivo .jar. • exegen: genera el archivo .prc a partir de los archivos .pdb y .jar. • build: construye la aplicación (ejecuta Warp y Exen sobre las clases

compiladas). • deploy: copia los archivos .prc y .pdb a DEPLOY. • deploy_ppc: copia los archivos .exe y .pdb a DEPLOY. • javadoc: genera la documentación en html de la librería. • run-glmatrix-test: corre las pruebas de la clase sys.GLMatrix. • run-glstack-test: corre las pruebas de la clase sys.GLStack. • run-glengine-test: corre las pruebas de la clase sys.GLStateMachine. • clean-gl: elimina el contenido dinámico del paquete GL.

Page 73: Documento Final de Tesis Entrega Final de Ciclo Terminal

70

• clean-glu: elimina el contenido dinámico del paquete GLU. • clean-sys: elimina el contenido dinámico del paquete SYS. • clean-tests: elimina el contenido dinámico del paquete TESTS. • clean-temp: elimina el contenido dinamico del directorio TEMP. • clean-deploy: elimina el contenido del directorio DEPLOY. • clean-docs: elimina el contenido del directorio DOCS. • clean-util: elimina el contenido del directorio UTIL. • clean: elimina el contenido dinámico del proyecto.

La manera de utilizar el archivo es situarse sobre el directorio que lo contiene y digitar lo siguiente: ant <nombre_de_tarea> donde el nombre pertenece al conjunto de tareas anteriormente especificadas. La tarea de nuestro interés tiene como nombre deploy, y se encarga de realizar tanto la compilación como la ejecución de la librería, copiando los archivos de interés (aquellos necesarios para instalar la librería) al directorio deploy que se encuentra bajo el directorio raíz. 5. Instalación La instalación de la librería depende de la plataforma sobre la cual va a ser utilizada la misma. Debido a que Palm OS fue la plataforma piloto a través de todo el desarrollo del proyecto, el proceso a detallar es aquel que culmina con la instalación de la librería sobre esta plataforma. Instalación sobre Palm OS Una vez compilada la librería se deben tener los siguientes archivos bajo el directorio deploy del proyecto:

• MobileGL.pdb • MobileGL.prc • MobileGL.lnk • MobileGL.exe

Los últimos dos nos interesan en el caso de instalar la librería sobre Pocket PC. En los siguientes párrafos nos concentraremos en los primeros dos (el primero se debe instalar siempre sin importar la plataforma). Para el caso del proyecto no se cuenta con un dispositivo real, por lo que la instalación se hará sobre el emulador. Lo primero que se debe hacer es abrir el emulador y seleccionar la opción que permite instalar un archivo sobre el mismo (este paso fue detallado en la sección que detalló la instalación de SuperWaba

Page 74: Documento Final de Tesis Entrega Final de Ciclo Terminal

71

sobre Palm OS). Esto se debe hacer dos veces; una para instalar el archivo MobileGL.pdb y la otra para instalar el archivo MobileGL.prc. El resultado debe ser el siguiente:

Figura 19 Figura 20 Figura 21 Con esto se completa la instalación de la librería gráfica móvil. Lo único que se debe hacer al momento de crear una aplicación es referenciar el archivo .jar de la librería gráfica móvil. El nombre de este archivo es MobileGL.jar. Más acerca de esto en la sección que detallará el caso de estudio para la librería o aplicación de demostración.

Page 75: Documento Final de Tesis Entrega Final de Ciclo Terminal

72

VII. Caso de Estudio La idea del caso de estudio es la de desarrollar una manera de probar el correcto funcionamiento de la librería gráfica móvil desarrollada. Como idea del director del proyecto se escogió un caso de pruebas que pudiera agrupar todas aquellas funcionalidades que deben hacer parte de la librería gráfica al término de esta primera etapa. El caso de estudio entonces consiste en el desarrollo de un robot alambrado en donde los brazos y antebrazos pudiesen ser girados toda las veces que el usuario lo deseara. Esta sección se detallará de la siguiente forma:

• Descripción del modelo jerárquico a implementar. • Estructura de directorios del proyecto • Funciones implementadas • Diagrama de clases del caso de estudio • Compilación y Ejecución • Instalación

1. Descripción del modelo jerárquico a implementar Como fue descrito anteriormente, el caso de pruebas consiste en el desarrollo de un robot alambrado y brazos con la posibilidad de ser rotados. Se define una rutina para el dibujo de rectángulos tridimensionales, y cada una de las partes del robot es dibujada haciendo uso de tal rutina. La descripción del modelo jerárquico es la siguiente:

Figura 22

Page 76: Documento Final de Tesis Entrega Final de Ciclo Terminal

73

El la sección dedicada a las funciones implementadas para el caso de estudio veremos que además de la función principal (la que construye el modelo y lo despliega en pantalla) existen otras dos funciones encargadas de dibujar las piernas y los brazos. Antes de dibujar cada hijo del torso se graba el estado de la matriz actual haciendo uso de la funcion glPushMatrix. Esto hace posible que cada uno de los hijos pueda ser dibujado con respecto su padre sin tener en cuenta si es el primer o último hijo a ser dibujado. Una vez se dibuja un hijo el estado anterior vuelve a ser reestablecido haciendo uso de la función glPopMatrix. Los hijos que a su vez tienen hijos no necesitan salvar el estado actual y por el contrario necesitan que todas las transformaciones sean acumulativas. Esto es lo que verdaderamente hace posible la construcción del modelo. Según la imagen podemos determinar entonces que

• El torso es el padre de la cabeza, base del brazo derecho, base del brazo izquierdo, base de la pierna derecha y base de la pierna izquierda.

• La base del brazo derecho es padre del antebrazo derecho. • El antebrazo derecho es padre de la mano derecha. • La base del brazo izquierdo es padre del antebrazo izquierdo. • El antebrazo izquierdo es padre de la mano izquierda. • La base de la pierna derecha es padre del segmento de la pierna

derecha. • El segmento de la pierna derecha es padre del pie derecho. • La base de la pierna izquierda es padre del segmento de la pierna

izquierda. • El segmento de la pierna izquierda es padre del pie izquierdo.

Una imagen del robot (modelo a dibujar) es presentada a continuación:

Figura 23

Page 77: Documento Final de Tesis Entrega Final de Ciclo Terminal

74

2. Estructura de directorios del proyecto La estructura de directorios para el caso de estudio es bastante más sencilla que aquella descrita para la librería móvil. De hecho únicamente presenta un paquete con una única clase. Esto es debe a que la mayoría del desarrollo que apoya el caso de estudio se encuentra presente en la librería gráfica móvil. Este es un gran avance, ya que el código a desarrollar para realizar un tipo de proyectos como este no es muy diferente al código a desarrollar para una aplicación gráfica basada en OpenGL. La estructura de directorios es presentada a continuación:

Figura 24

Cada uno de los directorios es descrito a continuación:

Page 78: Documento Final de Tesis Entrega Final de Ciclo Terminal

75

• src: contiene el código fuente del proyecto. Para este proyecto el único fuente que hay es una clase en Java contenida en un único paquete. La clase se llama DemoApp y el paquete demo.

• build: contiene las clases compiladas del proyecto. Debido a que solo hay una clase para el proyecto solo va a haber entonces un archivo .class.

• icons: archivo con los íconos del proyecto. Al igual que para la librería gráfica, esta carpeta se encuentra vacía.

• temp: archivo con contenido temporal del proyecto. En esta carpeta se almacena el archivo DemoApp.jar con las clases empaquetadas del proyecto.

Además de estos directorios, bajo el directorio principal del proyecto se encuentran los siguientes archivos:

• build.xml: archivo que automatiza el proceso de desarrollo para el proyecto.

• build.properties: archivo con un conjunto de propiedades utilizadas por el script build.xml.

• MobileGL.jar: archivo que empaqueta las clases compiladas de la librería gráfica móvil. Sin este archivo el proyecto no se hubiese podido haber desarrollado.

Comos se puede apreciar, la estructura de directorios es bastante simple. Todo se debe gracias a la librería gráfica móvil, la cual simplifica mucho del trabajo que deben realizar los programadores que deseen desarrollar aplicaciones gráficas haciendo uso de esta librería. 3. Funciones implementadas Las funciones que hacen parte este proyecto son las siguientes: drawSegment Esta función es la encargada de dibujar un rectángulo tridimensional en pantalla. Los rectángulos son la base de todas las figuras que componen el robot (el torzo, la cabeza, los brazos y piernas, las manos y los pies). La implementación hace llamados a las funciones glBegin, glVertex3f y glEnd del objeto de tipo GLEngine que hace parte de la clase. Un mejor entendimiento acerca de la manera en que deben construirse los programas que hagan uso de la librería gráfica cuando se detalle el diagrama de clases del proyecto. La especificación de la función es la siguiente: void drawSegment(float width, float height, float depth);

Page 79: Documento Final de Tesis Entrega Final de Ciclo Terminal

76

donde width, height y depth representan el ancho, alto y profundidad del segmento respectivamente. drawRobotArm Es la función encargada de dibujar un brazo del robot. Según el modelo jerárquico estudiado, el brazo esta conformado por tres partes: la base, el antebrazo y la mano. Cada una de estas partes es representada como un rectángulo tridimensional dibujado con la función drawSegment. Para colocar las partes en su lugar adecuado hay que hacer uso de transformaciones geométricas, precisamente de las funciones de rotación y traslación que ofrece el objeto de tipo GLEngine, objeto que hace parte de la clase. La especificación de la función es la siguiente: void drawRobotArm(float baseRotation, float armSegmentRotation); donde baseRotation y armSegmentRotation representan el ángulo inicial de rotación que va a tener el segmento del brazo con respecto a la base del mismo. Estos ángulos son necesarios debido a que uno de los requisitos del caso de prueba era que los brazos pudiesen rotarse según la interacción del usuario con el programa. drawRobotLeg Es la función encargada de dibujar las piernas del robot. Cada una de las partes de la pierna es un rectángulo tridimensional dibujado con la función drawSegment. Para colocar las partes de la pierna en su lugar es necesario hacer uso de transformaciones geométricas (de hecho son las mismas que utiliza la función encargada de dibujar los brazos). La especificación de la función es la siguiente: void drawRobotLeg(); Las dimensiones de cada una de las partes de la pierna son atributos de la clase principal de la aplicación. drawScene Es la función encargada de dibujar la escena (el robot). La función llama a drawSegment para dibujar tanto el torso como la cabeza, luego llama a drawRobotArm y drawRobotLeg para dibujar cada uno de los brazos y piernas. Para colocar cada una de las partes en su lugar correspondiente la función hace uso de transformaciones geométricas. Al igual que en OpenGL, el efecto de animaciones consigue variando las transformaciones de los objetos que hacen parte de la escena y luego redibujando la misma. En este caso lo que necesitamos es que los brazos puedan girar, por lo que lo único

Page 80: Documento Final de Tesis Entrega Final de Ciclo Terminal

77

que varía cuando el usuario selecciona una de las barras de desplazamiento es el ángulo de ya sea los antebrazos o las bases de los brazos. La especificación de la función es la siguiente: void drawScene() ; No recibe ningún parámetro debido a que todas las variables que necesita hacen parte de la clase principal como atributos de la misma. onDisplay Es una de las funciones llamada automáticamente por la librería gráfica cada vez que se desee dibujar algo sobre la ventana de una aplicación gráfica. Si no se implementa esta función lo único que se verá en la ventana es un fondo negro. La implementación de esta función para el proyecto únicamente llama a la función drawScene, la cual se encarga de dibujar los objetos en pantalla. Su especificación es la siguiente: void onDisplay(); Esta función se encuentra en la interfaz sys.GLWindow, de la cual extiende la clase GLBaseWindow (esta clase hace parte de la librería gráfica y debe ser extendida por toda aplicación que quiera hacer uso de la librería). addGUIComponents Es otra de las funciones que es llamada automáticamente por la librería. Este es el lugar donde cualquier componente de interfaz gráfica debe ser agregado so pena de que jamás sea desplegado y visible. La librería gráfica llama a esta función luego de haber dibujado la escena, asegurándose de que cada uno de los componentes que ahí se agregue sea visible. Si la ventana de la aplicación no tiene componentes GUI no es necesario implementar esta función. La implementación por defecto suministrada por la clase GLBaseWindow no realiza ninguna tarea. Esta función también hace parte de la interfaz sys.GLWindow. Su especificación es la siguiente: void addGUIComponents(); handleEvent Función llamada automáticamente por la librería gráfica y encargada del manejo de eventos de la aplicación. Una vez ocurrido un evento, la librería lo atrapa y se lo suministra a este método. De aquí en adelante lo que suceda depende de la aplicación gráfica misma. Los eventos que pueden ocurrir son los mismos que pueden ocurrir para una aplicación SuperWaba tradicional y su estudio no es tema de este documento. Para mayor información al

Page 81: Documento Final de Tesis Entrega Final de Ciclo Terminal

78

respecto favor remitirse a las referencias citadas. Esta función hace parte de la interfaz sys.GLWindow. Su especificación es la siguiente: void handleEvent(Event e) donde e representa el evento ocurrido. onIdle Función llamada automáticamente por la librería gráfica cada vez que en la aplicación no esta ocurriendo nada. Este es el lugar donde verdaderamente se produce el efecto de animación o movimiento de componentes de la escena, y típicamente lo que debe hacer una aplicación gráfica es llamar a la función que dibuja la escena desde esta función. Con respecto a OpenGL hay ciertas diferencias en este punto, ya que si una aplicación se mantiene quieta el 99% del tiempo esta función va a ser llamada un número grande de veces. Si la función que dibuja la escena contiene operaciones complejas y numerosas (lo cual es bastante común en la mayoría de las aplicaciones), la demanda de recursos al dispositivo sobre el cual corre la aplicación va a ser enorme. Para un computador de escritorio puede que no sea tan grave (razón por la cual OpenGL no ha cambiado la manera en que consigue crear el efecto de animación o movimiento) pero para un dispositivo móvil esto puede ser fatal. Es por esto que la librería gráfica móvil ofrece la función signalRepaint, la cual recibe un parámetro booleano que especifica si se debe o no repintar la ventana. Es cierto entonces que la función dibuja la escena es llamada múltiples veces durante la ejecución de una aplicación, pero esto no significa que la escena realmente sea dibujada cada una de estas veces. Esto únicamente sucederá si la aplicación explícitamente solicite a la librería el redibujo de la escena. No es tan eficiente como se quisiera pero por el momento es la mejor solución encontrada y si supera en rendimiento a aquella donde la escena es redibujada cada vez. La especificación de la función es la siguiente: void onIdle(); 4. Diagrama de clases del caso de estudio El siguiente es el diagrama de clases del caso de estudio. Este diagrama es muy sencillo ya que la aplicación solo consta de una clase. El resto de trabajo recae directamente sobre la librería gráfica.

Page 82: Documento Final de Tesis Entrega Final de Ciclo Terminal

79

Figura 25

Page 83: Documento Final de Tesis Entrega Final de Ciclo Terminal

80

Como se puede apreciar la aplicación solo consta de una clase que extiende de la clase GLBaseWindow, la cual pertenece a la librería gráfica móvil. El extender de esta clase es obligatorio si se quiere hacer uso de la librería ya que hay unas funciones de esta clase que son automáticamente llamadas por esta. Consecuencias de esta relación de generalización se presentan a continuación:

• El constructor de la clase principal DemoApp hace llamado al constructor de GLBaseWindow, el cual crea la ventana principal de la aplicación, asigna a la misma uno o dos buffers, obtiene una referencia de la librería gráfica móvil y se registra ante la misma. El registrarse ante la librería gráfica es un paso necesario debido a que la librería necesita una referencia a la ventana principal para poder realizar el dibujo de la escena y controlar los eventos que ocurren.

• La implementación de la función OnPaint (llamada cada vez que SuperWaba necesita redibujar la ventana principal de la aplicación) para esta clase es la que se encarga de llamar a la función OnDisplay de la aplicación para el dibujo de la escena y de llamar a la función addGUIComponents para adicionar los componentes de interfaz gráfica de la ventana principal. Este método no debe ser sobrescrito por la clase principal de las aplicaciones que hagan uso de la librería gráfica so pena de que la aplicación no funcione como se espera.

• La implementación de la función OnEvent (llamada cada vez que SuperWaba recibe un evento que debe ser procesado por la aplicación) para esta clase es la encargada de llamar a OnIdle cuando la aplicación se encuentra quieta y de pasarle el evento ocurrido al método handleEvent. Este método no debe ser sobrescrito por la clase principal de las aplicaciones que hagan uso de la librería gráfica so pena de que el efecto de animación o movimiento no pueda ser apreciado (no funcione como se espera).

5. Compilación y Ejecución La manera de compilar y ejecutar la aplicación de prueba es similar a como se compila y ejecuta la librería gráfica. Los dos archivos build.xml y build.properties son los que automatizan este proceso. Las mismas tareas que tiene el archivo build.xml de la librería gráfica las tiene el archivo build.xml de este proyecto. En una siguiente etapa seria bueno factorizar estas tareas en un archivo común, el cual podría ser llamado por aplicaciones gráficas basadas en MobileGL. No es una tarea difícil de realizar y facilitaría aún más el desarrollo de este tipo de aplicaciones. La única diferencia para este proyecto es que para compilar y generar los archivos de instalación se debe llamar a la tarea exegen,

Page 84: Documento Final de Tesis Entrega Final de Ciclo Terminal

81

ya que la tarea deploy no existe para este proyecto. Si se desea consultar el listado de tareas del build.xml de este proyecto favor remitirse a la sección correspondiente del capítulo dedicado a la librería gráfica móvil. Otra manera para consultar las tareas de este archivo es dar el siguiente comando: ant –projecthelp el cual se encargara de listar todas las tareas del archivo, cada una con su descripción. 6. Instalación Al igual que con la librería gráfica, el proceso a detallar será el que conlleva a la instalación del caso de pruebas sobre la plataforma Palm OS. Para instalar la aplicación se procede de la misma manera a como se hizo cuando se instaló la librería. Se abre el emulador y se selecciona la opción que permite instalar archivos o bases de datos. Una vez en esta opción se seleccionan los archivos DemoApp.prc y DemoApp.pdb. Estos archivos se encuentran en la carpeta temp del directorio principal de la aplicación. Una vez instalada la aplicación se debe poder apreciar la siguiente imagen en la pantalla del emulador:

Figura 26 Al dar clic sobre el ícono etiquetado como DemoApp se debe tener en la pantalla del emulador una imagen similar a la siguiente:

Figura 27

Page 85: Documento Final de Tesis Entrega Final de Ciclo Terminal

82

Cada uno de las barras de desplazamiento controla el movimiento de una de las partes del brazo. Su utilidad se describe a continuación:

• barra derecha: controla el movimiento del antebrazo derecho del robot. Si se hace clic sobre la flecha que apunta hacia arriba el antebrazo girara en sentido a favor de las manecillas del reloj; de lo contrario el antebrazo girara en sentido contrario a las manecillas del reloj.

• barra izquierda: controla el movimiento del antebrazo izquierdo del robot. Hacer clic sobre la flecha que apunta hacia arriba o hacia abajo tiene las mismas consecuencias que para el antebrazo derecho.

• barra superior: controla el movimiento de la base del brazo izquierdo del robot. Hacer clic sobre la flecha que apunta a la derecha girara el brazo hacia arriba (en sentido a favor de las manecillas del reloj); la flecha izquierda hace que el brazo gire hacia abajo (a favor de las manecillas del reloj).

• barra inferior: controla el movimiento de la base del brazo derecho del robot. Hacer clic que apunta hacia arriba o hacia abajo tiene las mismas consecuencias que para la base del brazo izquierdo.

Un ejemplo de movimiento del robot puede ser apreciado siguiendo las siguientes pantallas:

Figura 28 Figura 29 Figura 30

Figura 31 Figura 32 A manera de aclaración se quiere precisar en el hecho de que el mismo ejercicio fue desarrollando sobre un computador de escritorio haciendo uso de OpenGL. La imagen del robot para este proyecto es la siguiente:

Page 86: Documento Final de Tesis Entrega Final de Ciclo Terminal

83

Figura 33

Los resultados obtenidos por la librería gráfica desarrollada por ende son bastante satisfactorios.

Page 87: Documento Final de Tesis Entrega Final de Ciclo Terminal

84

VIII. A Futuro

La primera etapa de la librería gráfica esta lista y presenta unos resultados bastante satisfactorios. Se logró migrar toda la parte de transformaciones de modelo-vista a dispositivos móviles. El caso de prueba funciono si ningún problema y arrojando imágenes bastante parecidas a aquellas obtenidas por medio del programa gemelo desarrollado con OpenGL. A pesar de todo esto hay algunas tareas que deben desarrollarse en futuras etapas, para así incrementar la funcionalidad de la librería y su parecido a OpenGL. El listado de tareas fue organizado según la importancia de las mismas, colocando de primeras aquellas de mayor prioridad. Este listado es presentado a continuación:

1. Dibujo de polígonos con relleno. 2. Vista dinámica. 3. Operaciones sobre la matriz de proyección. 4. Incorporar vista ortogonal. 5. Habilitar el uso de texturas sobre objetos. 6. Habilitar sombras e iluminación.

Los primeros cuatro ítems son verdaderamente importantes y deben ser el objetivo a alcanzar en la segunda fase de la librería. Los siguientes dos son algo más complejos, por lo que sería bueno desarrollar cada uno por separado en una etapa independiente. Para el desarrollo de polígonos con relleno existen algoritmos que intentan cubrir tal operación. La manera a proceder sería la incorporación de cada uno de los algoritmos a la librería, escogiendo a través de pruebas aquel que ofrezca mejores resultados. Para la vista dinámica lo único que debe hacerse es implementar la función gluLookAt. Para esto sería ideal desarrollar una interfaz denominada GLUEngine (a manera únicamente de sugerencia) que contenga este método. En este punto hay dos opciones: desarrollar una clase que implemente esta interfaz o modificar la clase sys.GLStateMachine para que implementa también esta interfaz. La primera opción es mejor desde el punto de vista de separación de responsabilidades. La segunda opción reduce el número de clases que componen la librería, por lo que reduce hasta cierto punto el tamaño global de la librería. De igual manera la opción esta en manos de aquella persona o grupo de personas encargadas de la siguiente etapa de desarrollo. Para habilitar las operaciones sobre la matriz de proyección lo único que se debe hacer es implementar los métodos glFrustrum , glOrtho o gluPerspective. Los primeros dos deben ser agregados a la interfaz

Page 88: Documento Final de Tesis Entrega Final de Ciclo Terminal

85

gl.GlEngine, mientras que el último debe ser agregado a la interfaz glu.GLUEngine. glFrustrum, al igual que gluPerspective, permite generar una vista en perspeciva. La diferencia entre ambas radica en la forma en que logra este objetivo y el tipo y número de parámetros que reciben. glOrtho permite generar una vista ortogonal. Además de la implementación de estos métodos se deben modificar algunos otros como glPushMatrix, glPopMatrix, glRotatef, glTranslatef, glGetFloatv entre otros para que tengan en cuenta la nueva pila de matrices de proyección. Para los últimos dos ítems se deben estudiar los distintos algoritmos existentes para desarrollar estas tareas. Material al respecto se puede encontrar en Internet o en libros especializados en el tema. Según este planteamiento, el proyecto entonces tendría tres fases más. Cada fase de estas se compone de 4 meses, por lo que el total del tiempo invertido inicialmente llegaría a los 16 meses o un año y cuatro meses. Es probable que este estimado cambie debido a problemas encontrados a futuro, pero este es el tiempo mínimo de desarrollo para que la actual librería alcance un punto de madurez que le permita ser utilizada en proyectos de mayor trascendencia e importancia (comercial por ejemplo).

Page 89: Documento Final de Tesis Entrega Final de Ciclo Terminal

86

IX. Conclusiones El trabajo desarrollado para llevar la librería hasta este punto fue difícil y el esfuerzo invertido gigantesco. Razones a las que esto se debe tienen que ver con la poca documentación existente acerca de SuperWaba. El manual de SuperWaba28 y el grupo de noticias del mismo29 fueron la única fuente a la información, además de los ejemplos que venían con el SDK y aquellos otros encontrados en el sitio de superwaba30. Indudablemente esta información es buena y ayudó en cantidades el desarrollo del proyecto, pero en el caso de presentarse un error (algo bastante común y de hecho siempre presente en todo proyecto) los recursos eran limitados. El tiempo de solución de un problema entonces era proporcional al grado de rareza del mismo y a la suerte que se tenga para que alguno de los participantes del foro colaborara con alguna idea de solución. A pesar de todo esto se considera el trabajo desarrollado como de excelente calidad. Sin ninguna duda el software puede refinarse hasta llegar a convertir en la librería en una solución viable para cualquier tipo de aplicación que necesite hacer uso de funciones gráficas. No se necesitan más que ganas y gente comprometida para que este proyecto se retome y se desarrollen las fases que le hacen falta.

28 SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K 29 Grupo de Noticias – SuperWaba news://news.superwaba.net/pilot.programmer.waba 30 SuperWaba : The Real Power of Mobile Computing http://www.superwaba.com.br/en/default.asp

Page 90: Documento Final de Tesis Entrega Final de Ciclo Terminal

87

X. Glosario 1) Renderizar: proceso que realiza el computador para producir imágenes a

partir de modelos (geométricos) o primitivas31. 2) Primitiva: conjunto de vértices que representan puntos, líneas o polígonos. 3) Píxel: término americano que viene de la combinación de las palabras

picture element; es la unidad visible más pequeña que un hardware de gráficos puede colocar en pantalla.

4) Planos de bits: áreas en memoria que contienen un bit de información por cada píxel de la pantalla.

5) Framebuffer: colección de los planos de bits. El framebuffer es fundamental y requerido por el hardware de despliegue de gráficas para determinar la intensidad de cada píxel colocado en pantalla.

6) Objeto geométrico32: conjunto de primitivas (puntos, líneas y polígonos). 7) Objeto de rasterización: imágenes bidimensionales, mapas de bits y

fuentes de caracteres. 8) Viewport: el área donde va a ser desplegada la escena. Por lo general

esta área se establece como el área cliente de las ventanas. La librería gráfica a utilizar determinará si este valor puede o no ser modificable (OpenGL lo permite pero MobileGL en su primera etapa no lo permite).

9) JUnit33: plataforma de pruebas para software desarrollado en Java. 10) script: archivo ejecutable que permite realizar una o varias tareas. 11) GUI: interfaz gráfica de usuario o Graphical User Interface (en inglés).

Esta forma que tienen las aplicaciones gráficas para interactuar con el usuario.

31 Definiciones de los primeros cinco términos tomadas de: Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html 32 Definiciones sexta, séptima y octava tomadas de: Appendix B - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/appendixb.html 33 Definición tomada de: JUnit, Testing Resources for Extreme Programming http://www.junit.org/index.htm

Page 91: Documento Final de Tesis Entrega Final de Ciclo Terminal

88

XI. Referencias [1] Chapter 1 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter01.html Última modificación: Viernes, Julio 30, 2004 7:30:19 PM Expira: Martes, Marzo 22, 2005 2:51:21 AM [2] Appendix B - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/appendixb.html Última modificación: Viernes, Julio 30, 2004 7:28:52 PM Expira: Martes, Marzo 22, 2005 2:53:00 AM [3] Chapter 2 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter02.html Última modificación: Viernes, Julio 30, 2004 7:30:25 PM Expira: Martes, Marzo 22, 2005 2:53:11 AM [4] OpenGL Reference Manual http://rush3d.com/reference/opengl-bluebook-1.0/ Última modificación: Viernes, Julio 30, 2004 3:36:36 AM Expira: Martes, Marzo 22, 2005 4:28:51 AM [5] Chapter 3 - OpenGL Programming Guide (Addison-Wesley Publishing Company) http://rush3d.com/reference/opengl-redbook-1.1/chapter03.html Última modificación: Viernes, Julio 30, 2004 7:30:33 PM Expira: Martes, Marzo 22, 2005 2:55:08 AM [6] Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 5 – Transformaciones geométricas bidimensionales [7] Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 9 – Conceptos tridimensionales

Page 92: Documento Final de Tesis Entrega Final de Ciclo Terminal

89

[8] Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 11 – Transformaciones geométricas y de modelado tridimensionales [9] Gráficas por Computadora (Segunda Edición) – Donald Hearn, M. Pauline Baker Capítulo 12 - Vista tridimensional [10] SuperwabaWiki.Codev.SdkDocs - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Codev/SdkDocs#SuperWaba_Software_Development_K

Última modificación: Martes, Marzo 01, 2005 8:50:37 PM

Expira: sin especificar

[11] Grupo de Noticias - SuperWaba news://news.superwaba.net/pilot.programmer.waba [12] SuperwabaWiki.Main.Faq - The SuperWaba Wiki http://superwaba.sourceforge.net/cgi-bin/twiki/view/Main/Faq Última modificación: Martes, Marzo 01, 2005 8:51:47 PM Expira: sin especificar [13] SuperWaba : The Real Power of Mobile Computing http://www.superwaba.com.br/en/default.asp Última modificación: Martes, Marzo 01, 2005 8:52:54 PM Expira: sin especificar [14] JUnit, Testing Resources for Extreme Programming http://www.junit.org/index.htm Última modificación: Martes, Marzo 01, 2005 8:53:51 PM Expira: sin especificar [15] DSBox | miniGL http://www.dsbox.com/minigl.html Última modificación: Martes, Marzo 01, 2005 8:54:56 PM Expira: sin especificar

Page 93: Documento Final de Tesis Entrega Final de Ciclo Terminal

90

[16] TinyGL: a Small, Free and Fast Subset of OpenGL http://fabrice.bellard.free.fr/TinyGL/ Última modificación: Lunes, Marzo 01, 2004 7:17:19 PM Expira: Miércoles, Abril 06, 2005 6:44:44 PM [17] Pocket GL (ARM & Mips) on PocketGear.com http://www.pocketgear.com/software_detail.asp?id=1858 Última modificación: Martes, Marzo 01, 2005 8:57:37 PM Expira: Miércoles, Marzo 02, 2005 1:57:35 AM [18] OpenGL ES Overview http://www.khronos.org/opengles/index.html Última modificación: Viernes, Agosto 06, 2004 1:12:29 PM Expira: Martes, Marzo 22, 2005 12:20:46 AM [19] Hybrid Graphics - OpenGL ES API Framework http://www.hybrid.fi/main/esframework/index.php Última modificación: Martes, Marzo 01, 2005 9:00:43 PM Expira: sin especificar