9. Listas, Texto y FPS |
![]() |
![]() |
Videojuegos - Curso de Programación de juegos | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Escrito por Vicengetorix | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Página 1 de 3 ![]() Lo primero para cumplir los objetivos de este capitulo es aprender lo que son las "listas de pintado" en OpenGL (Display List). El concepto es facil. Tengo un numero de vertices (por ejemplo los de nuestro cubo) que voy a pintar varias veces porque quiero poner varios cubos iguales en mi escena. En vez de pintar varias veces el cubo en cada frame (un frame es como un fotograma, cada vez que pinto la escena), le mando a OpenGL los datos de mi cubo con un identificativo y cada vez que lo quiero pintar le digo a OpenGL que pinte el cubo (con los datos que le pase antes), mediante este identificativo. Resumiendo. Primero le paso a OpenGL los datos del cubo, fuera de la funcion Pinta(), y cuando quiero pintar el cubo solo tengo que decirle que lo pinte, 1, 2, 3,.. o 300 veces. Ahora veremos como hacemos esto de forma practica. Empezaremos con el codigo del capitulo anterior, en la version de luz puntual. Definimos una variable de tipo GLuint global para almacenar el identificativo de la lista que vamos a crear.
Lo primero, por ordenar un poco el programa vamos a sacar de la funcion Pinta() el codigo con el que pintabamos el cubo y lo pasaremos a otra funcion en la que generaremos la lista. Esta funcion la llamaremos GeneraLista(). Lo primero sera generar el identificativo para la lista con la funcion glGenLists. Esta funcion tiene como parametro en numero de listas a generar (en nuestro caso 1) y retorna el identificativo. Luego con la funcion glNewList indicamos a OpenGL que empezamos a indicarle las instrucciones que debe guardar en la lista. Los parametros son el identificativo de la lista y GL_COMPILE.
Tras este codigo van todas las funciones con las que pintabamos el cubo, desde glBegin a glEnd, y que hemos borrado de la funcion Pinta() y pasado aqui. Al final terminamos con la creacion de la lista poniendo la funcion glEndList().
Con esto terminamos la funcion GeneraLista(). Conviene aclarar que entre las funciones de inicio y fin de la generacion de la lista se puede incluir, por ejemplo, las funciones glVertex dentro de un bucle for o while y pasar las coordenadas en variables. En la lista se almacenara solo los datos que finalmente, como resultado del algoritmo que hagas, se envian a la tajeta de video (glVertex, glNormal, glTexCoord, ..., solo almacena lo relativo a OpenGL y con datos concretos), asi que no se puede guardar en una lista un algoritmo que genere diferentes formas en base a variables. Solo guarda datos de vertices concretos y exclusivamente datos OpenGL. Luego nos queda usar la lista generada en la funcion Pinta(). Aqui ya no estaba el codigo para pintar nuestro cubo, lo habiamos pasado a la funcion GeneraLista(), y ahora para pintar nuestro cubo deberemos invocar esta lista que hemos crado con la funcion glCallList(...) pasandole como parametro la variable que contiene el identificativo de la lista que contiene nuestro cubo: glCallList(Cubo). Asi pues, incluiremos nuevo codigo donde estaba antes el codigo delimitado por glBegin(...) y glEnd(), estas dos funciones incluidas (quiero decir que ya no hacen falta, que las hemos puesto al crear la lista):
En este codigo hemos pintado 4 cubos, en vez de el unico cubo que pintabamos antes. Cada funcion glCallList(cubo) del codigo pinta un cubo. El primero se pintara donde se pintaba el cubo original, y los otros los hemos puesto en otros lugares de nuestra escena, moviendolos con glTranslate (observa que no hemos cargado la matriz identidad entre una funcion glTranslate y otra, por lo que las traslaciones se sumaran, si antes he movido un cubo 2 y ahora muevo otro cubo otros 2, el segundo cubo se habra movido 4 en total, 2+2). Aqui aprovecho para hacer una apreciacion sobre las transformaciones y rotaciones que puede que os ahorre bastante tiempo, que de otro modo tendriais que perder hasta dar con el motivo por el que los objetos no se ponen donde quereis. En OpenGL no es lo mismo mover y rotar que rotar y mover. Para entenderlo mejor. Cuando movemos o rotamos no estamos haciendolo sobre el objeto si no sobre el eje de coordenadas. Si giramos el eje de coordenadas 90 grados respecto al eje Y, si luego movemos hacia el eje Z, no mandaremos al objeto hacia el fondo de la pantalla si no hacia un lado. No veremos el objeto que pretendemos colocar el pantalla, porque habremos puesto el eje Z donde antes estaba el eje X. En cambio si movemos hacia el eje Z primero veremos el objeto tan lejos como hayamos movido. Si luego giramos, estaremos girando el objeto sobre su propio eje pero todavia en el mismo lugar del espacio. Graficamente: Gira y mueve: ![]() Mueve y gira: ![]() Esta claro que aqui el orden si altera el producto (de matrices). Continuamos. Tambien he desabilitado las texturas - glDisable(GL_TEXTURE_2D) - Tras esto ya no tengo que desabilitarlas antes de pintar la esfera. Solo nos queda un detalle para que el resultado de nuestro programa, modificado para usar "display list" sea el deseado. Incluimos una llamada a la funcion GeneraLista() dentro de la funcion IniciaGL(), al final. Si no lo hicieramos, el programa nunca pasaria por el codigo que genera la lista y no podria luego pintarla.
Tambien tenemos la opcion de borrar las listas creadas si queremos reusar los indices con la funcion glDeleteLists(...), que permite borrar un indice o un rango de ellos. El resultado en pantalla seria asi: ![]() El codigo completo es este: usw9a.cpp ¡Sólo los usuarios registrados pueden escribir comentarios!
3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved." |