Subido por jose flores

262426267-Manual-de-OpenGL

Anuncio
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Manual de OpenGL
CURSO DE COMPUTACIÓN GRÁFICA
1
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Indice
Introducción ........................................................................................................................................ 3
Conceptos previos ............................................................................................................................... 4
Funcionamiento de OpenGL ............................................................................................................... 6
Primitivas de dibujo ............................................................................................................................ 9
Transformaciones.............................................................................................................................. 16
Estructura de un programa OpenGL ................................................................................................. 23
Compilación OpenGL ......................................................................................................................... 26
2
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Introducción
OpenGL es una interface de software para el hardware grafico, esta interface consiste de una larga
serie de comandos para manipulación de objetos y operaciones sobre estos los cuales permiten
controlar la implantación realizada en la forma de una maquina de estados finitos, donde cada una
de las variables que determinan el estado se aplican a partir de ese punto hasta que se indique
explícitamente el cambio, así las variables de estado de OpenGL que vamos a utilizar mas
comúnmente son:








Color (de dibujo y de borrado).
Matrices de Transformación (GL_MODELVIEW, GL_PROYECTION).
Patrones (de líneas y de relleno).
Modo de dibujo de polígonos.
Buffers de dibujo.
Buffer de Stencil.
Buffer de profundidad (z-Buffer).
Buffer de acumulacion.
3
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Conceptos previos
4
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
5
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Funcionamiento de OpenGL
Para poder trabajar con OpenGL, primero se debe crear un contexto de trabajo, este contexto
contiene el estado actual de maquina finita, así como las referencias a los diferentes buffers de
trabajo, estos buffers se pueden ver como zonas de memoria correspondiendo a la pantalla en las
cuales OpenGL va a dibujar, en general a parte del buffer de color (GL_COLOR_BUFFER) que es
el buffer en el cual se van a dibujar las primitivas, existen otro tipo de buffers mas especializados.
La configuración en memoria de estos buffers (cuantos bits representan un pixel, etc) depende de la
manera como fue creado el contexto OpenGL y de las limitaciones del hardware, por esto no se
puede acceder directamente sino solo a través de las primitivas OpenGL.
OpenGL puede funcionar adicionalmente de dos maneras, de modo directo o indirecto:

Modo directo: las primitivas se van dibujando a medida que se van definiendo.
Instruccion -> Buffer de Color = Pantalla

Modo indirecto: las primitivas se guardan en una lista y solo se dibujan cuando el usuario
decida o la lista este llena, esto permite optimizar la fase de dibujo.
Instruccion-> Pila de instrucciones-> flush -> Buffer de Color = Pantalla
En este modo cuando se desea que OpenGL pinte lo que está en la lista se utiliza la instrucción
glFlush(): esta instrucción obliga a pintar y no espera a que el hardawre termine para continuar con
el programa, análogamente la glFinish() obliga a pintar pero espera a que el hw termine antes de
continuar con el programa.
En el modo indirecto, OpenGL permite definir dos buffers de colores (doublebuffer), asi un buffer
corresponde a lo que se ve en pantalla y otro a el buffer donde se esta pintando, de esta manera una
vez que se ha pintado todo lo deseado y se quiere que esto aparezca en pantalla se intercambian los
buffers, esta instrucción depende del sistema operativo para esto se utilizara la instruccion de la
libreria portable glut: glutSwapBuffers() (esta ejecuta implicitamente glFlush o glFinish), en este
modo glFlush y glFinish obligan a pintar en el buffer de dibujo pero esto NO sera visible hasta
intercambiar buffers.
6
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Arquitectura gráfica:
7
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
8
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Primitivas de dibujo
En OpenGL solo se pueden dibujar primitivas muy simples, tales como puntos lineas, cuadrados,
triangulos y polygonos, a partir de estas primitivas es posible construir primitivas mas complejas
como arcos y circulos aproximandolos por poligonos.
Toda primitiva de dibujo se construye con un par: glBegin(tipo_de_primitiva); glVertex2f(); ...
glEnd();
Donde tipo_de_primitiva puede ser cualquiera de las siguientes:









GL_POINTS: Cada vertice es un punto
GL_LINES: Cada par de vertices sucesivos es una linea
GL_LINE_STRIP: lineas conectadas.
GL_LINE_LOOP: lineas conectadas donde el ultimo y el primer vertice indican una linea
cerrando el poligono.
GL_POLYGON: poligono (relleno o no) donde los vertices sucesivos componiendolo se
dan el sentido contrario de las manecillas del reloj.
GL_QUADS: cuadrilateros separados, cada 4 vertices hacen un quad.
GL_QUAD_STRIP: tira de cuadrados unidos, cada par de vertices sucesivos forman un
cuadrado con el par anterior.
GL_TRIANGLES: Triángulos separados, cada 3 vértices hacen un triangulo.
GL_TRIANGLE_STRIP: tira de triángulos unidos (similara quad_strip).
9
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software

UNMSM
Ciclo 2015 – I
GL_TRIANGLE_FAN: Grupo de triangulos con un unico vertice comun a todos.
Puntos
Un punto se define mediante la función glVertex, esta función especifica las coordenadas del punto
dentro de la ventana de visualización. Con esta función podremos definir puntos en dos y tres
dimensiones, dependiendo del número de coordenadas que se detallan. OpenGL trabaja
normalmente en coordenadas homogéneas representadas por cuatro componentes, (x, y, z, h), por lo
tanto cuando estamos definiendo puntos en dos dimensiones el valor z coge el valor cero y h el
valor 1, en tres dimensiones h coge el valor 1.
El tipo especificado de coordenadas viene determinado a partir según los sufijos que siguen a la
función glvertex. Los sufijos que pueden seguir a la función serán, d (double), indica que las
coordenadas deben especificarse en valores double, f (float), i (integer) y finalmente s (short), por lo
tanto las coordenadas deberán indicarse con valores que correspondan al sufijo. Existe la
posibilidad de definir un punto mediante un vector que contenga las coordenadas, para ello
deberemos utilizar el sufijo v indicando que es un vector de coordenadas.
Gldouble v[3]= {4.5, 6.7, 23.8}
glVertex(v);
Para definir un punto o conjuntos de puntos debemos especificar las siguientes cláusulas
glBegin(GL_POINTS) y la cláusula glEnd(), detallando entre ambas las posiciones de cada punto,
así tenemos por ejemplo:
glBegin(GL_POINTS)
glVertex2f(50.4,34.6); //Punto 2D,en punto flotante
glVertex3i(10,20 34); //Punto 3D, en enteros
glEnd();
Por lo tanto para definir un conjunto de punto sobre la ventana de visualización podemos emplear la
estructura anterior.
Una vez definido los puntos podemos modificar su tamaño empleando la sentencia
glPointSize(valor), donde valor representa el tamaño con el que deseamos dibujar el punto.
Líneas
10
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
De la misma forma que definimos puntos podemos definir líneas. Para definir una línea se precisan
dos puntos, estos dos puntos se definen de la misma forma que al definir un punto de la pantalla, es
decir con la función glVertex.
Existen diversas formas de definir líneas dependiendo del modo en que se describa en la cláusula
glBegin(modo), modo representará el tipo de línea que deseamos.
Modo
Descripción
GL_LINES
Genera una serie de líneas que no se conectan entre sí. Las líneas se
definen mediante los pares de puntos sucesivos, por lo tanto el número de
vértices debe ser par, en el caso de que fuera impar se ignoraría
Genera una serie de líneas pero que se conectan entre sí, es decir el punto
final de una línea es el punto inicial de la siguiente. Con este modo se
pueden generar figuras cerradas si el punto inicial coincide con el final.
GL_LINE_STRIP
GL_LINE_LOOP
Genera una serie de líneas conectadas entre sí, es parecido al modo
anterior pero este modo conecta automáticamente el punto inicial con el
punto final.
Podemos ver el efecto de los diferentes modos en el siguiente código:
glBegin (MODO);
glVertex2f(0.0,
glVertex2f(1.0,
glVertex2f(1.0,
glVertex2f(0.0,
glEnd;
0.0);
0.0);
1.0);
1.0);
Gráficamente quedará de la siguiente forma, según el valor de MODO.
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
11
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
(0,1)
(1,1)
(0,1)
(1,1)
(0,1)
(1,1)
(0,0)
(1,0)
(0,0)
(1,0)
(0,0)
(1,0)
El aspecto de las líneas también pueden modificarse, pudiendo crear líneas más gruesas y con
formato punteado, para ello se utilizará los comandos:
glEnable(GL_LINE_STIPPLE);
glLineStipple( factor, mascara);
glDisable(GL_LINE_STIPPLE);
Con estos comandos podemos conseguir líneas punteadas, la primera instrucción activa el modo de
línea punteada, mientras que el segundo define el estilo de la línea, donde factor es un valor que
está comprendido entre 1 y 255, este valor define la separación entre los trozos de la línea, mientras
que máscara, es un valor de 16 bits que se describe en hexadecimal, cada máscara define un
formato de línea, los valores van comprendidos entre 0x0000 hasta 0xAAAA.
Otra posibilidad que tenemos es modificar el grosor de la línea, para ello utilizaremos la siguiente
instrucción:
glLineWidth(tamaño);
Por defecto OpenGL define las líneas con tamaño 1.0, pero podemos modificarlo mediante la
sentencia anterior. Hay que tener en cuenta que una vez activado el tamaño hay que volver a
establecer si deseamos líneas con el tamaño por defecto.
Polígonos
OpenGL define los polígonos como secuencia de aristas, por lo tanto sigue con el mismo formato
especificado en los puntos anteriores.
Para generar polígonos tenemos los siguientes modos para la sentencia glBegin(modo), estos son:
Modo
Descripción
GL_POLYGON
Genera un simple poligono relleno con los vertices especificados.
Para generar un poligono debemos tener en cuenta que se debe
12
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
garantizar tres cosas:

Como mínimo se precisan 3 vertices.

Las líneas no deben cruzarse.

GL_TRIANGLES
Los vertices deben formar un poligono convexo, en
caso contrario OpenGL ignorará el vertice.
Genera una serie de triangulos rellenos que no se conectan entre sí.
El número de vertices debe ser multiplo de 3, si el total de vertices es
menor de tres, OpenGL ignora los vertices que no forma un
triángulo.
Genera una serie de triángulos rellenos conectados entre sí, es decir
dos de los vertices de un triángulo son los vertices del siguiente
GL_TRIANGLE_STRIP triángulo. Debemos saber que con N vertices se pueden crear N-2
triángulos. De igual forma que anteriormente el número de vertices
debe ser multiplo de tres, si no lo es se ignora aquellos que sobran.
GL_TRIANGLE_FAN
Genera un conjunto de triángulos rellenos conectados entre sí, con la
caracteristica de que todos los triángulos tiene un vertice en común.
El primer triángulo defien el vertice comun a todos los triángulos.
De igual forma que los anteriores el número de vertices debe ser
múltiplo de 3, si no lo es se ignora aquellos vertices que sobran.
GL_QUADS
Genera un conjunto de cuadrilateros rellenos sin conectar entre ellos.
El número de vertices que se requiere es multiplo de cuatro, si no se
verifica esto entonces OpenGL ignora los vertices que sobran. Cada
cuatro veretices se describe un cuadrilatero.
GL_QUAD_STRIP
Genera un conjunto de cuadrilateros rellenos que se conectan entre
sí, es decir dos vertices de un cuadrado se utilizan para generar el
siguiente cuadrilatero. Hay que tener en cuenta que si tenemos un
total de N vertices podremos obtener un total de N/2-1 cuadrados. El
número de vertices debe ser multiplo de cautro, si no se verifica
entonces los vertices que sobran son ignorados.
Gráficamente podemos ver las diferencias entre los modos para genera polígonos:
13
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
v2
Ciclo 2015 – I
v0
v1
v1
v1
v4
v2
v5
v3
v5
v0
vo
v3
v4
v2
GL_TRIANGLE_STRIP
GL_TRIANGLES
GL_POLYGON
v1
v1
v1
v0
v0
v2
v0
v2
v3
v4
v7
v3
v4
v2
v3
v4
v6
GL_QUADS
v5
v5
GL_QUAD_STRIP
GL_TRIANGLE_FAN
Dentro del par glBegin, glEnd solo pueden ir instrucciones OpenGL para definir objetos tales como
vértices, y colores (existen otras mas complejas como normales y materiales) y no transformaciones
ni cambios de estado (diferentes a los especificados), adicionalmente dentro del par pueden ir
instrucciones de programación del lenguaje tales que ciclos, condicionales, llamados a funciones,
etc. Siempre y cuando no usen alguna de las funciones OpenGL no permitidas, i.e.:
14
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Muchas primitivas básicas tienen sufijos indicando el tipo del valor o variable que se le pasan como
parámetro, asi como el número de parámetros, asi una instrucción como p.ej. glVertex puede tener
2,3 o 4 parámetros, así comor recibir tipos enteros, flotantes, etc. O un vector conteniendo esos
parámetros Entonces en los manuales se escribe como: glVertex[234][sifd][v] quiere decir que se le
pueden pasar 2,3 ó 4 parametros mas el tipo o un vector, como minimo debe tener el numero de
parámetros y el tipo i.e.:
glVertex2f(1.0,0.0). o si se usa un vector v Glfloat v[3]={1.0,0.5} entonces seria glVertex2fv(v);
los tipos de datos también se pueden usar para definir variables, estos son:
Las primitivas más básicas de dibujo son entonces:
glRect[sid][v]: dibuja un rectángulo, NO puede estar en bloque glBegin/glEnd
glColor3[f][v]: para cambiar el color actual de dibujo, puede estar en bloque glBegin/glEnd
glVertex[234][sifd][v]: vértice de un punto, línea o polígono, SOLO puede estar entre
glBegin/glEnd
Variables de estado que afectan las primitivas anteriores (NO puede estar en bloque
glBegin/glEnd):
glPointSize(size): size= flotante indicando el tamaño de dibujo de un punto > 0.0, 1.0 por defecto.
glLineWidth(size): size= flotante indicando el ancho de dibujo de una línea > 0.0, 1.0 por defecto.
glLineStipple(factor,patron): factor = entero indicando un factor de escalamiento, patrón= short
sin signo conteniendo el patrón de bits par pintar la línea (punteado,etc..)..
glPolygonMode(cara,modo): cara corresponde al lado del polígono, si el que esta hacia el usuario
(pantalla) (GL_FRONT) o hacia el otro lado (GL_BACK) o los dos (GL_FRONT_AND_BACK),
el modo puede ser: relleno (GL_FILL), solo los vértices (GL_POINT), o solo el borde (GL_LINE).
15
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Otras funciones y variables de estado:
glClearColor(r,g,b): r,g,b son flotantes y definen el color de borrado de la pantalla (fondo).
glClear(mask): mask = GL_COLOR_BUFFER_BIT borra el buffer de dibujo con el color de
fondo definido.
Transformaciones
Una vez que tenemos definida la ventana donde realizaremos la escena debemos definir como va a
ser la visualización de esta escena, es decir, deberemos definir aspectos tales como, posición de la
cámara, a que punto mirara la cámara, que tipo de proyección utilizará,... etc.
En este apartado se mostrará como podemos manipular la cámara virtual, es decir el punto desde
donde vemos la imagen, junto con las transformaciones de visualización. Estos dos puntos nos
permitirán definir una visión de los objetos más realista. Otro de los apartados de esta sección será
manipular las transformaciones de proyección, y poder ver los efectos sobre la imagen.
Matriz de visualización
Para poder manipular los objetos de la escena debemos tener definida una matriz de visualización,
esta matriz será de cuatro por cuatro, es decir coordenadas normalizadas. Esta matriz se utiliza tanto
en dos como en tres dimensiones, la diferencia esta en la coordenada z, en el caso de dos
dimensiones z siempre tomará el valor cero, mientras que en tres dimensiones podrá tomar
diferentes valores.
OpenGl, facilita maneras para poder manipular la matriz de visualización. Antes de manipular la
matriz directamente debemos inicializar el modo para la matriz de operaciones, esto se consigue
con la función:
glMatrixMode(GL_MODELVIEW);
Una vez definido el modo de la matriz podemos asignarle un valor con las siguientes funciones:
glLoadIdentity()
Inicializada la matriz de transformaciones con la identidad.
glLoadMatrix(M)
Esta sentencia nos permite inicializar la matriz con un valor dado, especificado por el valor de M.
M puede ser definido como una matriz de cuatro por cuatro o bien por un vector de dieciséis
elementos, (m1, m2, m3,...). Hay que tener en cuenta que los valores de la matriz se especifica por
16
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
columnas, es decir la primera columna corresponde a los valores del vector m1, m2, m3, m4, la
segunda columna corresponderá a los valores m5, m6, m7, m8, y así sucesivamente.
Como vemos estas dos sentencias nos permiten inicializar la matriz de transformaciones, para poder
realizar operaciones precisamos la siguiente instrucción:
glMultMatrix(M)
Esta sentencia nos permitirá multiplicar matrices, teniendo en cuenta que multiplicará la matriz
definida con una de las sentencias anteriores por la matriz M que definimos en este punto.
Vistas
OpenGl permite utilizar diferentes expresiones para definir la posición de la cámara y hacía donde
mira dicha cámara.
En OpenGl la representación de los ejes e coordenadas se describe en el siguiente gráfico.
y
x
z
Existe la posibilidad de manipular estos ejes cambiando la posición relativa de cada uno de ellos,
para ello OpenGl utiliza una serie de sentencias que nos definen como vamos a ver los ejes de
coordenadas y en consecuencia como se visualizará el objeto tridimensional.
gluLookAt()
Esta sentencia permite definir de forma especifica donde se situará la cámara, hacía donde mirara
está y cual va a ser el orden de los ejes de coordenadas.
gluLookAt(x0,y0,z0,xc,yc,zc,Vx,Vy,Vz);
17
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
Esta sentencia tiene nueve argumentos que describen tres puntos, los valores de x0, y0, z0,
representa el punto hacia donde mira la cámara virtual, este punto normalmente se identifica en el
origen de coordenadas (0,0,0), ahora bien podemos definir nosotros el punto que más propicio sea
para nuestra escena.
Los siguientes tres argumentos representan el punto donde se situará la cámara de visualización,
estas coordenadas no deben coincidir con el punto al cual miramos.
Las últimas tres coordenadas representa el vector de vista hacía arriba, es decir indica cual será el
vector cuya dirección será hacia arriba, “apuntará hacia la parte superior del monitor”.
Para entender este caso podemos ver una serie de ejemplos donde se especifica cual es el vector y
como que da definido los ejes de coordenadas:
y
y
x
x
z
z
(Vx,Vy,Vz) = (0,1,0)
(Vx,Vy,Vz) = (1,1,0)
Como podemos ver según sea el valor del vector de vista hacia arriba el objeto que visualizaremos
tendrá un aspecto u otro. Normalmente para simplificar la visualización el vector de vista hacia
arriba se hace coincidir con uno de los ejes de coordenadas, como es el caso del primer gráfico.
glOrtho()
Se utiliza para especificar una proyección ortográfica. Este tipo de proyección define un volumen
de vista rectangular, concretamente define un paralelepípedo de tamaño infinito, este hecho nos
lleva a definir una serie de planos de corte para detallar con exactitud el volumen de vista.
OpenGl define la sentencia como:
glOrtho(xwmin, xwmax, ywmin, ywmax, pcerca, plejos);
18
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
Estos seis argumentos definen la ventana de visualización y los planos de corte tanto cercano como
lejano.
Para definir la ventana de visualización es suficiente definir las coordenadas de dos esquinas de la
ventana, con estos dos valores queda totalmente definida.
Los valores de pcerca y plejos representan el plano cercano y el plano lejano. Hay que tener en
cuenta que el objeto a visualizar debe encontrarse dentro de ambos planos, si sobrepasan estos dos
planos el objeto se recortará automáticamente.
Plano de corte lejano
plejos
pcerca
Plano de corte cercano
(xwmax, ywmax)
(xwmin, ywmin)
El objeto se visualizará entre los dos planos de recorte, en el caso que sobrepase estos planos se
recortará, y si el objeto es tan grande que la ventana de visualización esta dentro de él, no se
visualizará nada quedando la pantalla en negro.
Hay que tener en cuenta que si el plano de corte es negativo esté se encontrará detrás de la ventana
de visualización.
glFrustum()
Este comando se utiliza para definir una proyección perspectiva, se define de forma similar a la
proyección ortográfica pero con la diferencia que la proyección perspectiva define como volumen
de vista una pirámide, en consecuencia el objeto a visualizar tiene un aspecto mucho más realista.
La sentencia que utiliza OpenGl es:
glFrustum(xwmin, xwmax, ywmin, ywmax, pcerca,plejos);
Como vemos esta sentencia se define de forma similar a la utilizada para definir proyecciones
paralelas, de igual forma que anteriormente definimos planos de corte para limitar el volumen de
vista, que en este caso al ser una proyección perspectiva definirá un tronco piramidal.
19
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
plejos
Plano de corte lejano
(xwmax, ywmax)
Plano de corte cercano
(xwmin, ywmin)
pcerca
Punto de vista
Como vemos ambas sentencias se define de forma similar pero determina vistas muy diferentes
entre sí.
gluPerpespective()
Esta sentencia es una alternativa a la función glFrustum, la diferencia entre ambas está en la forma
de definir la ventana de visualización. Si en la sentencia glFrustum definimos los dos vértices
necesarios de la ventana, en la sentencia glPerpestive solamente definiremos el ángulo de apertura
de la cámara y la relación entre el largo y ancho del plano cercano de corte.
La sentencia en OpenGl será pues de la forma:
gluPerpective(apertura, aspect, pcerca, plejos);
Apertura corresponde al ángulo de apertura de la cámara virtual, este ángulo puede tomar valores
comprendidos entre 0º y 180º. El valor de aspect, vendrá dado por la relación entre el alto y ancho
del plano de corte, por lo tanto aspect toma el valor de alto plano dividido entre largo plano.
Los valores de pcerca y plejos corresponden a los plano de corte cercano y lejano, de forma similar
que en los casos anteriores.
20
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
plejos
Plano de corte lejano
Plano de corte cercano
pcerca
Apertura
Punto de vista
Las transformaciones se realizan multiplicando por las matrices y se aplican en sentido inverso al
que se escriben, esto es si quiero rotar y luego trasladar un objeto en el código, primero traslado,
luego roto y luego si pinto mi objeto (es también en sentido inverso al que se lee el código),
OpenGL trabaja con dos matrices diferentes:


GL_MODELVIEW: es la matriz donde se trabajan con las transformaciones.
GL_PROJECTION: es donde se define la relación mundo viewport.
Para cambiar de matriz a utilizar se usa la instrucción:
glMatrixMode(modo): es uno de los dos modos de matriz.
Adicionalmente, la matriz en uso se puede guardar y eliminar de una pila:
glPushMatrix(): coloca la matriz en la pila.
glPopMatrix(): quita la matriz de la pila.
La pila de la matriz de proyección tiene un límite máximo de 2 en la mayoria de las
implementaciones. Para trabajar con la matriz directamente se tiene:
21
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
glLoadIdentity(): inicializa la matriz actual con una matriz identidad.
glMultMatrix(matriz): matriz = vector de 16 flotantes con el que multiplica la matriz actual.
glLoadMatrix(matriz): matriz = vector de 16 flotantes con el que reemplaza la matriz actual.
glGetFloatv(modo,m): modo = uno de los modos de matriz.
matriz = vector de 16 flotantes en el que se recupera la matriz actual de OpenGL.
Para no tener que generar sus propias matrices, se proveen instrucciones de tranformacion:
glRotate[fd](a,x,y,z): rota un angulo a alrededor del vector x,y,z
glTranslate[fd](x,y,z): traslada una cantidad x,y,z.
glScale[fd](sx,sy,sz): multiplica cada coordenada por el valor de escalamiento correspondiente.
22
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Estructura de un programa OpenGL
Para la creacion de programas OpenGL se va a utilizar la libreria GLUT, esta libreria permite
olvidarse de los problemas especificos de cada plataforma, La estructura general de un programa
utilizando la libreria GLUT es la siguiente (en C o C++ es las funciones de opengl son las mismas):
23
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Manejo de Buffers
Para utilizar los diferentes tipos de buffers de OpenGL estos se deben crear al crear el contexto
OpenGL, en el caso de la utilización de la libreria glut, al llamar la funcion: glutInitDisplayMode
(buffers), buffers es una combinación de valores indicando que buffers se deben crear i.e. para crear
un contexto con doble buffer rgba y z-buffer buffers seria = GLUT_RGBA | GLUT_DOUBLE |
GLUT_DEPTH, los valores para crear otro tipos de buffers son:
GLUT_STENCIL = buffer de stencil.
GLUT_ACCUM = buffer de acumulación.
Todos los buffers deben ser activados o desactivados dependiendo de la utilizacion con el comando
glEnable(param) o glDisable(param), donde param corresponde al tipo de test que se activa, i.e
param= GL_STENCIL_TEST para el buffer de stencil, o param=GL_DEPTH_TEST para el buffer
de profundidad (activado por defecto).
Los buffers de stencil, acumulacion y profundidad funcionan aplicando una serie de operaciones y
funciones sobre los valores que se van a escribir en el buffer, asi para manejar la funcion del buffer
de profundidad se utiliza la funcion glDepthFunc(funcion), donde funcion indica cuando pasa el
test de profundidad (GL_EQUAL, GL_LESS, GL_LEQUAL (por defecto), GL_NOTEQUAL,
GL_GREATER, GL_GEQUAL). En el caso de la funcion de test, se define glStencilFunc(funcion,
mascara), donde funcion son las mismas que para la profundidad, y mascara indica que bits del
stencil se utilizan. Adicionalmente a la funcion de stencil, se utiliza la operacion de stencil
glStencilOp(fallo,zfallo,zpaso) que especifica como se modifica el buffer de stencil dependiendo de
si la funcion del buffer stencil y z fallaron o pasaron, pueden ser GL_KEEP,GL_ZERO,
GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT.
Manejo de Animacion y Timers
Opengl no maneja animacion ni timers directamente ya que esto depende del sistema operativo,
OpenGL solo se preocupa de colocar poligonos en la pantalla, y solo seria cuestion de ordenarle de
manera ciclica el repintar la pantalla con paramentros nuevos, el problema se encuentra cuando se
desea que la animacion se no bloqueante, la libreria GLUT nos facilita el manejo de la animacion de
dos maners independientemente del Sistema operativo de manera no bloqueante:
a. Función de animacion Idle, GLUT nos permite manejar la animacion definiendo una
funcion de animacion con la funcion glutIdleFunc(funcname), donde funcname es el
nombre de la funcion que se va a llamar para realizar la animacion, esta funcion no recibe
ni retorna parametro alguno, esta funcion se debe encargar de calcular los parametros de la
animacion y luego llamar la funcion de dibujo, esta no se debe llamar directamente sino con
24
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
la funcion glutPostRedisplay() que quiere decir que solo se llama una vez se acabe de
calcular la funcion idle, esta funcion idle no se ejecuta de manera regular, solo se ejecuta
una vez se hallan procesado todos los eventos que recibe la aplicacion tales como teclado,
repintar, etc. Por lo tanto la velocidad de la animacion resultante puede no ser constante.
b. Funciones de Timers, para evitar el problema de la velocidad de animacion irregular y para
tener mas control sobre el tiempo de ejecucion de la funcion de animacion, glut nos permite
definir timers de a los cuales le asignamos una funcion que se debe ejecutar cada cierto
tiempo definido por el timer, para definir estos timers se utiliza la funcion:
glutTimerFunc(tiempo,funciontimer,valor), donde tiempo es el tiempo en milisegundos del
timer, funciontimer es la funcion a llamar la cual no devuelve nada pero recibe un
parametro entero (valor), valor es el parametro que se le va a pasar a la funcion. Esta
funcion se ejecuta dentro del tiempo determinado y termina, si se desea que se vuelva a
llamar, al final de la funcion se debe instalar de nuevo el timer. El valor sirve para
seleccionar diferentes acciones la proxima vez que se llame el timer, como estas funciones
no reciben parametros, cualquier resultado debe ser devuelto por una variable global.
25
Facultad de Ingeniería de Sistemas e Informática
Escuela académico profesional de Ingeniería de Software
UNMSM
Ciclo 2015 – I
Compilación OpenGL
Compilacion de aplicaciones OpenGL en Windows
Para compilar un programa OpenGL suponiendo que se está en un sistema operativo MS-Windows,
con el compilador VisualC++, se debe recuperar la librería glut para windows (glut.h glut32.lib y
glut32.dll), los archivs .h y . lib se deben colocar en el directorio respectivo para includes y librerias
del VisualC, el archivo glut32.dll se debe colocar en el directorio system32 de windows idealmente
o en su defecto en el directorio donde va a quedar el ejecutable.
En el VisualC se debe crear un proyecto nuevo de tipo win32 o win32 consola (si se va a utilizar
GLUT NO! se debe crear proyecto de tipo MFC) En las opciones de compilacion del proyecto, en el
tabulador de encadenamiento, se debe adicionar las siguientes librerias en este orden especifico:
glut32.lib glu32.lib opengl32.lib.
Pero también se pueden utilizar distintos lenguajes de programación, como por ejemplo: C++
Builder o Delphi.
Compilacion de aplicaciones OpenGL en Linux
Para compilar un programa OpenGL suponiendo que se está en sistema operativo UNIX o Linux
con las librerias instaladas en lugares estandar se debe dar el siguiente comando suponiendo que
todo el programa está en un solo archivo:
Programa esta en C:
gcc -o nombre_ejecutable nombre_programa.c –lglut –lGLU –lGL lm
Programa esta en C++:
g++ -o nombre_ejecutable nombre_programa.c –lglut –lGLU –lGL lm
Si el programa esta compuesto por varios modulos C o C++ se debe realizar un archivo llamado:
Makefile, este archivo debe ser de la manera siguiente:
26
Facultad de Ingeniería de Sistemas e Informática
UNMSM
Escuela académico profesional de Ingeniería de Software
Ciclo 2015 – I
Las identaciones en el archivo son tabulador no espacios en blanco!.
Solo se debe cambiar nombre programa por el nombre del archivo que contiene la funcion main, y
modulo1, modulo2, etc por los nombres de los otros archivos conteniendo otras funciones del
programa, para compilar solo basta dar en la linea de comandos el comando:
make
Para correr el programa ya sea que se haya compilado con la ayuda de make o directamente a mano
con gcc/g++ solo basta dar el comando:
./nombredeprograma
Para mas informacion sobre el comando make dar el comando:
falle:
man make ,o en caso que este
info make
Para mas informacion sobre opciones gcc/g++ dar el comando: man gcc ,o: man g++
27
Descargar