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
• yy
• zx
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 1i i'
0 1 0jj'
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