Академический Документы
Профессиональный Документы
Культура Документы
UNMSM
Ciclo 2015 I
Manual de OpenGL
CURSO DE COMPUTACIN GRFICA
UNMSM
Ciclo 2015 I
Indice
Introduccin ........................................................................................................................................ 3
Conceptos previos ............................................................................................................................... 4
Funcionamiento de OpenGL ............................................................................................................... 6
Primitivas de dibujo ............................................................................................................................ 9
Transformaciones.............................................................................................................................. 16
Estructura de un programa OpenGL ................................................................................................. 23
Compilacin OpenGL ......................................................................................................................... 26
UNMSM
Ciclo 2015 I
Introduccin
OpenGL es una interface de software para el hardware grafico, esta interface consiste de una larga
serie de comandos para manipulacin de objetos y operaciones sobre estos los cuales permiten
controlar la implantacin 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
explcitamente el cambio, as las variables de estado de OpenGL que vamos a utilizar mas
comnmente son:
UNMSM
Ciclo 2015 I
Conceptos previos
UNMSM
Ciclo 2015 I
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 configuracin 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 travs 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 instruccin
glFlush(): esta instruccin obliga a pintar y no espera a que el hardawre termine para continuar con
el programa, anlogamente 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 instruccin 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.
UNMSM
Ciclo 2015 I
Arquitectura grfica:
UNMSM
Ciclo 2015 I
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:
UNMSM
Ciclo 2015 I
Puntos
Un punto se define mediante la funcin glVertex, esta funcin especifica las coordenadas del punto
dentro de la ventana de visualizacin. Con esta funcin podremos definir puntos en dos y tres
dimensiones, dependiendo del nmero de coordenadas que se detallan. OpenGL trabaja
normalmente en coordenadas homogneas 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 segn los sufijos que siguen a la
funcin glvertex. Los sufijos que pueden seguir a la funcin sern, d (double), indica que las
coordenadas deben especificarse en valores double, f (float), i (integer) y finalmente s (short), por lo
tanto las coordenadas debern 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.
Para definir un punto o conjuntos de puntos debemos especificar las siguientes clusulas
glBegin(GL_POINTS) y la clusula 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 visualizacin podemos emplear la
estructura anterior.
Una vez definido los puntos podemos modificar su tamao empleando la sentencia
glPointSize(valor), donde valor representa el tamao con el que deseamos dibujar el punto.
Lneas
10
UNMSM
Ciclo 2015 I
De la misma forma que definimos puntos podemos definir lneas. Para definir una lnea 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 funcin glVertex.
Existen diversas formas de definir lneas dependiendo del modo en que se describa en la clusula
glBegin(modo), modo representar el tipo de lnea que deseamos.
Modo
Descripcin
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
glBegin (MODO);
glVertex2f(0.0,
glVertex2f(1.0,
glVertex2f(1.0,
glVertex2f(0.0,
glEnd;
0.0);
0.0);
1.0);
1.0);
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
11
UNMSM
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 lneas tambin pueden modificarse, pudiendo crear lneas ms 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 lneas punteadas, la primera instruccin activa el modo de
lnea punteada, mientras que el segundo define el estilo de la lnea, donde factor es un valor que
est comprendido entre 1 y 255, este valor define la separacin entre los trozos de la lnea, mientras
que mscara, es un valor de 16 bits que se describe en hexadecimal, cada mscara define un
formato de lnea, los valores van comprendidos entre 0x0000 hasta 0xAAAA.
Otra posibilidad que tenemos es modificar el grosor de la lnea, para ello utilizaremos la siguiente
instruccin:
glLineWidth(tamao);
Por defecto OpenGL define las lneas con tamao 1.0, pero podemos modificarlo mediante la
sentencia anterior. Hay que tener en cuenta que una vez activado el tamao hay que volver a
establecer si deseamos lneas con el tamao por defecto.
Polgonos
OpenGL define los polgonos como secuencia de aristas, por lo tanto sigue con el mismo formato
especificado en los puntos anteriores.
Para generar polgonos tenemos los siguientes modos para la sentencia glBegin(modo), estos son:
Modo
Descripcin
GL_POLYGON
12
UNMSM
Ciclo 2015 I
GL_TRIANGLES
GL_TRIANGLE_FAN
GL_QUADS
GL_QUAD_STRIP
Grficamente podemos ver las diferencias entre los modos para genera polgonos:
13
UNMSM
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
vrtices, 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 programacin 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
UNMSM
Ciclo 2015 I
Muchas primitivas bsicas tienen sufijos indicando el tipo del valor o variable que se le pasan como
parmetro, asi como el nmero de parmetros, asi una instruccin como p.ej. glVertex puede tener
2,3 o 4 parmetros, as comor recibir tipos enteros, flotantes, etc. O un vector conteniendo esos
parmetros 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
parmetros 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 tambin se pueden usar para definir variables, estos son:
Variables de estado que afectan las primitivas anteriores (NO puede estar en bloque
glBegin/glEnd):
glPointSize(size): size= flotante indicando el tamao de dibujo de un punto > 0.0, 1.0 por defecto.
glLineWidth(size): size= flotante indicando el ancho de dibujo de una lnea > 0.0, 1.0 por defecto.
glLineStipple(factor,patron): factor = entero indicando un factor de escalamiento, patrn= short
sin signo conteniendo el patrn de bits par pintar la lnea (punteado,etc..)..
glPolygonMode(cara,modo): cara corresponde al lado del polgono, 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 vrtices (GL_POINT), o solo el borde (GL_LINE).
15
UNMSM
Ciclo 2015 I
Transformaciones
Una vez que tenemos definida la ventana donde realizaremos la escena debemos definir como va a
ser la visualizacin de esta escena, es decir, deberemos definir aspectos tales como, posicin de la
cmara, a que punto mirara la cmara, que tipo de proyeccin utilizar,... etc.
En este apartado se mostrar como podemos manipular la cmara virtual, es decir el punto desde
donde vemos la imagen, junto con las transformaciones de visualizacin. Estos dos puntos nos
permitirn definir una visin de los objetos ms realista. Otro de los apartados de esta seccin ser
manipular las transformaciones de proyeccin, y poder ver los efectos sobre la imagen.
Matriz de visualizacin
Para poder manipular los objetos de la escena debemos tener definida una matriz de visualizacin,
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 visualizacin. Antes de manipular la
matriz directamente debemos inicializar el modo para la matriz de operaciones, esto se consigue
con la funcin:
glMatrixMode(GL_MODELVIEW);
Una vez definido el modo de la matriz podemos asignarle un valor con las siguientes funciones:
glLoadIdentity()
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 diecisis
elementos, (m1, m2, m3,...). Hay que tener en cuenta que los valores de la matriz se especifica por
16
UNMSM
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 instruccin:
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 posicin de la cmara y haca donde
mira dicha cmara.
En OpenGl la representacin de los ejes e coordenadas se describe en el siguiente grfico.
y
Existe la posibilidad de manipular estos ejes cambiando la posicin 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 cmara, haca 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
UNMSM
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 cmara virtual, este punto normalmente se identifica en el
origen de coordenadas (0,0,0), ahora bien podemos definir nosotros el punto que ms propicio sea
para nuestra escena.
Los siguientes tres argumentos representan el punto donde se situar la cmara de visualizacin,
estas coordenadas no deben coincidir con el punto al cual miramos.
Las ltimas tres coordenadas representa el vector de vista haca arriba, es decir indica cual ser el
vector cuya direccin 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 segn sea el valor del vector de vista hacia arriba el objeto que visualizaremos
tendr un aspecto u otro. Normalmente para simplificar la visualizacin el vector de vista hacia
arriba se hace coincidir con uno de los ejes de coordenadas, como es el caso del primer grfico.
glOrtho()
Se utiliza para especificar una proyeccin ortogrfica. Este tipo de proyeccin define un volumen
de vista rectangular, concretamente define un paraleleppedo de tamao 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:
18
UNMSM
Ciclo 2015 I
Estos seis argumentos definen la ventana de visualizacin y los planos de corte tanto cercano como
lejano.
Para definir la ventana de visualizacin 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 automticamente.
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 visualizacin 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 detrs de la ventana
de visualizacin.
glFrustum()
Este comando se utiliza para definir una proyeccin perspectiva, se define de forma similar a la
proyeccin ortogrfica pero con la diferencia que la proyeccin perspectiva define como volumen
de vista una pirmide, en consecuencia el objeto a visualizar tiene un aspecto mucho ms realista.
La sentencia que utiliza OpenGl es:
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 proyeccin perspectiva definir un tronco piramidal.
19
UNMSM
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 funcin glFrustum, la diferencia entre ambas est en la forma
de definir la ventana de visualizacin. Si en la sentencia glFrustum definimos los dos vrtices
necesarios de la ventana, en la sentencia glPerpestive solamente definiremos el ngulo de apertura
de la cmara y la relacin entre el largo y ancho del plano cercano de corte.
La sentencia en OpenGl ser pues de la forma:
Apertura corresponde al ngulo de apertura de la cmara virtual, este ngulo puede tomar valores
comprendidos entre 0 y 180. El valor de aspect, vendr dado por la relacin 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
UNMSM
Ciclo 2015 I
plejos
Plano de corte lejano
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 cdigo, primero traslado,
luego roto y luego si pinto mi objeto (es tambin en sentido inverso al que se lee el cdigo),
OpenGL trabaja con dos matrices diferentes:
UNMSM
Ciclo 2015 I
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
UNMSM
Ciclo 2015 I
23
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 utilizacin de la libreria glut, al llamar la funcion: glutInitDisplayMode
(buffers), buffers es una combinacin 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 acumulacin.
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.
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
UNMSM
Ciclo 2015 I
Compilacin 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 librera 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 tambin se pueden utilizar distintos lenguajes de programacin, como por ejemplo: C++
Builder o Delphi.
26
UNMSM
Ciclo 2015 I
info make
Para mas informacion sobre opciones gcc/g++ dar el comando: man gcc ,o: man g++
27