Iniciación a OpenGL

50
Accesibilidad y Realidad Aumentada Iniciación a OpenGL Vicente García Díaz – [email protected] Universidad de Oviedo, 2012

Transcript of Iniciación a OpenGL

Page 1: Iniciación a OpenGL

Accesibilidad y Realidad Aumentada

Iniciación a OpenGL

Vicente García Díaz – [email protected]

Universidad de Oviedo, 2012

Page 2: Iniciación a OpenGL

Tabla de contenidos

1. Conceptos básicos

2. OpenGL 2D

3. OpenGL 3D

2

Iniciación a OpenGL

Page 3: Iniciación a OpenGL
Page 4: Iniciación a OpenGL

¿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/

4

Conceptos básicos

Page 5: Iniciación a OpenGL

¿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

5

Conceptos básicos

Page 6: Iniciación a OpenGL

OpenGL y DirectX 11

6

AndAR

Page 7: Iniciación a OpenGL

Modelo de programación

7

Conceptos básicos

Fuente: http://playerstage.sourceforge.net

Page 8: Iniciación a OpenGL

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

8

Conceptos básicos

Page 9: Iniciación a OpenGL

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

9

Conceptos básicos

Fuente: http://docs.autodesk.com

Page 11: Iniciación a OpenGL

Proyección en perspectiva VS paralela

11

Conceptos básicos

Fuente: http://www.apress.com/9781430230427

Plano de delimitación lejano

Plano de delimitación cercano

Page 12: Iniciación a OpenGL

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

12

Conceptos básicos

Page 13: Iniciación a OpenGL

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

13

Conceptos básicos

Page 14: Iniciación a OpenGL

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

14

Conceptos básicos

Page 15: Iniciación a OpenGL

Ejemplo básico (I)

15

Conceptos básicos AROpenGLTests (com.vgd.aropengltest1)

Page 16: Iniciación a OpenGL

Ejemplo básico (II)

16

Conceptos básicos AROpenGLTests (com.vgd.aropengltest1)

Page 17: Iniciación a OpenGL

17

Conceptos básicos

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?

AROpenGLTests (com.vgd.aropengltest1)

?

Page 18: Iniciación a OpenGL

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

18

Conceptos básicos

Page 19: Iniciación a OpenGL

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)

19

Conceptos básicos

Page 20: Iniciación a OpenGL
Page 21: Iniciación a OpenGL

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)

21

OpenGL 2D

Fuente: http://www.apress.com/9781430230427

http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/3d_perspective/

Page 22: Iniciación a OpenGL

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

22

OpenGL 2D

Page 23: Iniciación a OpenGL

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

23

OpenGL 2D

Page 24: Iniciación a OpenGL

24

AROpenGLTests (com.vgd.aropengltest.triangulo)

Especificación de los puntos del triángulo

Definición de matriz de proyección paralela

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)

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)

OpenGL 2D

Dibujo de un triángulo

Page 25: Iniciación a OpenGL

25

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

AROpenGLTests (com.vgd.aropengltest.triangulo)

?

OpenGL 2D

Page 26: Iniciación a OpenGL

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

26

OpenGL 2D

X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y

X Y R G B A X Y R G B A X Y R G B A … …

Sin definir el color de los vértices

Definiendo el color de los vértices

Posiciones en memoria

Posiciones en memoria

Page 27: Iniciación a OpenGL

Triángulo con color por vértice

27

(2 coordenadas + 4 para el color) * 4 bytes por float

Los vértices tienen posición y también color

Ese valor es ignorado, ya que los vértices tienen color

En la posición 0 de la memoria de cada vértice se obtiene su posición

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.colorvertice)

En la posición 2 de la memoria de cada vértice se obtiene su color

Distancia entre cada vértice

Page 28: Iniciación a OpenGL

28

1. Intenta proyectar algo como lo siguiente:

2. Intenta visualizar algo parecido a lo siguiente:

?

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.colorvertice)

Page 29: Iniciación a OpenGL

Inserción de texturas en los vértices (I)

• Se pueden incluir texturas en los vértices indicando sus coordenadas

29

OpenGL 2D

X Y X Y X Y X Y X Y X Y X Y X Y X Y X Y

X Y S T X Y S T X Y S T X Y S T X Y S T

Sin definir texturas en los vértices

Definiendo las texturas de los vértices

Posiciones en memoria

Posiciones en memoria

Page 30: Iniciación a OpenGL

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

30

OpenGL 2D

(0,0) (1,0)

(0,1) (1,1)

Coordenadas s,t Coordenadas x,y

Page 31: Iniciación a OpenGL

Ejemplo de uso de texturas (I)

31

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.texturavertice)

Cargar un bitmap en memoria

Activar el modo textura El id se corresponde con una textura 2D

Se asocia la imagen con la textura

Necesitamos pasarle en el constructor el contexto con el fin de utilizarlo para cargar una imagen guardada en res/drawable

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

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)

Page 32: Iniciación a OpenGL

Ejemplo de uso de texturas (II)

32

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.texturavertice)

Método creado para cargar la textura

Los vértices tienen posición y también textura

Page 33: Iniciación a OpenGL

33

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

?

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.texturavertice)

Page 34: Iniciación a OpenGL

Otras primitivas

• Todas las primitivas se definen con vértices

34

OpenGL 2D

Fuente: http://librairie.immateriel.fr/fr/read_book/9780596804824/ch02s02

Page 35: Iniciación a OpenGL

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)

35

OpenGL 2D

Page 36: Iniciación a OpenGL

Traslaciones

• Haciendo el triángulo más pequeño,

quedaría espacio para varios…

1. ¿Es necesario que glMatrixMode y glLoadIdentity estén en onDrawFrame?

36

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.traslacion)

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)

?

Page 37: Iniciación a OpenGL

Rotaciones

1. ¿Qué ocurre si rotamos sobre el eje x o sobre el eje y?

37

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.rotacion)

?

Rota 45º sobre el eje Z

Fuente: http://www.germanium3d.com/code/CoordinateSystemConcepts

Page 38: Iniciación a OpenGL

Escalados

1. ¿Importa en orden en el que se definen en el código las trasnformaciones?

38

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.escalado)

?

Se hace 4 veces más ancho y 2 veces más alto

Page 39: Iniciación a OpenGL

Combinaciones de transformaciones

39

OpenGL 2D AROpenGLTests (com.vgd.aropengltest.triangulo.traslacion)

gl.glScalef(4, 2, 1);

gl.glTranslatef(30, 0, 0);

gl.glScalef(4, 2, 1);

gl.glTranslatef(30, 0, 0);

gl.glScalef(4, 2, 1);

gl.glTranslatef(30, 0, 0);

Page 40: Iniciación a OpenGL
Page 41: Iniciación a OpenGL

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

41

OpenGL 3D

Page 42: Iniciación a OpenGL

• 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)

42

OpenGL 3D

Trabajo con la matriz de proyección en perspectiva

Page 43: Iniciación a OpenGL

Dos triángulos en proyección perspectiva

43

OpenGL 3D AROpenGLTests (com.vgd.aropengltest.triangulo.tresdimen)

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

Page 44: Iniciación a OpenGL

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

44

OpenGL 3D

Page 45: Iniciación a OpenGL

45

OpenGL 3D

Z-Buffer (II)

Fuente: http://www.apress.com/9781430230427

Page 46: Iniciación a OpenGL

Creación de un cubo con texturas (I)

• Este es el objetivo final:

46

OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)

?

Page 47: Iniciación a OpenGL

Creación de un cubo con texturas (II)

• Pistas

▫ Coordenadas de los vértices y de las texturas

47

OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)

Fuente: http://www.apress.com/9781430230427

Page 48: Iniciación a OpenGL

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()

48

OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)

Fuente: http://www.apress.com/9781430230427

Page 49: Iniciación a OpenGL

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)

49

OpenGL 3D AROpenGLTests (com.vgd.aropengltest.cubo)

Fuente: http://www.apress.com/9781430230427

Page 50: Iniciación a OpenGL

Bibliografía

50