1. Accesibilidad y Realidad
Aumentada
Iniciación a OpenGL
Vicente García Díaz – garciavicente@uniovi.es
Universidad de Oviedo, 2012
2. 2
Tabla de contenidos
Iniciación a OpenGL
1. Conceptos básicos
2. OpenGL 2D
3. OpenGL 3D
3.
4. 4
Conceptos básicos
¿Qué es OpenGL?
• Open Graphics Library
• Es una especificación independiente del lenguaje
• Multiplataforma
• Es el estándar de la industria para realizar
aplicaciones con gráficos 2D y 3D
• Se basa en primitivas muy básicas
• Desarrollado inicialmente por Silicon Graphics Inc
• Actualmente lo gestiona el Khronos Group
• http://www.opengl.org/ -
http://www.khronos.org/
5. 5
Conceptos básicos
¿Qué es OpenGL ES?
• Es el estándar de la industria para trabajar con
gráficos 2D y 3D, especialmente pensado para
dispositivos móviles y embebidos
• Ha sido desarrollado y está siendo mantenido por el
Khronos Group
▫ ATI, NVIDIA, Intel, …
• Varias versiones: 1.0, 1.1, 2
▫ Ruptura de compatibilidad
• El estándar se define mediante cabeceras C y una
especificación detallada de como la implementación
debería comportarse
7. 7
Conceptos básicos
Modelo de programación
Fuente: http://playerstage.sourceforge.net
8. 8
Conceptos básicos
Elementos clave en OpenGL
• Objetos (modelos)
▫ Geometría conjunto de triángulos
▫ Color tripleta RGB
▫ Textura y material
• Luces
▫ Atributos como posición, dirección o color
• Cámara
▫ Atributos como posición y orientación que definen el
volumen de visión
• Ventana de visualización (Viewport)
▫ Define el tamaño y la resolución final
9. 9
Conceptos básicos
Proyecciones
• OpenGL necesita crear imágenes desde el punto de
vista de una cámara
• Las proyecciones pueden ser de 2 tipos:
▫ Paralelas u ortográficas
Análogo al software CAD
No importa la distancia
2D
▫ Perspectiva
Análogo a la vista humana
Los objetos más lejanos se visualizan más pequeños
3D
Fuente: http://docs.autodesk.com
10. 10
Conceptos básicos
Plano de proyección
• Es donde OpenGL “proyecta” las imágenes
Fuente: http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c10123/Deriving-Projection-Matrices.htm
http://www.ecst.csuchico.edu/~judyc/1011F-csci566/notes/notes14.html
11. 11
Conceptos básicos
Proyección en perspectiva VS paralela
Plano de delimitación lejano
Plano de
delimitación
cercano
Fuente: http://www.apress.com/9781430230427
12. 12
Conceptos básicos
Trabajo con matrices
• Se utilizan para realizar transformaciones en
OpenGL:
▫ Proyecciones
▫ Traslaciones
▫ Rotaciones
▫ Escalados
• Para realizar las transformaciones se multiplica la
matriz por un punto
• Se pueden concatenar transformaciones mediante
multiplicaciones
• Existe una matriz especial denominada identidad
13. 13
Conceptos básicos
Matrices disponibles en OpenGL
• Model-view matrix
▫ Para mover, rotar o escalar puntos de los
triángulos
• Projection matrix
▫ Para proyectar los objetos que están contenidos
en el volumen de visión
• Texture matrix
▫ Para trabajar con las texturas de los objetos
14. 14
Conceptos básicos
Trabajo con OpenGL en Android
• Necesitamos una vista que permita trabajar con
OpenGL en una actividad de Android
• Android incorpora GLSurfaveView
▫ Crea un hilo para trabajar con OpenGL
• Sólo hay que implementar una interfaz listener
17. 17
Conceptos básicos AROpenGLTests (com.vgd.aropengltest1)
?
1. ¿Qué ocurriría si se llamara al método
glClearColor desde onSurfaceCreated?
2. ¿Y si después de cambiarlo se volviera al menú
principal (una vez abierta la aplicación) y se
volviera a abrir la aplicación?
3. ¿Qué ocurriría si no se llama nunca al método
glClearColor?
18. 18
Conceptos básicos
La ventana de visualización
• La ventana de visualización traslada coordenadas de
los puntos proyectados en el plano de delimitación
cercano a pixeles que se mostrarán en el dispositivo
• Se puede especificar qué porción de la ventana se
quiere utilizar:
▫ GL10.glViewport(int x, int y, int width, int height)
▫ x e y hacen referencia la esquina inferior izquierda
19. 19
Conceptos básicos
Trabajo con la matriz de proyección
• Lo primero es especificar con qué matriz queremos
trabajar
▫ GL10.glMatrixMode(int mode)
▫ Posibles valores: GL10.GL_PROJECTION, GL10.GL_MODELVIEW,
GL10.GL_TEXTURE
• Se perderá la selección cuando se pierda el contexto
de la aplicación
• No se trabaja igual con la matriz paralela (2D) y con
la matriz en perspectiva (3D)
20.
21. 21
OpenGL 2D
Trabajo con la matriz de proyección paralela
• Se puede definir el volumen de visión utilizando un
sistema de coordenadas (se puede cambiar)
• Se verán todos los puntos definidos en ese área
• GL10.glOrthof(int left, int right, int
bottom, int top, int near, int far)
Fuente: http://www.apress.com/9781430230427
http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/3d_perspective/
22. 22
OpenGL 2D
Triángulos (I)
• ¿Cómo definimos un triángulo?
▫ Un triángulo se define entre 3 puntos
▫ Cada punto es un vértice
▫ Un vértice tiene una posición en el espacio 3D
▫ Una posición en el espacio 3D se representa por
tres coordenadas x,y,z
▫ Un vértice puede tener otros atributos como
color o textura
23. 23
OpenGL 2D
Triángulos (II)
• ¿Cómo se realizan las definiciones de las figuras?
▫ Mediante el empleo de arrays
• …pero OpenGL es un API C
• Java NIO buffers
▫ Bloques de memoria de bytes consecutivos
▫ ByteBuffer buffer = ByteBuffer.allocateDirect(NUMBER_BYTES);
▫ buffer.order(ByteOrder.nativeOrder());
▫ FloatBuffer floatBuffer = buffer.asFloatBuffer();
▫ float[] vertices = //Definiciones de los vértices
▫ floatBuffer.clear(); //Se “inicia” el buffer
▫ floatBuffer.put(vertices); //Se introducen los vértices
▫ floatBuffer.flip(); //Se “cierra” el buffer
24. 24
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo)
Dibujo de un
triángulo
Especificación de los puntos
del triángulo
Definimos la ventana de visualización
Especificamos el color del fondo (color por defecto)
Especificamos que queremos trabajar con una matriz
Resetea la matriz de proyección (realmente no es necesaria en este caso)
Definición de matriz de proyección paralela
El color de lo que queremos dibujar (de todos los vértices)
Indicamos que los vértices tienen posición ¿?
Utilizamos dos coordenadas (x,y) definidas
usando floats (consecutivos)
Dibujamos un triángulo que tiene 3
vértices (el primero es el 0)
25. 25
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo)
?
1. Coloca el método glOrthof en onDrawFrame,
¿funciona bien?
2. Introduce valores para la coordenada z del
triángulo, ¿cambia la salida?
3. ¿Qué sería lo que habría que dejar idealmente en
el método onDrawFrame?
4. Intenta hacer que el fondo de la pantalla sea blanco
26. 26
OpenGL 2D
Modificación de los colores de los vértices
• Se pueden tener un control más granulado de los
colores de cada vértice de los objetos
Sin definir el color de los vértices
X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y
Posiciones en memoria
Definiendo el color de los vértices
X Y R G B A X Y R G B A X Y R G B A … …
Posiciones en memoria
27. 27
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.colorvertice)
Triángulo con color por vértice
(2 coordenadas + 4 para el color) * 4 bytes por float
Ese valor es ignorado, ya que los vértices tienen color
Los vértices tienen posición y también color
En la posición 0 de la memoria de cada vértice se obtiene su posición
En la posición 2 de la memoria de cada vértice se obtiene su color
Distancia entre cada vértice
28. 28
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.colorvertice)
?
1. Intenta proyectar algo como
lo siguiente:
2. Intenta visualizar algo
parecido a lo siguiente:
29. 29
OpenGL 2D
Inserción de texturas en los vértices (I)
• Se pueden incluir texturas en los vértices indicando
sus coordenadas
Sin definir texturas en los vértices
X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y
Posiciones en memoria
Definiendo las texturas de los vértices
X Y S T X Y S T X Y S T X Y S T X Y S T
Posiciones en memoria
30. 30
OpenGL 2D
Inserción de texturas en los vértices (II)
• Las coordenadas s,t se asocian con las x,y
• Trabajamos con un sistema de coordenadas
normalizado
(0,0) (1,0)
(0,1) (1,1)
Coordenadas s,t Coordenadas x,y
31. 31
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.texturavertice)
Ejemplo de uso de texturas (I)
Cargar un bitmap en memoria
Se crea un array para las texturas
Se crea 1 textura empezando en la posición 0 del
array. Después se obtiene el id del primer elemento
Activar el modo textura
El id se corresponde con una textura 2D
Se asocia la imagen con la textura
Puede existir: magnificación y minificación. Hay que especificar como queremos que se
comporte OpenGL para escalar (GL10.GL_NEAREST o GL10.GL_LINEAR)
Necesitamos pasarle en el constructor el contexto con el fin de
utilizarlo para cargar una imagen guardada en res/drawable
32. 32
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.texturavertice)
Ejemplo de uso de texturas (II)
Método creado para cargar la textura
Los vértices tienen posición y también
textura
33. 33
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.texturavertice)
?
1. Dibuja 2 triángulos en la pantalla como los
siguientes:
2. ¿Cómo construirías un cuadrado?
**Busca información sobre los vértices indexados
34. 34
OpenGL 2D
Otras primitivas
• Todas las primitivas se definen con vértices
Fuente: http://librairie.immateriel.fr/fr/read_book/9780596804824/ch02s02
35. 35
OpenGL 2D
Transformaciones
• Para realizar rotaciones, traslados o escalados se
utiliza la matriz model-view
▫ gl.glMatrixMode(GL10.GL_MODELVIEW)
• Por defecto tiene los valores identidad (todo unos)
• Se utilizan los métodos:
▫ gl.glTranslatef(float x, float y, float z)
▫ gl.glRotatef(float angle, float axisX, float
axisY, float axisZ)
▫ gl.glScalef(float x, float y, float z)
36. 36
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.traslacion)
Traslaciones
• Haciendo el triángulo más pequeño,
quedaría espacio para varios…
Cambio de matriz
Se inicializa la matriz a unos
Cada vez que se entra, se aumenta en 30 cada valor
Se dibuja el triángulo (3 vértices con offset 0)
1. ¿Es necesario que glMatrixMode y ?
glLoadIdentity estén en onDrawFrame?
37. 37
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.rotacion)
Rotaciones
Rota 45º sobre el eje Z
1.
?
¿Qué ocurre si rotamos sobre el eje x o sobre el
eje y?
Fuente: http://www.germanium3d.com/code/CoordinateSystemConcepts
38. 38
OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.escalado)
Escalados
Se hace 4 veces más ancho y 2 veces más alto
1. ¿Importa en orden en el que se definen en el
código las trasnformaciones?
?
41. 41
OpenGL 3D
Principales diferencias respecto a 2D
1. Se utiliza también la coordenada z
2. En lugar de proyección paralela se utiliza la
proyección en perspectiva
3. Las transformaciones tienen más libertad de
movimiento (en lugar de utilizar 2 ejes ahora se
utilizan 3)
4. Hay que tener en cuenta el orden en el que se
definen los objetos, ya que los más cercanos
pueden tapar a los más lejanos
42. 42
OpenGL 3D
Trabajo con la matriz de proyección en
perspectiva
• GLU.gluPerspective(GL10 gl, float fieldOfView, float
aspectRatio, float near, float far);
▫ gl para acceder a toda la API de OpenGL
▫ fieldOfView ángulo (para ver más a izquierda-
derecha)
▫ aspectRatio para asegurar que el mundo no se
estira/contrae en caso de que la ventana de visualización
no tenga un aspectRatio de 1 (ancho / alto)
▫ near y far para delimitar lo que se observa en el
volumen de visualización (coordenada z)
43. 43
OpenGL 3D AROpenGLTests (com.vgd.aropengltest.triangulo.tresdimen)
Dos triángulos en proyección perspectiva
Proyección en perspectiva, con ángulo campo
de visión 67 y con capacidad para ver todos
los z > -1 y z < -10
Primero se dibuja un triángulo y luego el otro
44. 44
OpenGL 3D
Z-Buffer (I)
• Es una estructura que se encarga de guardar
valores de profundidad de los pixeles
• Es la distancia desde un punto z al plano de
proyección
• ¿Por qué lo necesitamos?
▫ Para saber si un elemento se ha de renderizar
delante o detrás de otro
▫ GL10.glEnable(GL10.GL_DEPTH_TEST)
▫ Si la profundidad de un pixel es menor que la de otro
pasa el test
45. 45
OpenGL 3D
Z-Buffer (II)
Fuente: http://www.apress.com/9781430230427
46. 46
OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)
Creación de un cubo con texturas (I) ?
• Este es el objetivo final:
47. 47
OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)
Creación de un cubo con texturas (II)
• Pistas
▫ Coordenadas de los vértices y de las texturas
Fuente: http://www.apress.com/9781430230427
48. 48
OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)
Creación de un cubo con texturas (III)
• Pistas
▫ El tamaño de cada vértice es (3 + 2) * 4 = 20
▫ Además de limpiar el buffer de color habrá que limpiar el
Z-buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT)
▫ Hay que activar el test de profundidad además de
GL_VERTEX_ARRAY y GL_TEXTURE_COORD_ARRAY
gl.glEnable(GL10.GL_DEPTH_TEST)
▫ Hay que trabajar con texturas (loadTexture)
Es buena práctica liberar los recursos asociados con el
bitmap antes de finalizar el método
bitmap.recycle()
Fuente: http://www.apress.com/9781430230427
49. 49
OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)
Creación de un cubo con texturas (IV)
• Pistas para el método onDrawFrame
▫ Hay que acordarse de reiniciar la matriz en cada frame
GL_MODELVIEW
▫ Al estar trabajando con el Z-buffer, hay que limpiar los
bufferes en cada frame
▫ Si se mantiene la misma configuración para la proyección
en perspectiva: GLU.gluPerspective(gl, 67, width /
(float)height, 0.1f, 10) habrá que trasladar el cubo más
lejos para que quede dentro del volumen de visión. Por
ejemplo:
gl.glTranslatef(0,0,-3)
▫ Queremos que el cubo rote sobre si mismo:
Gl.glRotate(angulo++, 1, 1, 1)
Fuente: http://www.apress.com/9781430230427