Está en la página 1de 66

Transformaciones 3D

OpenGL ES
Parte VI

Jhonny Felípez Andrade

jrfelizamigo@gmail.com
Contenido
 Transformaciones en 3D
 Cubo Malla
 Traslación, Escalación, Rotación
 Coordenadas Homogéneas
 Ejemplo cubo con colores
 ZBuffer
 Ejemplo de Animación en 3D
 Ejemplo de Interacción en 3D
 Modelos 3D 2
Transformaciones en 3D

TRANSFORMACIONES EN 3D

3
Ejemplo
http://www.xmission.com/~nate/tutors.html

Experimente con el
ejemplo de
Transformaciones de
Nate Robins

4
Coordenadas en 3D
 Recordando el espacio de coordenadas en 3
dimensiones.
y

z
x

z x
5
Transformaciones en 3D

CUBO MALLA

6
Ejemplo1. Vértices de un
Cubo. Y

private float vertices[] = {


-1, -1, -1, // 0
3 2
1, -1, -1, // 1
7 6
1, 1, -1, // 2
X
-1, 1, -1, // 3
-1, -1, 1, // 4 0 1
1, -1, 1, // 5 4 5
1, 1, 1, // 6 Z
-1, 1, 1, // 7
};
7
Ejemplo1. Caras del Cubo
(cuadrados)
3 2

3 7 6 2

private short indices[] = { 0 4 5 1


4, 5, 5, 6, 6, 7, 7, 4, // Frente
3, 2, 2, 1, 1, 0, 0, 3, // Atrás
0, 4, 4, 7, 7, 3, 3, 0, // Izquierda
0 1
5, 1, 1, 2, 2, 6, 6, 5, // Derecha
0, 1, 1, 5, 5, 4, 4, 0, // Abajo
7, 6, 6, 2, 2, 3, 3, 7, // Arriba
}; 3 2
8
Ejecución

9
Ejemplo1. Caras del Cubo
(triángulos)
private short indices[] = { 3 2
4, 5, 5, 6, 6, 4, // Frente
4, 6, 6, 7, 7, 4,
3, 2, 2, 1, 1, 3, // Atrás 7 6 2
3
3, 1, 1, 0, 0, 3,
0, 4, 4, 7, 7, 0, // Izquierda
0, 7, 7, 3, 3, 0,
5, 1, 1, 2, 2, 5, // Derecha 0 4 5 1
5, 2, 2, 6, 6, 5,
0, 1, 1, 5, 5, 0, // Abajo
0, 5, 5, 4, 4, 0, 0 1
7, 6, 6, 2, 2, 7, // Arriba
7, 2, 2, 3, 3, 7
};
3 2
10
Ejecución

11
Transformaciones en 3D

TRASLACIÓN

12
Traslación
 Para trasladar un punto en 3 dimensiones en tx,
ty y tz simplemente se calcula los nuevos puntos
como sigue:
x’ = x + tx y’ = y + ty z’ = z + tz

13
Ejemplo1.Trasladando
un objeto.
glColor3f(1, 0, 0); Original

objeto(gl)

glColor3f(0, 1, 0);
glPushMatrix();
glTranslatef(3, 0, 0);
objeto(gl);
glPopMatrix();
rotado(45,1,1,1)

14

área de despliegue: desde (-8,-12) hasta (8,12)


Transformaciones en 3D

ESCALACIÓN

15
Escalación
 Para escalar un punto en 3 dimensiones en Sx,
Sy y Sz simplemente se calcula los nuevos puntos
como sigue:
x’ = Sx*x y’ = Sy*y z’ = Sz*z

16
Ejemplo1.Escalando
un objeto.
glColor3f(1, 0, 0); Original

objeto(gl)

glColor3f(0, 1, 0);
glPushMatrix();
gl.glScalef(2, 2, 2);
objeto(gl);
glPopMatrix();
rotado(45,1,1,1)

17

área de despliegue: desde (-8,-12) hasta (8,12)


Transformaciones en 3D

ROTACIÓN

18
Rotación

x’ = x·cosθ - y·sinθ x’ = x x’ = z·sinθ + x·cosθ


y’ = x·sinθ + y·cosθ y’ = y·cosθ - z·sinθ y’ = y
z’ = z z’ = y·sinθ + z·cosθ z’ = z·cosθ - x·sinθ

19
Ejemplo1.Rotando
un objeto.
glColor3f(1, 0, 0); Original

objeto(gl)

glColor3f(0, 1, 0);
glPushMatrix();
glRotatef(20, 0, 1, 0);
objeto(gl);
glPopMatrix();
rotado(45,1,1,1)

20

área de despliegue: desde (-8,-12) hasta (8,12)


Transformaciones en 3D

COORDENADAS
HOMOGÉNEAS
21
Coordenadas Homogéneas
 Similar a 2-D las coordenadas homogéneas
para transformaciones en 3-D se agrega una
cuarta coordenada.
y
 Todas las transformaciones
pueden ser representados y

como matrices.
 x P
 y
P(x, y, z) =   z
z x
 
1  z x
22
Matrices de transformación en 3D

1 0 0 tx   sx 0 0 0
0 1 0 ty   0 sy 0 0 Escalación en sx, sy,
Traslación en
tx, ty, tz
  sz
0 0 1 tz   0 0 sz 0
   
0 0 0 1 0 0 0 1

1 0 0 0  cos 0 sin  0 cos  sin  0 0


0 cos  sin  0  0 1 0 0  sin  cos 0 0
  
0 sin  cos 0  sin  0 cos 0  0 0 1 0
     
0 0 0 1  0 0 0 1  0 0 0 1
Rotación en el eje X Rotación en el eje Y Rotación en el eje Z
23
Transformaciones en 3D

EJEMPLO CUBO CON COLORES

24
Cubo

25
private float vertices[] = { Vértices de
// Frente
-1, -1, 1, // 4 0 la figura
1, -1, 1, // 5 1
1, 1, 1, // 6
-1, 1, 1, // 7
2
3
Vértices del Cubo
// Atrás
-1, 1, -1, // 3 4
Ubicación 3 2
1, 1, -1, // 2 5
1, -1, -1, // 1 6 en el arreglo
-1, -1, -1, // 0 7
// Izquierda
-1, -1, -1, // 0 8
-1, -1, 1, // 4 9 3 7 6 2
-1, 1, 1, // 7 10
-1, 1, -1, // 3 11
// Derecha
1, -1, 1, // 5 12
1, -1, -1, // 1 13
0 4 5 1
1, 1, -1, // 2 14
1, 1, 1, // 6 15
// Abajo
-1, -1, -1, // 0 16
1, -1, -1, // 1 17
1, -1, 1, // 5 18 0 1
-1, -1, 1, // 4 19
// Arriba
-1, 1, 1, // 7 20
1, 1, 1, // 6 21
1, 1, -1, // 2 22
-1, 1, -1 // 3 23 3 2 26
};
byte maxColor = (byte)255;
private byte colores[] = new byte[] {
// Frente - lila Colores del Cubo
maxColor, 0, maxColor, maxColor, // 4 0
maxColor, 0, maxColor, maxColor, // 5 1
maxColor, 0, maxColor, maxColor, // 6 2
maxColor, 0, maxColor, maxColor, // 7 3
// Atrás - amarillo 3 2
maxColor, maxColor, 0, maxColor, // 3 4
maxColor, maxColor, 0, maxColor, // 2 5
maxColor, maxColor, 0, maxColor, // 1 6
maxColor, maxColor, 0, maxColor, // 0 7
// Izquierda - celeste
0, maxColor, maxColor, maxColor, // 0 8 3 7 6 2
0, maxColor, maxColor, maxColor, // 4 9
0, maxColor, maxColor, maxColor, // 7 10
0, maxColor, maxColor, maxColor, // 3 11
// Derecha - rojo
maxColor, 0, 0, maxColor, // 5 12
maxColor, 0, 0, maxColor, // 1 13
0 4 5 1
maxColor, 0, 0, maxColor, // 2 14
maxColor, 0, 0, maxColor, // 6 15
// Abajo - azul
0, 0, maxColor, maxColor, // 0 16
0, 0, maxColor, maxColor, // 1 17 0 1
0, 0, maxColor, maxColor, // 5 18
0, 0, maxColor, maxColor, // 4 19
// Arriba - verde
0, maxColor, 0, maxColor, // 7 20
0, maxColor, 0, maxColor, // 6 21
0, maxColor, 0, maxColor, // 2 22 3 2 27
0, maxColor, 0, maxColor // 3 23
};
private float vertices[] = {
// Frente
-1, -1, 1, // 4 0
1, -1, 1, // 5
1, 1, 1, // 6
1
2
Caras del Cubo
-1, 1, 1, // 7 3
// Atrás
-1, 1, -1, // 3 4
en base a triángulos
1, 1, -1, // 2 5
1, -1, -1, // 1 6
-1, -1, -1, // 0 7
// Izquierda private short indices[]= {
-1, -1, -1, // 0 8 0, 1, 2, 0, 2, 3, // Frente
-1, -1, 1, // 4 9
-1, 1, 1, // 7 10 4, 5, 6, 4, 6, 7, // Atrás
-1, 1, -1, // 3 11
// Derecha
8, 9, 10, 8, 10, 11, // Izquierda
1, -1, 1, // 5 12 12, 13, 14, 12, 14, 15, // Derecha
1, -1, -1, // 1 13
1, 1, -1, // 2 14 16, 17, 18, 16, 18, 19, // Abajo
1, 1, 1, // 6 15
// Abajo
20, 21, 22, 20, 22, 23 // Arriba
-1, -1, -1, // 0 16 };
1, -1, -1, // 1 17
1, -1, 1, // 5 18
-1, -1, 1, // 4 19
3 2
// Arriba Triángulos en base a las
-1, 1, 1, // 7 20 ubicaciones en el arreglo 0 1
1, 1, 1, // 6 21
1, 1, -1, // 2 22
-1, 1, -1 // 3 23 28
};
Inicio
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
cubo = new Cubo();
/* Habilita el modo de sombreado plano */
gl.glShadeModel(GL10.GL_FLAT);
/* Habilita el ocultamiento de superficies */
gl.glEnable(GL10.GL_DEPTH_TEST);
/* Color de fondo */
gl.glClearColor(0, 0, 0, 0);
}

29
Despliegue
public void onDrawFrame(GL10 gl) {
/* Inicializa el buffer de color y de profundidad */
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glRotatef(rotX, 1.0f, 0.0f, 0.0f);
gl.glRotatef(rotY, 0.0f, 1.0f, 0.0f);
gl.glRotatef(rotZ, 0.0f, 0.0f, 1.0f);
cubo.dibuja(gl);
gl.glFlush();
rotX = rotX + 0.3f;
rotY = rotY + 0.2f;
rotZ = rotZ + 0.4f;
}

30
Ángulos de Euler
Se puede crear cualquier rotación a través de
las rotaciones sobre los ejes x, y y z en el
orden establecido.
Las rotaciones tienen múltiples
representaciones.
Los ángulos elegidos se denominan los
ángulos de Euler.
https://es.wikipedia.org/wiki/%C3%81ngulos_de_Euler
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glRotatef(rotX, 1.0f, 0.0f, 0.0f);
gl.glRotatef(rotY, 0.0f, 1.0f, 0.0f);
gl.glRotatef(rotZ, 0.0f, 0.0f, 1.0f);

31
Actualizaciones
Pero, ¿qué cambia los ángulos?

/* Para la rotación */
private float rotX;
private float rotY;
private float rotZ;

rotX = rotX + 0.3f; // inc. para la rotación sobre el eje X


rotY = rotY + 0.2f; // inc. para la rotación sobre el eje Y
rotZ = rotZ + 0.4f; // inc. para la rotación sobre el eje Z

32
Preguntas
¿Qué se necesita para realizar 3D?
Definir los puntos como tripletas (x, y, z).
Habilitar alguna forma para la eliminación de la superficie
oculta.
Se utiliza el "Z buffer"

¿Qué se hizo para la animación?


Crear alguna forma de actualización de la escena.
Utilizar las variables de rotación.
Se usó el doble buffer para reducir el parpadeo.

¿Problemas con este programa?


Aumentar o reducir el tiempo de la animación. 33
Transformaciones en 3D

ZBUFFER

34
Algoritmo del Pintor

35
Algoritmo del Pintor
 Una forma para ocultar superficies ocultas se
denomina algoritmo del pintor. El cual ordena
los objetos por la distancia desde la vista.
 Pinta los objetos más distantes en primer lugar,
llegando hasta los objetos más cercanos a la
vista.

36
Algoritmo del Pintor
 Una dificultad que se
tiene es en ordenar los
objetos.
 Una segunda dificultad es
que la mayoría de los
objetos no tiene una
profundidad fija.

37
Z-Buffer
 Podemos resolver el problema utilizando
la memoria.
 Se asigna un buffer que almacena la
profundidad del pixel.
 Como se pinta cada pixel que aparece, se
guarda la profundidad en el Z-Buffer

38
Zbuffer

Para este ejemplo se toma en cuenta al pixel


de profundidad mayor.
39
40
41
Utilizando el Zbuffer
 Para utilizar el Z-Buffer se debe:
 Realizar una llamada a glEnable(GL_DEPTH_TEST)
en el método de inicialización del programa.
 Asegúrese de que los valores de zNear y zFar deben
ser positivos (no cero o negativo).
 Pase GL_DEPTH_BUFFER_BIT como un parámetro
del método glClear.

42
Transformaciones en 3D

EJEMPLO DE ANIMACIÓN EN 3D

43
Sistema Solar Básico

44
Solar
/*
* Programa que demuestra como utilizar el método de coordenada
* local para ubicar partes de un modelo en relación a otras
* partes del modelo.
*
* Dibuja un simple sistema solar, con un sol, un planeta
* y una luna. Basado en el código ejemplo de la Guía de la
* Programación OpenGL
* por Woo, Neider, Davis. Addison-Wesley.
*
*/

45
Botones
activity_main.xml:

<Button
android:id="@+id/boton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="boton_animacion"
android:text="on/off animación" />
...

46
Botones
MainActivity.java:

/* Botón de animación */
public void boton_animacion(View v) {
superficie.opcion_animacion();
}
/* Botón del simple paso */
public void boton_simple_paso(View v) {
superficie.opcion_simple_paso();
}
/* Botón del incremento del tiempo */
public void boton_incrementa(View v) {
superficie.opcion_incrementa();
}
/* Botón del decremento del tiempo */
public void boton_decrementa(View v) {
superficie.opcion_decrementa(); 47

}
Interface Lógica
Renderiza.java:

boolean animacion = true;


boolean simplePaso = false;

float horasPorDia = 0.0f;


float diasPorAnio = 0.0f;
float tiempoDeLaAnimacion = 24.0f;
/* Activa y desactiva la animación */
public void opcion_animacion(){
if (simplePaso) { // Si
simplePaso = false; // Finaliza modo de simple paso
animacion = true; // Restaura la animación
}
else {
animacion = !animacion; // Activa y desactiva la animación.
} 48
}
Interface Lógica

/* Activa el simple paso */


public void opcion_simple_paso(){
simplePaso = true;
animacion = true;
}

/* Duplica el tiempo de la animación */


public void opcion_incrementa(){
tiempoDeLaAnimacion *= 2.0;
}

/* Reduce a la mitad el tiempo de la animación */


public void opcion_decrementa(){
tiempoDeLaAnimacion /= 2.0;
} 49
Animación
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef ( 0.0f, 0.0f, -8.0f );
gl.glRotatef( 15.0f, 1.0f, 0.0f, 0.0f );
// Dibuja el sol -- de amarillo, la esfera está en base a líneas.
gl.glColor4f( 1, 1, 0, 1 );
sol.dibuja(gl);
// Dibuja la tierra
gl.glRotatef( 360.0f*diasPorAnio/365.0f, 0.0f, 1.0f, 0.0f );
gl.glTranslatef( 4.0f, 0.0f, 0.0f );
gl.glPushMatrix();
gl.glRotatef( 360.0f*horasPorDia/24.0f, 0.0f, 1.0f, 0.0f );
gl.glColor4f( 0.2f, 0.2f, 1.0f, 1 );
tierra.dibuja(gl); 50

gl.glPopMatrix();
Animación

// Dibuja la luna.
gl.glRotatef( 360.0f*12.0f*diasPorAnio/365.0f,0.0f,1.0f,0.0f );
gl.glTranslatef( 0.7f, 0.0f, 0.0f );
gl.glColor4f( 0.3f, 0.7f, 0.3f, 1 );
luna.dibuja(gl);
gl.glFlush();
/* Obtiene el tiempo real*/
fin = System.currentTimeMillis();
duracion = fin - inicio;
tiempo_real = duracion / 1000f;
inicio = fin;

/* Incrementa y verifica el límite del tiempo */


tiempoRotacion = tiempoRotacion - tiempo_real;
51
Animación

if (tiempoRotacion < 0.001) {


tiempoRotacion = PERIODO_DE_LA_ROTACION;
if (animacion) {
// Actualiza el estado de la animación
horasPorDia += tiempoDeLaAnimacion;
diasPorAnio += tiempoDeLaAnimacion/24.0;

horasPorDia = horasPorDia - ((int)(horasPorDia/24))*24;


diasPorAnio = diasPorAnio - ((int)(diasPorAnio/365))*365;
}
if ( simplePaso ) {
animacion = false;
}
}
} 52
Inicio
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
sol = new Esfera(1, 15, 15);
tierra = new Esfera(0.4f, 10, 10);
luna = new Esfera(0.1f, 5, 5);
/* Inicializa las variables */
inicio = System.currentTimeMillis();
tiempoRotacion = PERIODO_DE_LA_ROTACION;
/* Habilita el modo de sombreado plano */
gl.glShadeModel(GL10.GL_FLAT);
/* Color de fondo */
gl.glClearColor(0, 0, 0, 0);
/* Especifica el valor de limpiado */
gl.glClearDepthf( 1.0f );
/* Habilita el ocultamiento de superficies */
gl.glEnable(GL10.GL_DEPTH_TEST); 53

}
Proyección en Perspectiva

@Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
float aspectoRatio;
h = (h == 0) ? 1 : h;
w = (w == 0) ? 1 : w;
/* Ventana de despliegue */
gl.glViewport(0, 0, w, h);
aspectoRatio = (float)w/(float)h;
/* Matriz de Proyección */
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 60.0f, aspectoRatio, 1.0f, 30.0f );
/* Matriz del Modelo-Vista */
gl.glMatrixMode(GL10.GL_MODELVIEW);
54
}
Transformaciones en 3D

EJEMPLO DE INTERACCIÓN EN 3D

55
Cubo

56
Inicio
/* Objeto */
private Cubo cubo;
/* Para la rotación */
private float trazoHorizontal;
private float trazoVertical;
private float antX;
private float antY;
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
cubo = new Cubo();
/* Habilita el modo de sombreado plano */
gl.glShadeModel(GL10.GL_FLAT);
/* Habilita el ocultamiento de superficies */
gl.glEnable(GL10.GL_DEPTH_TEST);
/* Color de fondo */
gl.glClearColor(0, 0, 0, 0);
} 57
Trazos

Trazo Vertical Trazo Horizontal

dy

dx 58
Despliegue
public void onDrawFrame(GL10 gl) {
/* Se inicializa el buffer de color y de profundidad */
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

/* Se inicializa la Matriz del Modelo-Vista */


gl.glLoadIdentity();

/* Rota el cubo */
gl.glRotatef(trazoHorizontal, 0.0f, 1.0f, 0.0f);
gl.glRotatef(trazoVertical, 1.0f, 0.0f, 0.0f);

cubo.dibuja(gl); // P' = Ry Rx P

/* Se asegura que se ejecute las anteriores instrucciones */


gl.glFlush();
} 59
Proyección Paralela
public void onSurfaceChanged(GL10 gl, int w, int h) {
/* Ventana de despliegue */
gl.glViewport(0, 0, w, h);
/* Matriz de Proyección */
gl.glMatrixMode(GL10.GL_PROJECTION);
/* Se inicializa la Matriz de Proyección */
gl.glLoadIdentity();
/* Proyección paralela */
if (w <= h)
gl.glOrthof(-2, 2, -2 * (float) h / (float) w, 2 * (float) h
/ (float) w, -10, 10);
else
gl.glOrthof(-2 * (float) w / (float) h, 2 * (float) w / (float) h,
-2, 2, -10, 10);
/* Matriz del Modelo-Vista */
gl.glMatrixMode(GL10.GL_MODELVIEW);
/* Se inicializa la Matriz del Modelo-Vista */
gl.glLoadIdentity();
60
}
Interacción 3D
Si se arrastra de forma horizontal (trazo horizontal)
se tiene a lo más 320 pixeles de recorrido.
Si se quiere que para los 320 pixeles el cubo rote
180 grados, se tendrá:

320 pxls ---> 180 grados


dx pxls ---> a grados
dy 180
480
a grados = dx * ------ = dx * 0.5625
320

En el trazo vertical el análisis es similar:

dx 480 pxls ---> 270 grados


dy pxls ---> b grados

270
320 b grados = dy * ------ = dy * 0.5625
61
480
Actualizaciones

public boolean onTouchEvent(MotionEvent e) {


float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - antX;
float dy = y - antY;
trazoHorizontal = trazoHorizontal + dx * 0.5625f;
trazoVertical = trazoVertical + dy * 0.5625f;

requestRender();
}
antX = x;
antY = y;
return true; 62
}
Resumen
 Se mostró las transformaciones en 3D.
 Las transformaciones se definen antes de
dibujar un objeto.
 Se presentó como realizar una animación en
3D.
 Se exhibió como realizar una interacción en
3D.

63
Transformaciones en 3D

MODELOS 3D

64
Test de modelos en 3D
http://en.wikipedia.org/wiki/List_of_common_3D_test_models
http://www.graphics.stanford.edu/

65
GRACIAS

66

También podría gustarte