Introducci\u00f programaci\u00 video David Erosa Garc\u00eda Luis Rodero Morales
[email protected]
[email protected]
Programaci\u00f3n PONER ALGO
Fundamentos de OpenGL Inicializar SDL y OpenGL
\u2022 Cabeceras: < GL/gl.h> y < G L/ glu. h> \u2022 Librerias: libG L. so y libGLU.so (linux); opengl32. lib y Para poder usar OpenGL con SDL, hay que pasar algun \u2022 FLAGS a la llamada a SDL_SetVideoMode(...): \u2022 SDL_OPENGL \u2022 SDL_OPENGLBLIT \u2022 El intercambio de los buffer se realiza con: \u2022
void SDL_GL_SwapBuffers ( void );
Para establecer algunos valores, usaremos
int SDL_GL_SetAttribute ( SDL_GLattr attr, int value );
\u2022
Nosotros solo estableceremos SDL_GL_DOUBLEBUFFER a 1.
Fundamentos de OpenGL Inicialización de OpenGL 1
Dado que OpenGL se comporta como una máquina de estados, podemos • cambiar su estado en cualquier momento durante la ejecución del p A pesar de esto, es conveniente establecer ciertos parámetros al principio • del programa. • Iluminación. • Función de Z-Buffer. • Carga de texturas. • Modelo de sombreado. • Ocultación de caras traseras. • ...
Fundamentos de OpenGL Inicialización de OpenGL 2 glViewport (0, 0, w, h);
// Tamaño de la ventana.
glMatrixMode (GL_PROJECTION);
// Matriz de proyección...
glLoadIdentity ();
// ... “reseteada”.
gluPerspective (60.0, (GLfloat)w / (GLfloat)h, .5f, 100.0f ); // Transformación. glMatrixMode (GL_MODELVIEW);
// Matriz de modelado...
glLoadIdentity ();
// ... también “reseteada”.
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1 );
// Doble buffer.
glClearColor (1.0, 1.0, 1.0, 0.0);
// Limpia la pantalla en negro.
glShadeModel (GL_SMOOTH);
// Modelo de Representación
glEnable (GL_DEPTH_TEST);
// Profundidad.
glFrontFace ( GL_CCW );
// Especifica la cara frontal.
Fundamentos de OpenGL Redimensionado En caso de que se permita el cambio de tamaño de la ventana de la • aplicación, habría que seguir los siguientes pasos: Volver a llamar a SDL_SetVideoMode para cambiar el tamaño de la • superficie. • Cambiar el tamaño de la ventana con glViewport ( ... ). Cargar la matriz identidad en las matrices de proyección y modelado • con glLoadIdentity();
Fundamentos de OpenGL TODO Para mandar la geometría de nuestro mundo a OpenGL existen 3 métodos: • Directo, Compilado y Arrays de Vértices (Vertex-Array). Antes de mandar la geometría (vértices) limpiamos los bufers de color y • profundidad con:
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
También es conveniente cargar la matriz identidad, en caso de no haber • guardado la matríz en pila (lo veremos más adelante) con:
•
glLoadIdentity (); Finálmente ajustamos la posición y orientación del observador con:
gluLookAt (
eye_x, eye_y, eye_z, to_x, to_y, to_z, up_x, up_y, up_z );
Fundamentos de OpenGL Modo Directo
• •
Este modo manda directamente la geometría a OpenGL. Los datos a mandar se encuentran entre las funciones
void glBegin( GLenum modo ); y void glEnd ( void );
• Donde modo puede ser: • GL_POINTS • GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP • GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN • GL_QUADS, GL_QUAD_STRIP • GL_POLYGON
Fundamentos de OpenGL GL_POINTS
• • •
Especifica vértices a dibujar como puntos. El tamaño de los puntos se puede cambiar con
void glPointSize (GLfloat size); El uso es el siguiente:
glBegin ( GL_POINTS ); glVertex3f ( -1.0, -1.0, 0.0 ); glVertex3f ( 1.0, -1. 0, 0.0 ); glVertex3f ( 0.0, 1.0, 0.0 ); glEnd ();
Fundamentos de OpenGL GL_LINES
• •
Especifica vértices a usar como extremos de líneas rectas. El uso es el siguiente:
glBegin ( GL_LINES ); // Cada par de vértices genera una linea. glVertex3f ( -1.0, 0.0, 0.0);
// Un extremo de una linea.
glVertex3f ( 1.0, 0.0, 0.0);
// El otro extremo.
glVertex3f ( 0.0, 1.0, 0.0);
// Un extremo de la otra.
glVertex3f ( 0.0, -1.0, 0.0);
// Final de la linea.
glEnd ();
Fundamentos de OpenGL GL_LINE_STRIP - GL_LINE_LOOP
• Usan la lista de vértices para generar una sola linea quebrada. A diferencia de GL_LINE_STRIP, GL_LINE_LOOP une con una línea el • último vértice especificado con el primero.
Fundamentos de OpenGL GL_TRIANGLES • Por
cada
trío
de
vértices,
genera
• Hay
un
triángulo.
que tener cuidado con el sentido de creación sentido incorrecto puede provocar que no se visualice.
glBegin ( GL_TRIANGLES ); glVertex3f ( -1.0, -1.0, 0.0 ); glVertex3f ( 1.0, -1.0, 0.0 ); glVertex3f ( 0.0, 1.0, 0.0); glEnd ();
de
Fundamentos de OpenGL GL_TRIANGLE_STRIP • Genera una tira de triángulos de la siguiente forma:
• Primero genera un triángulo completo con los tres primeros vértices
• A continuación, especificando solo un nuevo vértice, se usan los dos
vértices de cada triángulo para generar otro: V4 3
V2
V3
2 1
V0
V1
Fundamentos de OpenGL GL_TRIANGLE_STRIP • Genera
• Primero
una
abanico
se
especifica
de el
triángulos. vértice
central,
y
a
continuación
glBegin (GL_TRIANGLE_FAN); glVertex3f (4.0, 0.0, 0.0); for (float angulo = 0.0f; angulo < (2 * GL_PI); angulo += ( GL_PI / 9.0 )) { x = 4 + 2.0 * sin (angulo); y = 2.0 * cos (angulo); glVertex2f (x, y); } glEnd ();
Fundamentos de OpenGL GL_QUADS - GL_QUADS_STRIP • Estos
modos
generan
cuadriláteros
por
cada
• El
cuatro
vértice
modo GL_QUAD_STRIP es similar a GL_TRIANGLE_STRIP, los dos últimos vértices del anterior cuadrilátero y otros dos nue generar el siguiente. V1
V2
V5
V0
V3
V4
Fundamentos de OpenGL GL_POLYGON • Genera
• Cuidado
polígonos con
los
de
cualquier
polígonos
no
número
de
convexos.
lados.
Fundamentos de OpenGL Transformaciones • Para
realizar desplazamientos, rotaciones y escalados, matriz de modelado con ciertas funciones de OpenGL.
• Para
conseguir
el
efecto
de
desplazamiento
de
los
hay
objetos
void glTranslatef ( GLfloat x, GLfloat y, GLfloat z );
• La
rotación
se
consigue
con:
void glRotatef ( GLfloat ang, GLfloat x, GLfloat y, GLfloat z );
• ang
es el ángulo a rotar alrededor del eje dado por el
• Podemos escalar con: void glScalef ( GLfloat x, GLfloat y, GLfloat z );
• Escala la matriz con un factor x, y, z.
vector
Fundamentos de OpenGL Listas de visualización 1 • Otro de los modos de visualización.
de
mandar
geometría
a
OpenGL
es
creando
• Estas listas son secuencias de vértices precompilados no tienen que procesarse en cada iteración, solo llamadas.
de
forma
• Suponen una mejora de rendimiento con respecto al modo directo.
Fundamentos de OpenGL Listas de visualización 2 • Primero hay que reservar espacio para las listas GLuint glGenLists ( GLsizei range );
• Esto nos devuelve un índice a partir del cual podemos nuestras listas. • Antes de comenzar un bloque con glBegin: void glNewList ( GLuint lista, GLenum modo );
• Con modo: • GL_COMPILE • GL_COMPILE_AND_EXECUTE • La diferencia entre los dos es que el segundo representa la geometría a la vez que la compila.
numerar
Fundamentos de OpenGL Listas de visualización 3 • Tras terminar el bloque con glEnd() cerramos la lista con: void glEndList ( void );
• Solo queda llamar a la lista cuando necesitemos renderizarla. void glCallList ( GLuint lista );
Fundamentos de OpenGL Iluminación 1
• Para construir luces en OpenGl debemos aclarar antes tres conceptos • Luz ambiental: Es la luz que no proviene de ninguna fuente ni dirección en particular, pues los rebotes con el entorno le hacen perder direccionalidad. • Luz difusa: Es aquella que viene de una dirección particular, que se refleja suavemente en una superficie, como luz fluorescente.
pero
• Luz especular: Es también direccional, pero se refleja de forma uniforme y precisa en las superficies, como un rayo láser. • Toda luz tiene cierta cantidad de componente ambienta, difusa y especular.
Fundamentos de OpenGL Iluminación 2 • Antes de poder construir nuestras luces en OpenGL, hay que flag correspondiente a la iluminación:
activa
glEnable ( GL_LIGHTNING ) ;
• Para especificar la luz ambiental, usamos glLightModelfv ( GL_LIGHT_MODEL_AMBIENT, arrayRGBA );
• Una vez que tenemos iluminación ambiental, hay que dar propiedade a los materiales. • Usaremos el llamado “seguimiento de color”. glEnable ( GL_COLOR_MATERIAL );
Fundamentos de OpenGL Texturas (1) Antes de texturizar un objeto, hay que activar una serie de opciones en • OpenGL . Esto lo hacemos en nuestra función init().
glEnable ( GL_TEXTURE_2D )
Fundamentos de OpenGL Texturas (2) Para aplicar una textura a un objeto, primero necesitamos crear dicha • textura. Para ésto, nos servimos de un fichero gráfico con los datos Las texturas deben tener potencias de dos como dimensiones (128x128, • 256x256, 512x512). Hemos de generar un espacio para la textura. É sto se hace con la función • glGenTextures ( int , GLuint ). Luego especificamos el tipo de textura para dicho espacio. Usamos la • función glBindTexture ( GL_TEXTURE_2D , GLuint ). Finalmente generamos los datos de la textura con la función glTexImage2D • (GL_TE XTURE_2D , nivel , componentes , ancho , alto, 0,
formato , GL_UNSIGNED_BYTE, *pixels).
Fundamentos de OpenGL Texturas (3)
• •
Una vez creada la textura, necesitamos “pegarla” al objeto que queramos. Para ésto utilizamos el concepto de coordenadas de textura. 1,0 v3
v1 v2
v1
v3
v2 0,0
0,1
Fundamentos de OpenGL Texturas (4) Para asignar coordenadas de textura a un vértice, llamamos a la función • glTexCoord2f ( GLfloat u , GLfloat v ). Como cada vértice tendrá sus propias coordenadas de textura, habrá que • llamar a glTexCoord2f cada vez que definamos un vértice con glVertex*
Fundamentos de OpenGL Niebla El efecto de niebla en OpenGL es muy sencillo, basta con activar la niebla y • especificar la densidad, color y tipo de niebla. • La activación se realiza con:
•
glEnable ( GL_FOG )
La densidad, color y tipo con:
lFogf ( GL_FOG_DENSITY, Glfloat densidad)
g
glFogfv (GL_FOG_COLOR, Glfloat * color) glFogi (GL_FOG_MODE, MODO) glFogi ( GL_F OG_START, GLfloat );
•
glFogi ( GL_F OG_END, GLfloat ); Donde MODO puede ser: GL_LINEAR | GL_EXP | GL_EXP2
Aplicaciones Introducción
Ya tenemos nociones básicas de dibujo en 3D. Con ellas y utilizando • algunas técnicas podemos hacer cosas más complejas. • Por ejemplo, podemos crear modelos tridimensionales. También podemos crear una cámara genérica, que tome todas sus • características como parámetros, y podamos moverla libremente po
espacio.
podemos crear efectos especiales de luz y atmosféricos ( pero esto • yaTambién empieza a tener mandanga :P ). Algo muy importante : que dibujemos en 3D no significa que nuestro mundo • lógico sea tridimensional.
Aplicaciones Modelos 3D (1)
• En 2D, para representar objetos y personajes, usábamos Sprites. • En 3D también podemos usar Sprites, pero lo suyo es usar modelo • Un modelo 3D (para nosotros) es un conjunto de vértices y de trián • Un ejemplo de modelo es un cubo: • Tiene 12 triángulos (2 triángulos por cara del cubo). • Para dibujarlo hacemos glBegin ( GL_T RIANGLES ) 12 veces. oblema : un triángulo está formado por 3 vértices, 12 * 3 = 36 • enPrtotal ( uf, pero un cubo no eran 8 vértices?? ). Solución : las caras pueden compartir vértices, definimos 8 vértices y cada • triángulo contiene 3 índices.
Aplicaciones Modelos 3D (2)
• Los modelos pueden llegar a tener un número bastante alto de triángulos. roblema : dibujar los modelos a mano se convierte en algo incómodo • ( Ppor no decir imposible ). “Uf, por ahí hay gente que dibuja los modelos en el código, no es coña” • (Luis). Solución : crear los modelos en un modelador y desarrollar herramientas • que los importen a un formato de nuestro gusto. Usaremos unas estructuras de datos que tengan relación directa con • nuestras necesidades.
Aplicaciones Modelos 3D (3) Para guardar vértices, usaremos una estructura vertex con los siguientes • campos: • x, y, z : coordenadas espaciales del vértice • u, v : coordenadas de textura • Para guardar triángulos, usaremos la siguiente estructura triangle: • v[3] : array de índices. • Para guardar materiales, tendremos la estructura material: • r, g, b : color del material • textureID : id de la textura (si tiene)
Aplicaciones Modelos 3D (4)
• Para almacenar una malla, tenemos la estructura mesh : • mat_id : id del material • n_triangles : número de triángulos • n_vertices : número de vértices • vertex *v_list : array de vértices • triangle *t_list : array de triángulos • Finalmente, para almacenar el modelo, tenemos model : • n_mats : número de materiales • n_meshes : número de mallas • material *mat_list : array de materiales • mesh *mesh_list : array de mallas
Aplicaciones Modelos 3D (5)
Necesitamos algo para convertir los datos de un formato de modelador a • nuestro formato propio. una herramienta (ase2mod) que traduce los modelos exportados • enTenemos ASE de 3D Studio MAX. La herramienta aún está en desarrollo, por lo que ahora mismo no ofrece • una funcionalidad completa ( no carga texturas por ejemplo ). Nuestro formato soporta sombreado por triángulos. E l sombreado por • vértices es fácil de implementar y aporta mejores resultados visuale
Aplicaciones Mapping en 3D (1)
técnica de mapping descrita para 2D es fácilmente practicable en 3D de • laLasiguiente manera: • Tenemos un array de texturas que representarán los tiles. Para dibujar el mapa, aplicamos la textura que corresponda según la • matriz de mapeado en un quad y lo dibujamos en la posición que n
dicha matriz.
Una variante del método es usar modelos que representen trozos de • escenario en lugar de quads con textura. A pesar de todo, lo que más se utiliza para escenarios es un gran modelo • que represente la zona por la que nos vamos a mover.
Aplicaciones Mapping en 3D (2)
Imágenes de Downtown Drivin'
(Monstrous Software: http://home.planet.nl/~monstr
Bibliografía • Internet • API's • Página oficial de SDL : http://www.libsdl.org • Página oficial de Allegro : http://alleg.sf.net • Suplementos de Allegro: http://www.allegro.cc http://www.opengl.org • Página de OpenGL : • Desarrollo de juegos en general: http://www.gamedev.net • Gamedev http://www.flipcode.com • Flipcode http://www.gametutorials.com • GameTutorials http://home.planet.nl/~monstrous • Monstrous Software http://www.ultimategameprogramming.com • UGP
Bibliografía • Inteligencia Artificial http://www.aidepot.com • AIDepot http://www.gameai.com • GameAI • Amit's Game Programming Site (pregunta, que no cabe) http://www.generation5.org • Generation5 • Gráficos http://nehe.gamedev.net • NeHe http://cone3d.gamedev.net • Cone3D • Varios: • Google (Dios bendiga a Google) ht tp: // www.google.com http://code.box.sk • Code Box
Bibliografía • Libros • Game Programming Gems 1, 2, 3 y 4 • AI Game Programming Wisdom 1 y 2 • Core Techniques and Algorithms in Game Programming • Physics for Game Developers • Game Architecture and Design • OpenGL Programming Guide (a.k.a. the Red Book) • OpenGL Programming Reference (a.k.a. the Blue Book) • ...
EOD && EOC • Agradecimientos: Al SIC, por este pedazo de aula y de equipos (aunque exploten los • monitores...) • A Mauri, por su portátil : http://www.laffer.tk • A Coque, por sus gráficos (sin acritud <@:) ) . • A Jezú, por darnos espinacas. • Al Lidl, por sus galletas maría. • A Sur Multimedia, por hacernos perder una tarde. • Al UT2004. • A ID Software, por tenernos en ascuas con el Doom 3. • A Valve, por esperar a ID. • A nosotros mismos. • A AsCII.
P.D. Si a alguien le interesa (o conoce alguien que le interese) cualquier cosa • relacionada con el diseño y programación de videojuegos, con la
•
programación en general o con cualquier cosa, tiene algún proyecto e mente y necesita ayuda, o le apetece ayudar en algún proyecto, que se por AsCII y que nos haga saber de su existencia. Nuestro correo está para que nos escribáis, esaboríos:
[email protected]