02_OpenGL_primitivas_y_transformaciones

Download Report

Transcript 02_OpenGL_primitivas_y_transformaciones

Introducción a los
gráficos 3D
OpenGL
Introducción a OpenGL
• Breve historia:
– En 1973 se desarrolla GKS (Graphical Kernel System)
– No se adapta bien a los gráficos 3D y a la continua
evolución del hardware.
– Nacen otras propuestas: Programmers Hierarchical
Graphics System (PHIGS) y X Window System.
– PEX intenta combinar estas soluciones pero el resultado
es complejo
Introducción a OpenGL
• Breve historia:
– En 1982 una compañía llamada Silicon Graphics (SGI)
revoluciona el mercado con una propuesta basada en
implementar el pipeline gráfico en hardware.
– Esta propuesta utiliza una librería gráfica llamada GL.
– Su diseño hace que sea posible realizar gráficos 3D de
forma sencilla.
Introducción a OpenGL
• Breve historia:
– En 1992 nace OpenGl basándose en el diseñó en GL.
– Es un API con muchas ventajas:
• Es independiente de la plataforma y del lenguaje
• Es fácil de usar
• Evita todo lo relativo al sistema de ventanas y se centra en el
proceso de renderizado
• Soportado por multitud de empresas
• Estable
• Evoluciona continuamente e incorpora todas las mejoras en
hardware.
Introducción a OpenGL
El rendimiento se obtiene utilizando la GPU en lugar
de usar la CPU
Podemos programar la GPU unos programas
especiales llamados: “shaders”.
Nuestra aplicación debe suministrar los datos para
que trabaje la GPU
La GPU realiza todo el trabajo “pesado”:
OpenGL
≡
Abstract Drawing Machine
triangles, lines, points
OpenGL
images
commands
Vertices
Per-vertex ops
Transformed
vertices
Rasterizer
Texturing
Fragments
Per-fragment ops
Shaded
fragments
Frame buffer ops
pixels in the
framebuffer
Pixels
Introducción a OpenGL
OpenGL


OpenGL32 en Windows

Se suele llamar GL en unix/linux (libGL.a)
OpenGL Utility Library (GLU)


Aporta funcionalidad nueva escrita usando
OpenGL.
Links with window system




GLX en sistemas X window systems
WGL en Windows
AGL en Macintosh
Introducción a OpenGL

Otras API y librerías interesantes:



GLUT
Freeglut
GLEW: OpenGL Extension Wrangler Library
Introducción a OpenGL
Introducción a OpenGL

Primitivas




Atributos






Puntos (Points)
Líneas (Line Segments)
Triángulos (Triangles)
Transformaciones
Vista
Modeling
Control (GLUT)
Entrada (Input) (GLUT)
Consulta (Query)
Introducción a OpenGL
function name
dimensiones
glUniform3f(x,y,z)
Forma parte de GL lib.
x,y,z son floats
glUniform3fv(p)
p es un puntero a un array
Un ejemplo tonto:
El código sería:
#include <GL/glut.h>
void mydisplay(){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUAD;
glVertex2f(-0.5, -0.5);
glVertex2f(-0,5, 0,5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd()
}
int main(int argc, char** argv){
glutCreateWindow("simple");
glutDisplayFunc(mydisplay);
glutMainLoop();
}
Introducción a OpenGL
• OpenGL trabaja en un bucle infinito
– Sitúa elementos en la escena(puntos, líneas, polígonos,..)
– Describe la cámara (pos., orientación, field of view)
– Atiende los eventos del teclado (keyboard events)
– Dibuja la escena
Introducción a OpenGL
• OpenGL tiene un estado
– El programa OpenGL tiene multitud de posibles
configuraciones.
– La configuración actual se almacena en el estado de
OpenGL
– Los comandos de OpenGL afectan al estado del
programa.
OpenGL: Geometría
• La geometría en OpenGL es una serie de vértices entre un
glBegin() y glEnd()
– Como ejemplo simple, supongamos un triángulo:
glBegin(GL_POLYGON);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
glEnd();
– En la llamada a glBegin(geomtype) indicamos el tipo de geometría
que deseamos:
• puntos, líneas, polígonos, triángulos, cuadrados, etc...
Tipos de primitivas
• GL_POINTS
• GL_LINE
– {S | _STRIP | _LOOP}
• GL_TRIANGLE
– {S | _STRIP | _FAN}
• GL_QUAD
– {S | _STRIP}
• GL_POLYGON
Primitivas de OpenGL
GL_POLYGON
• La lista de vértices define un polígono
• Los polígonos deben ser convexos.
Polígonos no-coplanares
• Imagina un polígono no-coplanar
• Según la perspectiva, podría verse como no convexo
• En general no podemos esperar que se dibujen
correctamente.
• Tenemos que evitar utilizar polígonos que no se
sitúen en el mismo plano.
OpenGL: Más ejemplos
• Ejemplo:
glBegin(GL_QUADS);
glVertex3f(-1, 1, 0);
glVertex3f(-1, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, 1, 0);
glEnd();
– Este tipo de operación se llama inmediata: (“immediate-mode
rendering”) dado que los comandos se ejecutan de forma
instantánea.
OpenGL: Dibujando triángulos
• Podemos dibujar triángulos con
glBegin(GL_TRIANGLES) and glEnd():
float v1[3], v2[3], v3[3], v4[3];
...
glBegin(GL_TRIANGLES);
glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3);
glVertex3fv(v1); glVertex3fv(v3); glVertex3fv(v4);
glEnd();
• Cada conjunto de 3 vértices forma un triángulo
– ¿Qué crees que se dibujaría?
– ¿Crees que es redundante?
OpenGL: Dibujando tiras
•
En OpenGL un “triangle strip“ es una primitiva que reduce el trabajo reutilizando los vértices:
glBegin(GL_TRIANGLE_STRIP);
glVertex3fv(v0);
glVertex3fv(v1);
glVertex3fv(v2);
v0
glVertex3fv(v3);
glVertex3fv(v4);
glVertex3fv(v5);
glEnd();
–
–
–
–
v1
Triángulo 0 es v0, v1, v2
Triángulo 1 es v2, v1, v3 (no v1, v2, v3?)
Triángulo 2 es v2, v3, v4
Triángulo 3 es v4, v3, v5 (de nuevo, no v3, v4, v5)
v2
v4
v5
v3
OpenGL: Cara frontal y trasera
• Cada polígono tiene dos caras: una frontal y otra
trasera.
• OpenGL puede dibujar de dos formas diferentes
• El orden de los vértices define la cara frontal:
– Cuando lo vemos desde la cara frontal, los vértices se
definen en el orden contrario a las agujas del reloj
(counterclockwise)
Doble Buffering
• Evita que se dibujen imágenes a medio construir
• OpenGL genera una imagen mientras presenta otra
en el monitor
• glxSwapBuffers (Display *dpy, Window, w)
• glutSwapBuffers (void)
Jugando con OpenGL
Jugando con OpenGL
Introducción a OpenGL
• OpenGL utiliza matrices (Matrix)
– Las matrices describen el tipo de cámaras
– Las matrices describen la configuración actual del espacio
3D
Introducción a OpenGL
• Sistema de coordenadas en OpenGL
– De “mano derecha”
– Por defecto, la cámara mira hacia el eje z en sentido negativo
(hacia abajo).
Introducción a OpenGL
• Por lo tanto…
– X-axis = pulgar = 1, 0, 0
– Y-axis = índice = 0, 1, 0
– Z-axis = medio = 0, 0, 1
1 0 0 
0 1 0 


0 0 1 
– Supongamos que queremos cambiar la cámara
– Y que deseamos mirar hacia abajo en el eje X.
– Antes de ver la solución, veamos la importancia de las
matrices.
Uso de matrices.
Ejemplo con escalado
Una operación de escalado:
O en la forma matricial:
 x' ax
 y'  by
   
 x'  a
 y '  0
  
scaling matrix
0  x 



b  y 
Rotación en 2-D
(x’, y’)
(x, y)

x’ = x cos() - y sin()
y’ = x sin() + y cos()
Rotación en 2-D
(x’, y’)
(x, y)

f
x = r cos (f)
y = r sin (f)
x’ = r cos (f + )
y’ = r sin (f + )
Es igual a …
x’ = r cos(f) cos() – r sin(f) sin()
y’ = r sin(f) sin() + r cos(f) cos()
Que resulta …
x’ = x cos() - y sin()
y’ = x sin() + y cos()
Rotación 2-D
Esto lo podemos expresar en una matriz:
 x' cos   sin    x 
 y'   sin   cos    y 
  
 
Incluso si sin() y cos() no son funciones lineales de ,
x’ es una combinación lineal de x e y
y’ es una combinación lineal de x e y
Una matriz es un operador lineal.
Más adelante veremos la importancia de este hecho.
Introducción a OpenGL
• Retomemos nuestros ejes, si queremos cambiar la
forma de presentar los ejes
• Entonces utilizaríamos una matriz de transformación
– Si eje x  eje z negativo
• x  -z
• yy
• zx
 0 0 1
 0 1 0


1 0 0
Introducción a OpenGL
• La matriz a i define una transformación:
1 0 0
 a b c
0 1 0
d e f

 
 =


0 0 1
 
g h i

 0 0 1
 0 1 0


1 0 0
• ¿Qué opináis? ¿Guardamos la matriz de transformación o el
resultado final de aplicarla?
• Guardamos la matriz de transformación.
Introducción a OpenGL
• La transformada se aplicará a muchos puntos
– Si la transformada mueve los ejes,
1 0 0
 a b c
0 1 0
d e f

 



0 0 1
 
g h i

=
 0 0 1
 0 1 0


1 0 0
– La misma transformada moverá todos los demás puntos
• Ejemplo: (1, 1, -1)  (-1, 1, -1)

0 0 1i i'
0 1 0jj'

   

1 0 0

k
 
k'

Introducción a OpenGL
• Esta matriz es MUY importante y se denomina la matriz
MODELVIEW
– Esta matriz MODELVIEW es tan importante que OpenGL mantiene una
pila de ellas.
– Tenemos el control de dicha pila mediante glPushMatrix y glPopMatrix.
– La matriz es realmente de 4x4, pero esos detalles los vermos en breve.
• Además, OpenGL tiene una matriz similar para describir la
cámara. Esta matriz se llama PROJECTION_MATRIX
Introducción a OpenGL
• Un pequeño ejemplo:
– Vamos a ver cómo manejar MODELVIEW
– Para ello vamos a utilizar:
•
•
•
•
•
glLoadIdentity();
glTranslatef(GLfloat x, y, z);
glRotatef(GLfloat degrees, x, y, z);
glScalef (GLfloat x, y, z);
glPushMatrix(), glPopMatrix();
Trabajando con Transformaciones
• glTranslate (x, y, z)
– Post-multiplica la matriz actual por una matriz que mueve
los objetos a los valores x, y, z
• glRotate (theta, x, y, z)
– Post-multiplica la matriz actual por una matriz que rota el
objeto de forma “counterclockwise” sobre la línea que
forma el origen y el punto (x, y, z)
Trabajando con Transformaciones
• glScale (x, y, z)
– Post-multiplica la matriz actual por una matriz que escala
el objeto en cada eje.
Trabajando con Transformaciones
• Es importante que entendamos cómo funciona el orden de las
transformaciones.
glMatrixMode (MODELVIEW);
glLoadIdentity();
glMultMatrix(N);
glMultMatrix(M);
glMultMatrix(L);
El valor de Modelview es:
I(dentity), N, NM, NML
glBegin(POINTS);
glVertex3f(v);
glEnd();
El vértice es:
NMLv = N(M(Lv))
Manipulando la Pila
• Algunas transformaciones se comparten entre varios modelos
• Nos gustaría evitar tener que cargar continuamente la misma
secuencia de transformaciones.
• glPushMatrix ( )
– Guarda (apila) una matriz en la pila
• glPopMatrix ( )
– Extrae (desapila) la última matriz almacenada
Manipulando la Pila
• Veamos cómo se comporta este ejemplo
draw_wheel( );
for (j=0; j<5; j++) {
glPushMatrix ();
glRotatef(72.0*j, 0.0, 0.0, 1.0);
glTranslatef (3.0, 0.0, 0.0);
draw_bolt ( );
glPopMatrix ( );
}
Manipulando las transformaciones
draw_wheel( );
for (j=0; j<5; j++) {
glPushMatrix ();
glRotatef(72.0*j, 0.0, 0.0, 1.0);
glTranslatef (3.0, 0.0, 0.0);
draw_bolt ( );
glPopMatrix ( );
R
RT
RTv
Global – Bottom Up
Start
Trans
Rot
Manipulando las transformaciones
draw_wheel( );
for (j=0; j<5; j++) {
glPushMatrix ();
glRotatef(72.0*j, 0.0, 0.0, 1.0);
glTranslatef (3.0, 0.0, 0.0);
draw_bolt ( );
glPopMatrix ( );
R
RT
RTv
Local – Top Down
Start
Rot
Trans
Jugando con las transformaciones
Jugando con las transformaciones
Jugando con las transformaciones
Jugando con las transformaciones
Transformaciones básicas en 2D
Translación:
x’ = x + tx
y’ = y + ty
Escalado:
x’ = x * sx
y’ = y * sy
Cizalla (Shear):
x’ = x + hx*y
y’ = y + hy*x
Rotación:
x’ = x*cosQ - y*sinQ
y’ = x*sinQ + y*cosQ
Las transformaciones se
pueden combinar
(utilizando álgebra básica)
Representación matricial
• Una transformación se puede representar por una
matriz:
a b 
 c d 
• Multiplicando la matriz por una vector columna
 estamos aplicando una transformada a un
vértice
 x '  a
 y '  c
b  x
d   y 
x'  ax  by
y '  cx  dy
Representación matricial
• Las transformaciones se concadenan al multiplicar
matrices:
 x'  a
 y '  c
b  e
d   g
f  i
h  k
j x
l   y 
Las matrices son realmente útiles para representar
una sucesión de transformaciones!
Matrices de 2x2
• ¿Qué podemos representar con matrices de 2x2?
Identidad en 2D
x'  x
y'  y
 x '   1
 y ' 0
0  x 
1   y 
Escalado en 2D sobre el origen (0,0)
x'  s x * x
y'  s y * y
 x '  s x
 y '   0
  
0  x

s y   y 
Matrices de 2x2
• ¿Qué podemos representar con matrices de 2x2?
Rotaciones en 2D
x'  cosQ * x  sin Q * y
y'  sin Q * x  cosQ * y
Cizalla en 2D
x '  x  shx * y
y'  shy * x  y
 x' cosQ
 y'   sin Q
  
 sin Q  x 
cosQ   y 
 x '  1
 y '   sh
   y
shx   x 
1   y 
Matrices de 2x2
• ¿Qué podemos representar con matrices de 2x2?
Operación espejo sobre el eje Y
x'   x
y'  y
 x '     1 0  x 
 y '  0 1   y 
Operación espejo sobre el origen
x'   x
y'   y
 x'   1 0   x 
 y '  0  1  y 
Transformaciones lineales
• Las transformaciones lineales son una combinación de …
–
–
–
–
Escalado,
Rotación,
Cizalla, y
Espejo
 x'  a
 y '   c
  
b  x
d   y 
• Recuerda que las propiedades de una transformada lineal garantizan que:
–
–
–
–
–
El origen se convierte en origen
Las líneas se transforman en líneas
Las líneas paralelas se conservan
Las proporciones se conservan
Es una operación cerrada
T (s1p1  s2p 2 )  s1T (p1 )  s2T (p 2 )
¿Y qué hacemos con la translación?
¿Se puede representar una translación con una matriz 2x2?
x'  x  t x
y'  y  t y
NO!
Las matrices 2x2 únicamente se pueden utilizar
para representar transformaciones lineales
Coordenadas homogéneas
• Coordenadas homogéneas
– Representan coordenadas en
2D pero utilizan un vector de
3D
– Fueron introducidas por el
matemático alemán August
Ferdinand Möbius en el año
1837.
 x
 x  homogeneous coords  
 y      y 
 
 1 
Aunque no son nada intuitivas son de gran
utilidad para los sistemas gráficos!!
Coordenadas homogéneas
• ¿Y de qué nos sirve para la translación?
x'  x  t x
y'  y  t y
• De mucho!!
1

Translation  0
0

0
1
0
tx 

ty
1 
Translación
• Ejemplo
 x ' 1 0 t x   x   x  t x 
 y '  0 1 t   y    y  t 
y  
y
  

 1  0 0 1   1   1 
tx = 2
ty = 1
Coordenadas homogéneas
• Añade una tercera coordenada a cada punto 2D
– (x, y, w) representa un punto en la posición (x/w, y/w)
– (x, y, 0) representa un punto en el infinito
– (0, 0, 0) no está permitido
y
2
(2,1,1) O (4,2,2) O (6,3,3)
1
1
2
x
Transformaciones básicas en 2D
• Las transformaciones básicas en 2D se realizan
utilizando matrices de 3x3
 x ' 1
 y '  0
  
 1  0
0
1
0
 x '  s x
 y '   0
  
 1   0
t x  x
t y   y 
1   1 
Translación
 x' cos Q
 y '   sin Q
  
 1   0
 sin Q
cos Q
0
Rotación
0  x 
0  y 
1   1 
0
sy
0
Escalado
0  x 
0  y 
1  1 
 x '  1
 y '   sh
   y
 1   0
shx
1
0
Shear
0  x 
0  y 
1  1 
Transformaciones en 3D
• Utilizamos la misma idea que en 2D
– Coordenadas homogéneas: (x,y,z,w)
– Las matrices de transformación es de 4x4
 x'   a
 y'  e
 z'    i
 w' m

b
f
j
n
c
g
k
o
d  x 
h  y 
l  z 
p   w
Transformaciones en 3D
 x '  1
 y ' 0
 z '   0
 w  0
0
1
0
0
0
0
1
0
0  x 
0  y 
0  z 
1   w
Identidad
 x ' 1
 y ' 0
 
 z '  0
  
 w  0
0
1
0
0
0
0
1
0
 x '  s x
 y '  0
 
 z'   0
  
w   0
0
sy
0
0
0  x 
0  y 
0  z 
 
1  w 
0
0
sz
0
Escalado
t x  x 
t y   y 
tz  z 
 
1  w 
Translación
 x'  1
 y '  0
 z'   0
 w   0
0
1
0
0
0
0
1
0
Espejo
0  x 
0  y 
0  z 
1   w
Transformaciones en 3D
Giro sobre el eje Z:
 x' cosQ
 y '  sin Q
 z'   0
 w   0
Giro sobre el eje Y:
 x '  cosQ
 y '  0
 
 z '   sin Q
  
w   0
Giro sobre el eje X:
 x '  1
 y ' 0
 z '   0
 w  0
 sin Q
cos Q
0
0
0
cos Q
sin Q
0
0
1
0
0
0
0
1
0
0  x 
0  y 
0  z 
1  w
sin Q
0
cosQ
0
0  x 
0  y 
0  z 
 
1  w 
0
 sin Q
cos Q
0
0  x 
0  y 
0  z 
1  w