Mini Manual de OpenGL                          Por Daniel Barrero (dbarrero@cable.net.co) - 11/6/2002IntroducciónOpenGL es...
Primitivas de dibujo :En OpenGL solo se pueden dibujar primitivas muy simples, tales como puntos lineas, cuadrados, triang...
Entonces en los manuales se escribe como: glVertex[234][sifd][v] quiere decir que se le pueden pasar 2,3 o4 parametros mas...
Para trabajar con la matriz directamente se tiene: glLoadIdentity(): inicializa la matriz actual con una matriz identidad....
glutKeyboardFunc(keyboard);    // instale la funcion de teclado        glutIdleFunc(idle);              // funcion de anim...
en milisegundos del timer, funciontimer es la funcion a llamar la cual no devuelve nada pero recibe unparametro entero (va...
all: $(OBJECTS) $(PROGS)       nombreprograma: modulo1.c modulo2.cpp           $(CC) -o $@ $(CFLAGS) $(INCDIR) $(OBJECTS) ...
Upcoming SlideShare
Loading in...5
×

Mini introopengl

335

Published on

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
335
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Mini introopengl"

  1. 1. Mini Manual de OpenGL Por Daniel Barrero (dbarrero@cable.net.co) - 11/6/2002IntroducciónOpenGL es una interface de software para el hardware grafico, esta interface consiste de una larga serie decomandos para manipulacion de objetos y operaciones sobre estos los cuales permiten controlar laimplentacion realizada en la forma de una maquina de estados finitos, donde cada una de las variables quedeterminan el estado se aplican a partir de ese punto hasta que se indique explicitmanete el cambio, asi lasvariables de estado de OpenGL que vamos a utilizar mas comunmente son: • Color (de dibujo y de borrado). • Matrices de Transformacion (GL_MODELVIEW, GL_PROYECTION). • Patrones (de lineas y de relleno). • Modo de dibujo de poligonos. • Buffers de dibujo. • Buffer de Stencil. • Buffer de profundidad (z-Buffer). • Buffer de acumulacion.Funcionamiento de OpenGL:Para poder trabajar con OpenGL, primero se debe crear un contexto de trabajo, este contexto contiene elestado actual de maquina finita, asi como las referencias a los diferentes buffers de trabajo, estos buffers sepueden ver como zonas de memoria correspondiendo a la pantalla en las cuales OpenGL va a dibujar, engeneral a parte del buffer de color (GL_COLOR_BUFFER) que es el buffer en el cual se van a dibujar lasprimitivas, existen otro tipo de buffers mas especializados. La configuracion en memoria de estos buffers (cuantos bits representan un pixel, etc) depende de lamanera como fue creado el contexto OpenGL y de las limitaciones del hardware, por esto no se puedeacceder directamente sino solo a traves 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 esta en la lista se utiliza la instruccion glFlush(): esta instruccion obliga a pintar y no espera a que el hardawre termine para continuar con el programa, analogamente 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 buffercorresponde a lo que se ve en pantalla y otro a el buffer donde se esta pintando, de esta manera una vez quese ha pintado todo lo deseado y se quiere que esto aparezca en pantalla se intercambian los buffers, estainstruccion 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 glFinishobligan a pintar en el buffer de dibujo pero esto NO sera visible hasta intercambiar buffers.
  2. 2. Primitivas de dibujo :En OpenGL solo se pueden dibujar primitivas muy simples, tales como puntos lineas, cuadrados, triangulosy polygonos, a partir de estas primitivas es posible construir primitivas mas complejas como arcos ycirculos 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 puntoGL_LINES: Cada par de vertices sucesivos esuna lineaGL_LINE_STRIP: lineas conectadas.GL_LINE_LOOP: lineas conectadas donde elultimo y el primer vertice indican una lineacerrando el poligono.GL_POLYGON: poligono (relleno o no) dondelos vertices sucesivos componiendolo se dan elsentido contrario de las manecillas del reloj.GL_QUADS: cuadrilateros separados, cada 4vertices hacen un quad.GL_QUAD_STRIP: tira de cuadrados unidos,cada par de vertices sucesivos forman uncuadrado con el par anterior.GL_TRIANGLES: Triangulos separados, cada3 vertices hacen un triangulo.GL_TRIANGLE_STRIP: tira de triangulosunidos (similara quad_strip).GL_TRIANGLE_FAN: Grupo de trianguloscon un unico vertice comun a todos. Dentro del par glBegin, glEnd solo pueden ir instrucciones OpenGL para definir objetos tales comovertices, y colores (existen otras mas complejas como normales y materiales) y no transformaciones nicambios de estado (diferentes a los especificados), adicionalmente dentro del par pueden ir instrucciones deprogramacion del lenguaje tales que ciclos, condicionales, llamados a funciones, etc. Siempre y cuando nousen alguna de las funciones OpenGL no permitidas, i.e.: glBegin(GL_POLYGON)’; glColor3f(1.0, 0.0, 0.0); // rojo for(int i=0; i<10; i++){ glVertex3f(1.0/i, i*i, 0.0); } glColor3f(0.0, 1.0, 0.0); // verde glVertex3f(1.0, 0.0, 0.0); glColor3f(0.0, 0.0, 1.0); // azul glVertex3f(1.0, 1.0, 0.0); glEnd();muchas primitivas basicas tiene sufijos indicando el tipo del valor o variable que se le pasan comoparametro, asi como el numero de parametros, asi una instruccion como p.ej. glVertex puede tener 2,3 o 4parametros, asi comor recibir tipos enteros, flotantes, etc. O un vector conteniendo esos parametros
  3. 3. Entonces en los manuales se escribe como: glVertex[234][sifd][v] quiere decir que se le pueden pasar 2,3 o4 parametros mas el tipo o un vector, como minimo debe tener el numero de parametros 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 tambien se pueden usar para definir variables, estos son: b entero 8 bits GLbyte s entero 16 bits GLshort i entero 32 bits Glint f float 32 bits GLfloat d flotante 64 bits GLdouble ub entero sin signo 8 bits GLubyte us entero sin signo 16 bits GLushort ui entero sin signo 32 bits GLuintLas primitivas mas basicas de dibujo son entonces: glRect[sid][v]: dibuja un rectangulo, 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]: vertice de un punto,linea o poligono, SOLO puede estar entre glBegin/glEndVariables 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 linea > 0.0, 1.0 por defecto. glLineStipple(factor,patron): factor = entero indicando un factor de escalamiento, patron= short sin signoconteniendo el patron de bits par pintar la linea (punteado,etc..).. glPolygonMode(cara,modo): cara corresponde al lado del poligono, 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 modopuede ser: relleno (GL_FILL), solo los vertices (GL_POINT), o solo el borde (GL_LINE).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 fondodefinido.Transformaciones: Las tranformaciones se realizan multiplicando por las matrices y se aplican en sentido inverso al que seescriben, esto es si quiero rotar y luego trasladar un objeto en el codigo, primero traslado, luego roto y luegosi pinto mi objeto (es tambien en sentido inverso al que se lee el codigo), OpenGL trabaja con dos matricesdiferentes: • GL_MODELVIEW: es la matriz donde se trabajan con las transformaciones. • GL_PROJECTION: es donde se define la relacion mundo viewport.Para cambiar de matriz a utilizar se usa la instruccion: 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 projeccion tiene un limite maximo de 2 en la mayoria de las implementaciones.
  4. 4. Para trabajar con la matriz directamente se tiene: 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.Estructura de un programa OpenGLPara la creacion de programas OpenGL se va a utilizar la libreria GLUT, esta libreria permite olvidarse delos problemas especificos de cada plataforma, La estructura general de un programa utilizando la libreriaGLUT es la siguiente (en C o C++ es las funciones de opengl son las mismas): #include <GL/gl.h> #include <GL/glut.h> void init(void) { glClearColor(0,0,0,0); // iniciar estado global (color de borrado } void reshape ( int w, int h) { glViewport(0,0,w,h); // coloque el viewport al tamano de la ventana glMatrixMode(GL_PROJECTION); // modo matriz de proyeccion glLoadIdentity(); // inicialize la matriz glOrtho(0, w, 0, h, -1, 1); // tranformacion directa a pantalla glScalef(1, -1, 1); // invierta Y para que vaya para abajo glTranslatef(0, -h, 0); // corra el origen a la parte superior izq. glMatrixMode(GL_MODELVIEW); // modo matriz de transformacion glLoadIdentity(); // inicialize la matriz } void display(void) // pinte.... { glClear(GL_COLOR_BUFFER_BIT); // borre la pantalla glBegin(GL_TRIANGLES); // pinte glColor3f(0.0, 0.0, 1.0); glVertex3f(0, 1,0); glVertex3f(0, 0,0); glVertex3f(0, -1,0); glEnd(); glutSwapBuffers(); // cambie buffers... } void keyboard(unsigned char c, int x, int y) { switch(c) { // aqui adicionar los casos para las diferentes teclas. case 27: exit(0); break; } glutPostRedisplay(); //pinte si se cambiaron variables que afectan el dibujo } void idle(void) { // modifique variables glutPostRedisplay(); //pinte } void main( int argc, char **argv) { glutInit(&argc,argv); // inicie la libreria GLUT glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); // inicie el modo de video glutInitWindowSize(w,h); // inicie tamano de la ventana glutInitWindowPos(x,y); // inicie posicion de la ventana glutCreateWindow("nombre ventana "); init(); // iniciar variables y estado global glutDisplayFunc(display); // instale la funcion de display glutReshapeFunc(reshape); // instale la funcion de tamaño.
  5. 5. glutKeyboardFunc(keyboard); // instale la funcion de teclado glutIdleFunc(idle); // funcion de animacion. glutMainLoop(); // ciclo infinito }Manejo de Buffers Para utilizar los diferentes tipos de buffers de OpenGL estos se deben crear al crear el contexto opengl, enel caso de la utilizacion de la libreria glut, al llamar la funcion: glutInitDisplayMode (buffers), buffers esuna combinacion de valores indicando que buffers se deben crear i.e. para crear un contexto con doblebuffer rgba y z-buffer buffers seria = GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH, los valorespara crear otro tipos de buffers son: GLUT_STENCIL = buffer de stencil. GLUT_ACCUM = buffer de acumulacion. Todos los buffers deben ser activados o desactivados dependiendo de la utilizacion con el comandoglEnable(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 deprofundidad (activado por defecto).Los buffers de stencil, acumulacion y profundidad funcionan aplicando una serie de operaciones yfunciones sobre los valores que se van a escribir en el buffer, asi para manejar la funcion del buffer deprofundidad se utiliza la funcion glDepthFunc(funcion), donde funcion indica cuando pasa el test deprofundidad (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 funcionson las mismas que para la profundidad, y mascara indica que bits del stencil se utilizan. Adicionalmente ala funcion de stencil, se utiliza la operacion de stencil glStencilOp(fallo,zfallo,zpaso) que especifica comose modifica el buffer de stencil dependiendo de si la funcion del buffer stencil y z fallaron o pasaron, puedenser GL_KEEP,GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT.Manejo de Animacion y TimersOpengl no maneja animacion ni timers directamente ya que esto depende del sistema operativo, OpenGLsolo se preocupa de colocar poligonos en la pantalla, y solo seria cuestion de ordenarle de manera ciclica elrepintar la pantalla con paramentros nuevos, el problema se encuentra cuando se desea que la animacion seno bloqueante, la libreria GLUT nos facilita el manejo de la animacion de dos maners independientementedel Sistema operativo de manera no bloqueante:1. Funcion de animacion Idle, GLUT nos permite manejar la animacion definiendo una funcion deanimacion con la funcion glutIdleFunc(funcname), donde funcname es el nombre de la funcion que se va allamar para realizar la animacion, esta funcion no recibe ni retorna parametro alguno, esta funcion se debeencargar de calcular los parametros de la animacion y luego llamar la funcion de dibujo, esta no se debellamar directamente sino con la funcion glutPostRedisplay() que quiere decir que solo se llama una vez seacabe de calcular la funcion idle, esta funcion idle no se ejecuta de manera regular, solo se ejecuta una vezse hallan procesado todos los eventos que recibe la aplicacion tales como teclado, repintar, etc. Por lo tantola velocidad de la animacion resultante puede no ser constante.2. Funciones de Timers, para evitar el problema de la velocidad de animacion irregular y para tener mascontrol sobre el tiempo de ejecucion de la funcion de animacion, glut nos permite definir timers de a loscuales le asignamos una funcion que se debe ejecutar cada cierto tiempo definido por el timer, para definirestos timers se utiliza la funcion: glutTimerFunc(tiempo,funciontimer,valor), donde tiempo es el tiempo
  6. 6. en milisegundos del timer, funciontimer es la funcion a llamar la cual no devuelve nada pero recibe unparametro entero (valor), valor es el parametro que se le va a pasar a la funcion. Esta funcion se ejecutadentro del tiempo determinado y termina, si se desea que se vuelva a llamar, al final de la funcion se debeinstalar de nuevo el timer. El valor sirve para seleccionar diferentes acciones la proxima vez que se llame eltimer, como estas funciones no reciben parametros, cualquier resultado debe ser devuelto por una variableglobal.Compilacion de aplicaciones OpenGL en WindowsPara compilar un programa OpenGL suponiendo que se esta en un sistema operativo MS-Windows, con elcompilador VisualC++, se debe recuperar la libreria glut para windows (glut.h glut32.lib y glut32.dll), losarchivs .h y . lib se deben colocar en el directorio respectivo para includes y librerias del VisualC, el archivoglut32.dll se debe colocar en el directorio system32 de windows idealmente o en su defecto en el directoriodonde 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 GLUTNO! se debe crear proyecto de tipo MFC) En las opciones de compilacion del proyecto, en el tabulador deencadenamiento, se debe adicionar las siguientes librerias en este orden especifico: glut32.lib glu32.libopengl32.lib.Compilacion de aplicaciones OpenGL en LinuxPara compilar un programa OpenGL suponiendo que se esta en sistema operativo UNIX o Linux con laslibrerias instaladas en lugares estandar se debe dar el siguiente comando suponiendo que todo el programaesta en un solo archivo:Programa esta en C: gcc -o nombre_ejecutable nombre_programa.c –lglut –lGLU –lGL lmPrograma esta en C++: g++ -o nombre_ejecutable nombre_programa.c –lglut –lGLU –lGL lmSi 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: CC = gcc CXX = g++ INCDIR = -I./ -I/usr/local/include # XLIBS = -lX11 -lXt -lXext -lXm -lXmu -lXi GL_LIBS= -lglut -lGLU -lGL -lm LIBDIR = -L/usr/X11/lib -L/usr/X11R6/lib -L/usr/local/lib CFLAGS = -O DOCDIR = doc OBJECTS= modulo1.o modulo2.o PROGS = nombreprograma .SUFFIXES: .c .cc .cpp .c: $(CC) -o $@ $(CFLAGS) $(INCDIR) $< $(LIBDIR) $(GL_LIBS) $(XLIBS) .cc: $(CXX) -o $@ $(CFLAGS) $(INCDIR) $< $(LIBDIR) $(GL_LIBS) $(XLIBS) .cpp: $(CXX) -o $@ $(CFLAGS) $(INCDIR) $< $(LIBDIR) $(GL_LIBS) $(XLIBS)
  7. 7. all: $(OBJECTS) $(PROGS) nombreprograma: modulo1.c modulo2.cpp $(CC) -o $@ $(CFLAGS) $(INCDIR) $(OBJECTS) $(LIBDIR) $(GL_LIBS) $(XLIBS) Ojo: Las identaciones en el archivo son tabulador no espacios en blanco!. Solo se debe cambiar nombreprograma 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 compilarsolo 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 congcc/g++ solo basta dar el comando: ./nombredeprogramaPara mas informacion sobre el comando make dar el comando: man make ,o en caso que este falle: info makePara mas informacion sobre opciones gcc/g++ dar el comando: man gcc ,o: man g++Informacion AdicionalPara mas informacion sobre instalar OpenGL y glut en caso que estos no esten instalados ir a: http://www.opengl.org y http://www.mesa3d.orgTutoriales basicos y avanzados de opengl se pueden encontrar en los siguientes sitios: • http://nehe.gamedev.net/ • http://romka.demonews.com/index_eng.htm

×