III Opengl

55

Transcript of III Opengl

Page 1: III Opengl
Page 2: III Opengl

Introducción

Este tutorial pretende introducir al alumno en el mundo de Op enGL. Paraello da una primera visión superficial de su uso, dejando al a lumno laopción de profundizar más en su aprendizaje, ya que OpenGL es unconjunto de librerías muy potente en el desarrollo de gráfic os porcomputador.

Este tutorial también pretende conseguir que el alumno no se aburra conla teoría matemática de los gráficos por computador, mostrá ndole unaforma sencilla de poner en práctica sus conocimientos desde el primerforma sencilla de poner en práctica sus conocimientos desde el primermomento. Para ello se introducirá al alumno paso a paso en el c omplejomundo de OpenGL, desde la simplicidad del programa que solo m uestrauna línea por pantalla, hasta la aplicación que permite inte ractuar con elusuario. Esto se logra gracias a la sucesión de aplicaciones ejemplo, enlas que la dificultad ira en incremento, mostrándose cada ve z algunas delas operaciones de OpenGL.

Se utilizarán las librerías de OpenGL, así como sus extension es, que sonlas GLaux, GLU y GLUT .

Page 3: III Opengl

¿ Qué es OpenGL ?

OpenGL se define estrictamente como "una interfaz software paragráficos por hardware" [Wrigth & Sweet, 1997]

Pero, ¿qué es OpenGL realmente? OpenGL no es un lenguaje deprogramación; Se puede decir que OpenGL es un API (Applicati onProgramming Interface) para desarrollo de aplicaciones 3D . En realidades más que un simple Interfaz. Son unas definiciones estándar para ladefinición, gestión y manipulación de gráficos 3D.

Cuando se dice que una aplicación esta basada en OpenGL, o que es unaaplicación OpenGL, quiere decir que está escrita en un lengu aje deprogramación que hace llamadas a una o más de las librerías de OpenGL.

¿Para que puedo usar OpenGL? : OpenGL puede ser usado para tod otipo de aplicaciones que necesiten visualización 3D en tiemp o real de altorendimiento y calidad, en esto están incluido los videojueg os, CAD,aplicaciones científicas, médicas, militares, simulador es, etc.

Page 4: III Opengl

¿ Qué es OpenGL ?

OpenGL fue definido por SGI (Silicon Graphics Inc.) dirigid o a susmáquinas de desarrollo 3D a partir de un lenguaje llamado GL q ue yaposeían.

Pero esta vez lo definieron para que fuera lo más abierto posi ble yportable a cualquier plataforma (de ahí lo de Open).

Lo presentaron al público en la misma presentación en la que M icrosoftpresentó Windows NT 3.5 allá por el año 1992. En un primer momentopresentó Windows NT 3.5 allá por el año 1992. En un primer momentosolamente las máquinas de SGI eran capaces de soportar estasespecificaciones, ya que necesita de un hardware potente y r ápido, sobretodo en lo referente al hardware de presentación. No obstant e Microsoft ySGI se pusieron a trabajar para efectuar un desarrollo para W indows NTque posteriormente fue trasladado a Windows 95. Y gracias, s obre todo, alas tarjetas gráficas aceleradores 3D se consiguen unos res ultadosexcelentes.

Actualmente OpenGL está soportado de forma automática en to das lasversiones Win32 con excepción de Windows CE.

Page 5: III Opengl

Las librerías de OpenGL

Las funciones que definen actualmente OpenGL están conteni das en lalibrería opengl32.lib, y su cabecera gl.h. Las funciones de esta libreríatienen el prefijo gl.

Además OpenGL tiene tres extensiones como ya se ha explicado . Estasson:

GLauxGLaux -- Las funciones de esta librería no forman realmente parte de l aespecificación OpenGL, se trata más bien de una librería de recursos .especificación OpenGL, se trata más bien de una librería de recursos .Estas funciones están contenidas en la librería glaux.lib, y su fichero decabecera glaux.h. Las funciones de esta librería tienen pre fijo aux. endesuso ahora se utiliza Glut.

Page 6: III Opengl

Las librerías de OpenGL

GLUGLU - GLU es el acrónimo de OpenGL Utility (se podría traducir comoBiblioteca de utilidades para OpenGL). Esta biblioteca est á compuestapor una serie de funciones de dibujo de alto nivel que, a su vez, se basanen las rutinas primitivas de OpenGL y se suele distribuir nor malmentejunto a él. Las funciones de GLU se reconocen con facilidad ya que todascomienzan con el prefijo glu. Por ejemplo gluOrtho2D(), que d efine unamatriz en proyección ortográfica de dos dimensiones. Las fu ncionesestán contenidas en la librería glu32.lib y su fichero de cab ecera glu.h.Las funciones de esta librería tienen prefijo glu.GLUTGLUT - (del inglés OpenGL Utility Toolkit) es una biblioteca de uti lidadespara programas OpenGL que principalmente proporciona dive rsasfunciones de entrada/salida con el sistema operativo. Entr e las funcionesque ofrece se incluyen declaración y manejo de ventanas y la i nteracciónpor medio de teclado y ratón. También posee rutinas para el di bujado dediversas primitivas geométricas (tanto sólidas como en mod o wireframe)que incluyen cubos, esferas y teteras. También tiene soport e paracreación de menús emergentes. Todas las funciones de GLUT co mienzancon el prefijo glut (por ejemplo, glutPostRedisplay indica que la ventanaactual necesita ser redibujada). Las funciones están conte nidas en lalibrería glut32.lib y su fichero de cabecera glut.h.

Page 7: III Opengl

Las librerías de OpenGL

GLUIGLUI - (del inglés OpenGL User Interface) es una biblioteca de inte rfaz deusuario escrito en C++. Está basada en GLUT, y proporciona el ementosde control tales como botones, cajas de selección y spinners paraaplicaciones que usen OpenGL. Es independiente del sistema operativo,sustentándose en GLUT para manejar los elementos dependien tes delsistema, como las ventanas y el control del ratón.

Fue escrito, originalmente por Paul Rademacher para ayudar se con sutrabajo académico . Actualmente Nigel Stewart mantiene el proyecto .trabajo académico . Actualmente Nigel Stewart mantiene el proyecto .

Page 8: III Opengl

Tipos de datos en OpenGL

OpenGL define sus propios tipos de datos, que corresponden c on lostipos normales de C.

Tipos de datos OpenGL Definición en C

Glbyte char con signoGlshort shortGlint, Glsizei longGlint, Glsizei longGlfloat , Glclampf float

Gldouble , Glclampd double

GLubyte , Glboolean unsigned charGlushort unsigned short

GLuint , Glenum, Glbitfield unsigned long

Page 9: III Opengl

Tipos de datos en OpenGLTipo GL Prefijo Tamaño Descripción

GLboolean - 1 Valor de verdad

GLbyte b 8 Byte con signo, complemento a 2

GLubyte ub 8 Byte sin signo

GLchar - 8 Caracter

GLshort s 16 Entero corto

GLushort us 16 Entero corto sin signo

GLint i 32 Entero con signo, complemento a 2

GLuint ui 32 Entero sin signoGLuint ui 32 Entero sin signo

GLsizei - 32 Entero largo no-negativo

GLintptr - ptrbitsEntero complemento de 2 , es el numero de bits necesarios

para representar un puntero a GLint

GLsizeiptr - ptrbitsEntero no-negativo, es el numero de bits necesarios para

representar un puntero a GLsizei

GLbitfield - 32 Campo de bits

GLfloat f 32 Numero de punto flotante

GLdouble d 64 Punto flotante de precisión doble.

GLclampd - 64 Doble convertido al intervalo [0,1]

Page 10: III Opengl

Denominación de las Funciones

Las letras de la columna “Prefijo” se usan en las convenciones defunciones, para identificar el tipo de dato que la función re cibe.

Los bits en la columna de “Tamaño” indican la mínima cantidad que debetener el tipo de dato, ya que dependiendo de la implementació n delfabricante de hardware este número puede ser mayor.

Las entrada de las funciones de OpenGL pueden ser cualquier t ipo dedato que cumpla las especificaciones de arriba, es decir, el API nodato que cumpla las especificaciones de arriba, es decir, el API nosolamente funciona con los tipos de datos propios, sino que t ambiénpuede funcionar con los tipos de datos de C, C++, algún binding de java,etc. Así es que por ejemplo se puede usar el float de C++ como en tradade una función con parámetro GLfloat de OpenGL sin problemas . Aún asíes recomendable utilizar los tipos de datos de OpenGL para man teneruna buena portabilidad de la aplicación.

Page 11: III Opengl

Denominación de las Funciones

Todas las funciones de OpenGL siguen unas simples convencio nes quepermiten identificar su funcionamiento de manera rápida pa ra elprogramador, dichas convenciones fueron establecidas ini cialmente porSGI y hasta hace poco lo eran por el ARB. Actualmente y con el tr aspasodel ARB al grupo Kronos, se espera que dichas normas sean dict adasdesde allí.

Una “disección” de una función en OpenGL luciría algo así como :

Page 12: III Opengl

Denominación de las Funciones

� Nombre: El nombre de la función.� # Parámetros: Cantidad de parámetros que recibe la función, puedenser ninguno (se obvia), 1, 2, 3 o 4.� Tipo parámetros: Indica el tipo de todos los parámetros que recibe lafunción. Pueden ser cualquiera de los tipos con prefijo indi cados en latabla de Tipos de Datos de OpenGL. Si se le agrega la letra ‘v’ d espuésdel prefijo de tipo de parámetro, indica que la función recib e un arreglode tamaño # Parámetros y tipo Tipo parámetros.� Parámetros : Los parámetros de la función .� Parámetros : Los parámetros de la función .� Retorno: El retorno puede ser cualquiera de los tipos especificadosanteriormente.� Liberaría: Indica la fuente de la función, las más comunes son gl paraOpenGL, glu para el OpenGL Utility Library y wgl para la librería debindings OpenGL – win32. Para el caso de las extensiones, apa recen dela forma GL_EXT, GL_ARB, GL_NV (nvidia), GL_ATI y en generalcualquier nombre de compañía que produzca extensiones de har dwarepara OpenGL.

Page 13: III Opengl

Denominación de las FuncionesUno de los ejemplos más amplios para mostrar el funcionamien to deestas convenciones es de de glVertex , todas las definiciones de estasfunción son:

void glVertex2d( GLdouble x, GLdouble y );void glVertex2f( GLfloat x, GLfloat y );void glVertex2i( GLint x, GLint y );void glVertex2s( GLshort x, GLshort y );void glVertex 3d( GLdouble x, GLdouble y, GLdouble z );void glVertex 3d( GLdouble x, GLdouble y, GLdouble z );void glVertex3f( GLfloat x, GLfloat y, GLfloat z );void glVertex3i( GLint x, GLint y, GLint z );void gl Vertex3s( GLshort x, GLshort y, GLshort z );void glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdoubl e w );void glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w );void glVertex4i( GLint x, GLint y, GLint z, GLint w );void glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w );void glVertex2dv( const GLdouble *v );void glVertex2fv( const GLfloat *v );

Page 14: III Opengl

Denominación de las Funcionesvoid glVertex2iv( const GLint *v );void glVertex2sv( const GLshort *v );void glVertex3dv( const GLdouble *v );void glVertex3fv( const GLfloat *v );void glVertex3iv( const GLint *v );void glVertex3sv( const GLshort *v );void glVertex4dv( const GLdouble *v );void glVertex4fv( const GLfloat *v );void glVertex4iv( const GLint *v );void glVertex4sv( const GLshort *v );

Como se evidencia, es posible “adivinar” el tipo de entrada qu e tendrá lafunción, solamente con observar su nombre.

No todas las funciones poseen número de argumentos variable , así queen esos casos se omite el número delante del nombre de la funci ón,como por ejemplo en glTranslate (). Esto también puede ocurrir con el tipode datos y si la función recibe como parámetros arreglos.

Page 15: III Opengl

Constantes

OpenGL y sus librerías auxiliares nombran sus constantes si empre enmayúsculas, poniéndoles un prefijo, el mismo que en las func iones, queindica en que librería esta definida.

Ejemplos de constantes:

GLUT_RGB GLUT_KEY_INSERT GLUT_STENCILGL_POINTS GL_LINES GL_LINE_LOOPGL_LINE_STRIP GL_TRIANGLES GL_TRIANGLE_STRIPGL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIPGL_POLYGON

Page 16: III Opengl

Primitivas Geométricas Básicas

Una primitiva es simplemente la interpretación de un conjun to de vérticesdibujados de una manera específica en pantalla. Hay diez pri mitivas distintas enOpenGL; para ello hace uso del lo que sus creadores llaman el “ paradigmaBegin/End”, que simplemente es la forma en que se pasan las in strucciones paraindicar al API como se deben armar las primitivas, a través de dos funciones:

void glBegin( tipo_de_primitiva);void glEnd ( void );

La función glBegin () indica a OpenGL que los siguientes llamados a la funciónLa función glBegin () indica a OpenGL que los siguientes llamados a la funciónglVertex (), entre esta y glEnd () deberán ser interpretados como vértices paraensamblar la primitiva especificada en ( tipo_de_primitiva), el parámetro de lafunción glBegin (). Adicionalmente a especificar vértices es posible espec ificarcolores, normales, materiales y texturas entre los llamado s de glBegin () y glEnd ().Los vértices sumistrados entre los llamados del glBegin() – glEnd() pueden sercualquiera de la forma:

Page 17: III Opengl

Primitivas Geométricas Básicas

Es posible especificar diez tipos de primitivas diferentes al llamar la funciónglBegin , estas son:

1. GL_POINTS: Cada vértice es un punto 2. GL_LINES: Cada par de vértices sucesivos es una línea3. GL_LINE_STRIP: líneas conectadas.4. GL_LINE_LOOP: líneas conectadas donde el último y el primer vérti ce indican

una línea cerrando el polígono.5. GL_TRIANGLES : Triángulos separados, cada 3 vértices hacen un tria ngulo.5. GL_TRIANGLES : Triángulos separados, cada 3 vértices hacen un tria ngulo.6. GL_TRIANGLE_STRIP: tira de triángulos unidos (similar a quad_strip).7. GL_TRIANGLE_FAN: Grupo de triángulos con un único vértice común a to dos.8. GL_QUADS: cuadriláteros separados, cada 4 vértices hacen un q uad.9. GL_QUAD_STRIP: tira de cuadrados unidos, cada par de vértices suce sivos

forman un cuadrado con el par anterior.10. GL_POLYGON: polígono (relleno o no) donde los vértices sucesivo s

componiéndolo se dan el sentido contrario de las ma necillas del reloj.

Page 18: III Opengl

Primitivas Geométricas Básicas

Page 19: III Opengl

Primitivas de Objetos PredefinidosHay algunos objetos que vamos a renderizar muy a menu do, y que por tanto, ya vienen definidos. Así, disponemos de las siguientes funciones:

glutWireSphere (radius, slices, stacks);glutSolidSphere( radius, slices, stacks);glutWireCone( base, height, slices, stacks);glutSolidCone (base, height, slices, stacks);glutWireCube (size);glutSolidCube (size);glutSolidCube (size);glutWireTorus( innerRadius, outerRadius, sides, rings);glutSolidTorus (innerRadius, outerRadius, sides, rings);glutWireDodecahedron (void);glutSolidDodecahedron (void);

Page 20: III Opengl

Primitivas de Objetos PredefinidosglutWireTeapot( size);glutSolidTeapot( size);glutWireOctahedron (void);glutSolidOctahedron (void);glutWireTetrahedron( void);glutSolidTetrahedron (void);glutWireIcosahedron (void);glutSolidIcosahedron (void);

glutWire: Malla. glutSolid: Solido.

Page 21: III Opengl

Primitivas de Objetos Predefinidos

Page 22: III Opengl

Tipografía

La implementación de texto en Glut se realiza mediante las sig uientesfunciones.

glutBitmapCharacter(void *font, int character);glutBitmapWidth(void *font, int character);glutStrokeCharacter(void *font, int character);glutStrokeWidth(void *font, int character);glutBitmapLength (void *font , const unsigned char *string );glutBitmapLength (void *font , const unsigned char *string );glutStrokeLength(void *font, const unsigned char *string );

Las dos últimas solo disponibles para versiones superiores a la 4.0

Page 23: III Opengl

Tipografía

Los siguientes estilos de letras están definidos por la func iónglutBitmapCharacter , en la implementación de ésta función se define elestilo de fuente utilizada.

Page 24: III Opengl

Mis primeros pasos con Glut

Las primeras funciones para inicializar Glut son:

void glutInit (int argc, char **arrgv) : Inicializa Glut.

void glutWindowsPosition (int x, int y) : Setea la ventana de trabajo, dondex e y son las coordenadas de nuestra ventana.

void glutWindowsSize (int width , int height ) : Definimos el tamaño de lavoid glutWindowsSize (int width , int height ) : Definimos el tamaño de laventana; donde width y height son largo y ancho de la ventana.

int glutCreateWindows (char *title) : Permite crear una ventana; donde titlees el titulo de esta. glutCreateWindows retorna el identifi cador de laventana, que se ocupa cuando se definen múltiples ventanas.

Page 25: III Opengl

Mis primeros pasos con Glut

void glutDisplayMode (unsigned int mode) : Define el "modo“ de laventana, donde mode puede tomar los siguientes valores:

�GLUT_RGBA o GLUT_RGB selecciona una ventana con rgb ( rojo,verde, azul) o rgba ( rojo, verde, azul y el canal alfa). El canal alfa seocupa para transparencias.�GLUT_SINGLE un buffer.

GLUT_DOUBLE doble buffer, para animaciones principalmente .�GLUT_DOUBLE doble buffer, para animaciones principalmente .También se pueden especificar que buffer se quiere :

� GLUT_ACCUM buffer de acumulación.� GLUT_STENCIL se ocupa para reflejos y sobras.� GLUT_DEPTH buffer de fondo.

Si se quiere una ventana tipo RGB, con buffer simpl e y depth buffer seria:glutDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);

Page 26: III Opengl

Mi primer programa con Glut

#include <GL/glut.h>

int main( int argc, char ** argv){

glutInit(&argc, argv);glutInitWindowSize(320, 320);glutInitWindowPosition(100, 100);glutInitDisplayMode (GLUT_RGB);glutInitDisplayMode (GLUT_RGB);glutCreateWindow("Prog00");

}

Si compilan y ejecutan este código, se abrirá una ventana en n egro, estodebido a que no hemos dibujado nada aún.

Page 27: III Opengl

Mi primer programa con Glut

Ahora vamos a dibujar algo sencillo en la pantalla:

void display(){

glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_LINES);glVertex3f(-0.5, -0.5, 0.0);

glVertex3f(0.0, 0.0, 0.0);glEnd ();glEnd ();glFlush();

}

Uno le puede poner el nombre que quiera a esta función, lo que s i debe hacer esdecirle a GLUT cual es es nombre de esta, esto se hace por medio de la fusiónglutDisplayFunc (void *(func)(void)); donde func es el nombre de la función q uehace las tareas de dibujar.

Page 28: III Opengl

Mi primer programa con Glut

Ahora le avisamos a GLUT que estamos listos para entrar en loo p de eventos de laaplicación, esto lo hacemos con la función glutMainLoop() ;. Ahora nuestro códigoluce así:

Por lo que ahora nuestra función main quedaría de la siguient e forma:

int main(int argc, char **argv){

glutInit (&argc,argv );glutInit (&argc,argv );glutInitWindowPosition(100,100);glutInitWindowSize( 320, 320);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );glutCreateWindow("Prog01");glutDisplayFunc(display);glutMainLoop();

}

Page 29: III Opengl

Cambiando el tamaño de la ventana

Al cambiar el tamaño de la ventana a veces, no se despliega lo e sperado, puestoque los cálculos de perspectiva quedan mal hechos por tener u n nuevo tamaño,para solucionar esto, Glut proporciona una función que llam a a una función paraque recalcule estos valores para casos en que se cambie el tam año de la ventana.

La función es glutReshapeFunc (void *(func)(int width, int height); donde func es lafunción a la que llamaremos y width y height son los datos que l e ingresaremos aesta.

Por lo que la dicha función se tendría que mandar a llamar de la siguiente manera :Por lo que la dicha función se tendría que mandar a llamar de la siguiente manera :

glutReshapeFunc (resize).

Page 30: III Opengl

Cambiando el tamaño de la ventana

A Continuación veremos la implementación de la función:

void resize( int w, int h ){

glClearColor( 1.0, 1.0, 1.0, 1.0 );glViewport( 0, 0, w, h );glMatrixMode( GL_PROJECTION );glLoadIdentity();glOrtho ( -50.0, 50.0, -50.0, 50.0, -50.0, 50.0 );glOrtho ( -50.0, 50.0, -50.0, 50.0, -50.0, 50.0 );glMatrixMode( GL_MODELVIEW );glLoadIdentity();

}

Page 31: III Opengl

Mi primer programa con Glut

Por lo que ahora nuestra función main quedaría de la siguient e forma:

int main(int argc, char **argv){

glutInit(&argc,argv);glutInitWindowPosition(100,100);glutInitWindowSize( 320, 320);glutInitDisplayMode (GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);glutInitDisplayMode (GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);glutCreateWindow("Prog02");glutDisplayFunc(display);

glutReshapeFunc(resize);glutMainLoop();

}

Page 32: III Opengl

Mi primer programa con GlutOtras funciones necesarias para empezar, son void glColor3f ( float r, float g, float b);con lo cual definimos el color que vamos a usar; y glClearColor (GLclampf red, GLclampfgreen, GLclampf blue, GLclampf alpha ); con la cual establec emos el color de Fondo.

Void display(){

glClearColor( 1.0, 1.0, 1.0 ); //Establecemos el color de Fo ndoglClear(GL_COLOR_BUFFER_BIT); // Se borra el buffer de la p antallaglBegin(GL_TRIANGLES); // Se va a empezar una secuencia de t riángulos.GlColor3f(1.0, 0.0, 0.0);glVertex 3f(-0.5, -0.5, 0.0); // Se usa para definir puntos con 3glVertex 3f(-0.5, -0.5, 0.0); // Se usa para definir puntos con 3glColor3f(0.0, 1.0, 0.0); // coordenadas que sean float, gl vertex3d para 3glVertex3f(0.0, 0.0, 0.0); // coordenadas que sean double.glColor3f(0.0, 0.0, 1.0);glVertex3f(0.0, 0.5, 0.0);glEnd(); // Se termina de definir los triángulos.glFlush(); // Se termina flujo de datos.

}Con ese nuevo código se obtendrá un triángulo con cada vértic e de diferente color y unfondo blanco. Si se dibuja en 2D, se puede ocupar glVertex2f ( float x, float y); oglVertex2d (double x, double y);

Page 33: III Opengl

Código para dibujar un triángulo(Ejercicio 01)

#include <GL/glut.h>void dibujar(){glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLES);glColor3f(1.0, 0.0, 0.0);glVertex3f(-0.5, -0.5, 0.0glColor3f(0.0, 1.0, 0.0);glVertex3f(0.5, 0.0, 0.0);

gluPerspective(45,(float)largo/(float)ancho,1,1000);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt( 0.0, 0.0, 2.0,0.0, 0.0, -1.0,0.0, 1.0,0.0);}

int main(int argc, char **argv){glColor3f(0.0, 0.0, 1.0);

glVertex3f(-0.5, 0.5, 0.0);glEnd();glFlush();}void cambiarTamano(int largo, int ancho){if(ancho==0) ancho=1;glMatrixMode(GL_PROJECTIONglLoadIdentity();glViewport(0,0,largo, ancho);

{glutInit(&argc,argv);glutInitWindowPosition(100,100);glutInitWindowSize( 320, 320);glutInitDisplayMode(GLUT_RGB);glutCreateWindow(“Ejercicio 01");glutDisplayFunc(display);glutReshapeFunc(resize);glutMainLoop();

}

Page 34: III Opengl

Programa que dibuja una línea

#include <GL/glut.h>#define WIDTH 200#define HEIGHT 200

void display(void){

glClear(GL_COLOR_BUFFER_BIT );glColor3f( 0.0, 0.0, 0.0 );glBegin( GL_LINES );

glMatrixMode( GL_PROJECTION );glLoadIdentity();glOrtho( -50.0, 50.0, -50.0, 50.0, -50.0, 50.0 );glMatrixMode( GL_MODELVIEW );glLoadIdentity();

}

int main(int argc, char** argv){

glVertex3f( -30.0f, -30.0f, 0.0f );glVertex3f( 30.0f, 30.0f, 0.0f );glEnd();glFlush();

}void resize( int w, int h ){

glClearColor( 1.0, 1.0, 1.0, 1.0 );glViewport( 0, 0, w, h );

glutInitDisplayMode ( GLUT_RGB );glutInitWindowSize ( WIDTH, HEIGHT );glutInitWindowPosition ( 100, 100 );glutCreateWindow("Ejercicio 02");glutDisplayFunc( display );glutReshapeFunc( resize );glutMainLoop();return 0;

}

Page 35: III Opengl

Interactuando con el Teclado

Funciones añadidas en esta aplicación:

�void glLineWidth (10.0) - Selecciona el ancho de las líneas dibujadas conGL_LINES.

�void glutKeyboardFunc (Teclado) - Cuando se pulsa una tecla el sistema llamaraautomáticamente a la función definida por el programador en este caso la funciónTeclado.

�void Teclado (unsigned char key, int x, int y) - Esta función es llamada cad a vezque el usuario pulsa una tecla.

�void glutPostRedisplay () - Manda repintar la ventana, es decir, el sistema indicaque se ha de ejecutar la función definida en glutDisplayFunc() .

Page 36: III Opengl

Interactuando con el Teclado

Conocimientos previos uso de la función glColor3f() .

Actividades:1a. Aumentar el grosor a la línea del ejercicio 02.

2a. Se hará uso de las teclas 'r', 'g' y 'b', que disminuirán la propiedad 'roja' la 'r','verde' la 'g' y 'azul' la 'b‘.

3er Se hará uso de las teclas ‘R', ‘G' y ‘B', que aumentarán la propiedad 'roja' la ‘R' ,3er Se hará uso de las teclas ‘R', ‘G' y ‘B', que aumentarán la propiedad 'roja' la ‘R' ,'verde' la ‘G' y 'azul' la ‘B'.

4ª Se hará uso la tecla esc para finalizar la aplicación.

Page 37: III Opengl

Programa que cambia el color de una línea(Ejercicio 03)

#include < GL/glut.h >

#include < stdio.h >#define WIDTH 200#define HEIGHT 200

GLfloat FEA_Red = 0.0f;GLfloat FEA_Green = 0.0f;GLfloat FEA_Blue = 0.0f;

void teclado (unsigned char key, int x, int y){switch(key){

case 'r':if (FEA_Red > 0.01)

FEA_Red = FEA_Red - 0.1;break;

case 'R':if (FEA_Red < 1.0)

void display(void){glClear( GL_COLOR_BUFFER_BIT );glColor3f( FEA_Red, FEA_Green, FEA_Blue );glLineWidth(10.0f);glBegin( GL_LINES );glVertex3f( -30.0f, -30.0f, 0.0f );glVertex3f( 30.0f, 30.0f, 0.0f );glEnd();glFlush();}

if (FEA_Red < 1.0)FEA_Red = FEA_Red + 0.1;

break;case 'b':

if (FEA_Blue > 0.01)FEA_Blue = FEA_Blue - 0.1;

break;case 'B':

if (FEA_Blue < 1.0)FEA_Blue = FEA_Blue + 0.1;

break;

Page 38: III Opengl

case 'g':if (FEA_Green > 0.01)

FEA_Green = FEA_Green - 0.1;break;

case 'G':if (FEA_Green < 1.0)

FEA_Green = FEA_Green + 0.1;break;

case 27: //exit(0);

Void resize( int w, int h ){

glClearColor( 1.0, 1.0, 1.0, 1.0 );glViewport( 0, 0, w, h );glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho( -50.0, 50.0, -50.0, 50.0, -50.0, 50.0 );glMatrixMode(GL_MODELVIEW);glLoadIdentity();

}

Programa que cambia el color de una línea(Ejercicio 03)

exit(0);break;

}glutPostRedisplay();

}

}int main(int argc, char** argv)

{glutInitDisplayMode ( GLUT_RGB );glutInitWindowSize ( WIDTH, HEIGHT );glutInitWindowPosition ( 100, 100 );glutCreateWindow(“Ejercicio 03");glutDisplayFunc(display);glutKeyboardFunc(teclado);glutReshapeFunc( resize );glutMainLoop(); return 0;}

Page 39: III Opengl

Para la escucha de teclas especiales se hace uso de la siguien te función voidglutSpecialFunc (teclaespecial): la cual cada que se pulsa una tecla especia l el sistemallamara automáticamente a la función definida por el progra mador en este caso lafunción teclaespecial, la cual tiene sl siguiente prototip o void tecladoespecial (int key,int x, int y) - Esta función es llamada cada vez que el usuario p ulsa una tecla especial.

Las teclas especiales en Glut están definidas por las siguie ntes constantes:

Uso de Teclas especiales

Teclas de Función Teclas de Dirección

GLUT_KEY_F1 GLUT_KEY_LEFTGLUT_KEY_F1

GLUT_KEY_F2

GLUT_KEY_F3

GLUT_KEY_F4

GLUT_KEY_F5

GLUT_KEY_F6

GLUT_KEY_F7

GLUT_KEY_F8

GLUT_KEY_F9

GLUT_KEY_F10

GLUT_KEY_F11

GLUT_KEY_F12

GLUT_KEY_LEFT

GLUT_KEY_UP

GLUT_KEY_RIGHT

GLUT_KEY_DOWN

GLUT_KEY_PAGE_UP

GLUT_KEY_PAGE_DOWN

GLUT_KEY_HOME

GLUT_KEY_END

GLUT_KEY_INSERT

Page 40: III Opengl

Interactuando con el Mouse

Otras funciones relacionadas con la iteración son:

�glutMouseFunc(void (*func)(int button, int state, int x, i nt y)) - Llama a la funcióndefinida, cuando se pulsa (o suelta) algún botón del ratón de ntro de la ventana deOpenGL. Los parámetros que se pasan a la función son el botón p ulsado :

� GLUT_LEFT_BUTTON: botón izquierdo,� GLUT_RIGHT_BUTTON : botón derecho y� GLUT_MIDDLE_BUTTON : botón central.

La acción GLUT_DOWN (pulsar) o GLUT_UP (soltar), y las coordenadas dondeLa acción GLUT_DOWN (pulsar) o GLUT_UP (soltar), y las coordenadas dondeesta el puntero en relación a la esquina superior izquierda d e la ventana derenderizado.

�glutMotionFunc(void (*func)(int x, int y)) - Llama a la función definida cada ciertotiempo si el ratón esta activo, tiene algún botón pulsado. Lo s parámetros que lepasa a la función son las coordenadas del puntero.

�glutPassiveMotionFunc(void (*func)(int x, int y)) - Llama a la función definidacada cierto tiempo si el ratón esta pasivo, no tiene ningún bo tón pulsado. Losparámetros que le pasa a la función son las coordenadas del pu ntero.

Page 41: III Opengl

Tipos de Proyección

Definición y colocación de la cámara

Una vez hemos definido toda nuestra escena en coordenadas mu ndo, tenemosque “hacerle la foto”. Para ello, tenemos que hacer dos cosas : colocar lacámara en el mundo (o sea, en la escena) y definir el tipo de pro yección querealizará la cámara.

Posición de la cámara

Tenemos que definir no sólo la posición de la cámara (o donde e stá), sinotambién hacia dónde mira y con qué orientación (no es lo mismo mirar con latambién hacia dónde mira y con qué orientación (no es lo mismo mirar con lacara inclinada o recta… aunque veamos lo mismo).

Page 42: III Opengl

Tipos de Proyección

Para hacer esto, basta con modificar la matriz ModelView para mover toda laescena de manera que parezca que hemos movido la cámara. El pr oblema deeste sistema es que tenemos que pensar bastante las transfor maciones aaplicar. Es por ello que la librería GLU viene al rescate con l a función gluLookAt .Su sintaxis es la siguiente:

void gluLookAt( eyeX, eyeY, eyeZ, cenX, cenY, cenZ, vp_X, vp _Y, vp_Z);

donde eye corresponde a la posición de la cámara, cen corresp onde al puntohacia donde mira la cámara y vp es un vector que define la orien tación de lacámara . No podemos llamar a gluLookAt en cualquier momento, puesto quecámara . No podemos llamar a gluLookAt en cualquier momento, puesto quetiene postmultiplicar la matriz ModelView (por tanto, conviene llamarla loprimero de todo). El vector vp no puede ser paralelo al vector formado por eye ycen, es más, debería serle perpendicular. Si no, el resultad o es impredecible.

A la vez de definir la posición y orientación de la cámara, hay que definir el tipode “foto” que hace, un poco como si seleccionásemos el objeti vo. Esto es loque nos va a definir la forma del volumen de visualización.

La primera elección que tenemos que hacer es si queremos una p royecciónortogonal o perspectiva. Dependiendo del tipo de aplicació n, utilizaremos una uotra.

Page 43: III Opengl

Tipos de Proyección

Page 44: III Opengl

Tipos de Proyección

Una vez definida la posición y orientación de la cámara, hay q ue definir el tipode “foto” que hace, un poco como si seleccionásemos el objeti vo. Esto es loque nos va a definir la forma del volumen de visualización.

En OpenGL, para definir la proyección, modificaremos la mat riz Projection . Parahacer esto, pues, tendremos que hacer una llamada aglMatrixMode(GL_PROJECTION) , para indicarle que vamos a modificar estamatriz.

A partir de ese momento, todas las funciones de transformaci ón (glRotatef ,glTranslatef , glScalef , …etc) y las de pila (glPushMatrix y glPopMatrix ) seglTranslatef , glScalef , …etc) y las de pila (glPushMatrix y glPopMatrix ) seaplican sobre estas matriz.

Page 45: III Opengl

Del griego orthos (recto) y gonía(ángulo)

El término ortogonalidad (en lasmatemáticas) es una generalizaciónde la noción geométrica deperpendicularidad. En el espacioeuclídeo convencional el términoortogonal y el término perpendicularson sinónimos . Sin embargo, en

Ortogonalidad

Proyecciones ortogonales de un cuerpo en el plano

son sinónimos . Sin embargo, enespacios de dimensión finita y engeometrías no euclídeas el conceptode ortogonalidad generaliza al deperpendicularidad.

En la figura se han obtenido las proyecciones del cuerpo sobr e tres planosperpendiculares dos a dos. El alzado corresponde a la vista d e frente delcuerpo, el perfil a la vista de lado y la planta a la vista desde arriba.

Page 46: III Opengl

Proyección Ortogonal

Para el caso de la proyección ortogonal la analogía de la cáma ra no es tanevidente, porque en realidad estamos definiendo una caja, o volumen devisualización alrededor del eye de la cámara (esto es, podem os ver detrás) Parahacer esto, llamamos a

glOrtho(left, right, bottom, top, near, far)

Como se aprecia en la figura, la “foto” obtenida incluye tant o la tetera como eltoroide, puesto que el volumen de visualización tiene un nea r negativo (detrásde la cámara) y por tanto el volumen de visualización lo inclu irá.

Page 47: III Opengl

Proyección Ortogonal

Esto sería equivalente a tener la cámara situada de la siguie nte manera:

En este caso, la imagen sería la misma, pero near y far serían a mbos positivos,puesto que el volumen se está definiendo por delante de la cám ara. Si near y farfueran los valores de la figura anterior, entonces segurame nte sólo apareceríaen la imagen el toroide, puesto que el volumen de visualizaci ón estaría centradoen la cámara

Page 48: III Opengl

El concepto es parecido a la proyección ortogonal; pero los p untos de la escena seproyectan sobre el plano de proyección (la pantalla) siguie ndo una línea que pasa porun punto detrás de este plano, el punto de vista (donde estamo s situados para ver laescena).

Proyección en Perspectiva

A OpenGL se le puede decir que vamos a usar esta proyección de d os formas:

Page 49: III Opengl

glFulstrum

glFrustum(xwmin, xwmax, ywmin, ywmax, pcerca,plejos );

Page 50: III Opengl

gluPerpespective

gluPerpective(apertura, aspect, pcerca, plejos);apertura: corresponde alángulo marcado en el gráficocon un máximo de 180.

aspect: será la relación entrelargo y alto del plano de cortecercano (largo/alto).

pcerca : sera la distanciapcerca : sera la distanciamínima al punto de vista apartir de la cual se pintaran losojetos.

plejos: será la distanciamáxima al punto de vista. Apartir de esta distancia no sepintaran los objetos.

Page 51: III Opengl

Veremos en muchas ocasiones que un punto en tres dimensiones se representa porcuatro coordenadas.

Por lo que el punto (3,2,5) se representará como (3,2,5,1). S encillamente le añadimos un1 como cuarta coordenada. Para que cuando OpenGL lo multipli que por una matriz de4x4 para rotarlo, moverlo, escalarlo y calcular en que posic ión de la pantalla hay quedibujarlo, no tengamos problemas.

En realidad OpenGL añade este cuarto 1 internamente si usamo s tres coordenadas con

Coordenadas Homogéneas

una función como glVertex3f().

OpenGL y todos los motores gráficos usan matrices para modif icar las coordenadas delos puntos de los objetos que van a dibujar porque es el método más fácil deimplementar y más rápido para un ordenador y permite muchas c osas.

Page 52: III Opengl

En OpenGL hay dos matrices principales que determinan como s e pintara un punto enpantalla.

La primera es la MODELVIEW que transforma los puntos en el espacio tridimensional,los traslada, los rota y los escala.

Se le dice a OpenGL que es la que vas a modificar con la funciónglMatrixMode(GL_MODELVIEW) ;

Coordenadas Homogéneas

Los más habituales contenidos de esta matriz son:

La matriz identidad: Es la que no transforma el punto. si multiplicas un punto por e stamatriz da el mismo punto.

Se le dice a OpenGL que es la que queremos con la función glLoad Identity(); EnOpenGL la matriz identidad es la que se aplica por default si n o se le dice lo contrario.

Page 53: III Opengl

La matriz para mover un objeto:

En las posiciones de la X, Y y Z se pone la distancia que queremo s mover el objeto encada eje (positivo o negativo). La función para cargar esta m atriz es glTranslatef(x,y,z) ;

La matriz para escalar un objeto:

Escala con un factor por cada eje. La función para hacerlo es glScalef (x,y,z );

Coordenadas Homogéneas

Escala con un factor por cada eje. La función para hacerlo es glScalef (x,y,z );

Las matrices para rotar un objeto dependen del eje de rotació n. Las más comunes sonalrededor de cada eje de coordenadas. La función para hacerl o es glRotatef(X,Y,Z);

Page 54: III Opengl

Si queremos rotar un objeto y moverlo tendremos que multipli car las matricescorrespondientes y obtendremos una matriz con los datos nec esarios para que si lamultiplicamos por los puntos de nuestro objeto, los rote y lo s mueva. Pero cuidado, lasmatrices A y B multiplicadas no son igual que las matrices B y A multiplicadas, el ordenen que multiplicamos cambia el resultado.

Cuando usamos glTranslate , glScale o glRotate , en realidad estamos multiplicando laactual MODELVIEW por la de la correspondiente transformación.

Coordenadas Homogéneas

Ejemplo:- Cargamos la matriz identidad para asegurarnos de donde emp ezamos:glLoadIdentity();- Decimos a OpenGL que lo siguiente a pintar va movido de sitio : glTranslatef(0,0,-10);- Lo mismo pero girado alrededor del eje y: glRotatef(30,0,1 ,0);- Ahora pintamos el objeto: glBegin(...); glVertex3f(...) ; ... glEnd();- Podriamos cargar otra vez la matriz identidad para pintar d espues otros objetos enotros lugares: glLoadIdentity();- Y seguimos moviendo, girando, escalando y pintando mas cos as ...

Page 55: III Opengl

La segunda matriz es la PROJECTION, y es la encargada de definir la proyección quevamos a usar. OpenGL antes de pintar un punto en la pantalla, l o multiplica primero porla matriz MODELVIEW y luego por la PROJECTION.

A OpenGL se le dice que vas a modificar esta matriz con la funci ónglMatrixMode(GL_PROJECTION);

Esta matriz se modifica cuando vas a definir el tipo de proyec ción que vas a usar conlas funciones glOrtho (), glFulstrum () y gluPerspective ().

Coordenadas Homogéneas

las funciones glOrtho (), glFulstrum () y gluPerspective ().

Por fin toca modificar nuestro programa y lo primero que camb iaremos será la funciónglOrtho( ) , ya que es la que definía la proyección ortogonal, y la cambia remos por lafunción gluPerspective( ) correspondiente.