lunes, 17 de diciembre de 2012

Texturas BMP con SDL en objetos 3D OpenGL (The easy way)


Tetris

Es un juego originalmente programado por Alekséi Pázhitnov en la Union Sovietica, cuyo nombre viene de un prefijo numérico “tetra” (4) y el nombre del pasatiempo favorito de su creador, el tenis.
Este juego probablemente sea uno de los que mas versiones tiene, pues existe una para casi cada consola, aparato portátil, sistema operativo que existe, lo que le dio según la revista Electronic Gaming Monthly el titulo de el “mejor juego de todos los tiempos”

El programa a presentar esta vez, mas que un juego es una presentación de gráficos de OpenGL 3D con texturas cargadas a través de SDL, que de alguna forma, basa su estética en el juego original no siendo “fiel” en particular a ninguna versión conocida de tetris




Screenshot de los gráficos logrados


Para el desarrollo de la aplicación se ocuparon diferentes texturas cargadas como imágenes en formato BMP, lo que en fin, con un trabajo mas acabado se podría lograr un aspecto muy cercano al original del juego.



                   Screenshot de una de las versiones mas famosas del juego, la de NES


Descripción de la solución

Abordare esta parte del informe tomando primero en cuenta el enunciado propuesto por el profesor, para luego abordar los detalles técnicos la implementación del juego en su conjunto.

  • Sobre los objetos estáticos: Puesto que esta aplicación es mas que nada una presentación de gráficos no pretende ser jugable mas que por una mera demostración, por tanto solo existe un objeto estático que vendría siendo el escenario que es invocado mediante la función cargar_escenario(); que se apoya en una función creada anteriormente para cargar texturas desde imágenes en formato BMP.

  • Sobre los objetos animados: debido a especificaciones del enunciado la mayoría de los objetos son animados, aunque si se controla mediante el teclado uno puede desplazar o rotar de manera total el escenario junto a sus elementos.
Un alcance MUY importante es que todos los objetos se encueran animados por una única función que gracias a “glutTimerFunc(1,Avanzar,1);” se ejecuta cada 1 ms (milésima de segundo) asignando nuevos valores a variables globales que intervienen a través de todos los procesos del juego.

  • Por ultimo respecto al código:

El programa completo se encuentra segmentado en 3 partes un archivo de extensión “.c” y dos headers “.h” , esto debido que se separo lo que tiene que ver con funcionalidades de glut y linea general en un archivo “tetris.c”, el manejo de sprite y sus matrices en “sprites.h” y las acciones y mecánica del juego en “ttGL_SDL.h” (se describirá con mayor detalle en el siguiente tema).

Debido a la falta de exactitud en cuanto al temporizador que provee glut, la velocidad debe ajustarse en el código manualmente si es que este llegara a verse demasiado rápido, (el numero a modifica se encuentra en el archivo “tetris.c” y se encuentra debidamente comentado.

Alcances:
  1. Existe forma de usar diferentes formatos para crear texturas para objetos creados con OpenGL, sin embargo no existe necesidad de reinventar la rueda para este cometido, por tanto se integra en este código de manera simple SDL y OpenGL (cosa que en realidad parece simple desde el punto de vista de codificación, pero se podrá observar que en los ejemplos propuestos en Internet el estilo de codificación cambia demasiado al integrar OpenGL con SDL, pues bien este no es el caso)
  2. Si bien SDL provee un completo conjunto de bibliotecas que hubiesen podido hacer posible la construcción de las demostración casi en su totalidad (excepto por el modelado 3D) no era materia del curso el trabajar con al API de SDL, por tanto solo se utilizo un mínimo de su capacidad para integrar la funcionalidad de las texturas al modelado con OpenGL.
  3. Las aplicaciones generadas con parte de esta API (SDL), por lo menos en versiones antiguas de windows XP, necesitan de la DLL “SDL.dll” pues en ellas se encuentran binarizadas las definiciones de las funciones que requiere SDL para su funcionamiento.
  4. Una observación importante es como cambia el mapeado de las texturas cuando se cambia entre “glOrtho” a “glPerspective”, pues uno respecto al otro invierte los mapeados hechos, por tanto para una plena compatibilidad entre estos modos es necesario tomar en cuenta en esto y programar debidamente, en esta demostración, eso no se hizo, ya que al existir este alcance se necesita comprobación.
  5. Por ultimo señalar que esta vez se trabaja con una melodía en formato WAV, cuya funcionalidad esta soportada por una biblioteca no portable, propia de los sistemas Microsoft.


Descripción de funciones y archivos usados:

tetris.c: En este archivo se encuentra la linea general de la demostración, ademas de las funcionalidades de glut que apoyan el proceso, tales como el apoyo al teclado, el re dimensionamiento de objetos etc.
  • void InicializarGL(); esta es una función de propósito general no especifica para el juego, libera de código extra en la función main(); ya que se encarga de tareas especificas de glut que no necesariamente son tarea de la linea principal de un programa.
  • void display(); esta función se encarga de exhibir todos lo objetos del juego y debe ser específicamente llamada por la función glutDisplayFunc(display); de lo contrario no hará nada.
  • void resize(int w, int h); esta función se encarga de ajustar los tamaños si es que la ventana se redimensiona, ademas crea la escala con la que se trabajara en el resto del juego, los argumentos “w”, “h” usan como argumento el tamaño actual de la pantalla.
Esta función debe ser llamada o enviada como argumento específicamente a la función glutReshapeFunc(resize); de lo contrario tampoco se hará nada.

  • void ControlTeclado(unsigned char key, int x, int y); fácil, esta función controla las teclas que no son especiales dentro del juego “ENTER” y “ESC” y debe ser argumentada para la función glutKeyboardFunc(ControlTeclado); y sus argumentos propios son un “key” correspondiente a una tecla y un “x” , “y” que aunque en mi caso particular no ocupo debe ser igualmente anexado.
  • void ControlFlechas(int key, int x, int y); igualmente fácil, esta función se encarga de los eventos que ocurren con la flechas del teclado, puesto a que estas son teclas especiales, no se consideran dentro de la función descrita anteriormente por tanto son argumentadas a glutSpecialFunc(ControlFlechas); y también cuentan entra sus argumentos un “key” que es la flecha oprimida, y un “x”, “y” que no utilizo.
  • void timer(int x); función que se auto ejecuta sobre intervalos dados que gracias a esto provee movimiento a la demostración.

tGL_SDL.h: En este archivo se concentran las acciones propias del juego y el soporte a texturas SDL no la funcionalidades de glut como por ejemplo la carga escenarios y piezas ademas de la variables globales que apoyan los cálculos y conjunto de flags que permiten las acciones

  • void void setmov(); esta función se encarga de establecer los valores iniciales (si es que se necesita) de la mayoría de la variables globales del juego.
  • SDL_Surface *LoadBMP(char *filename); función genérica VITAL para el trabajo con texturas y la integración de OpenGL y SDL, ademas genera archivos con los respectivos mensajes de error creados por SDL, da soporte al formato BMP que corresponda a la porfundidad de color requerida, en este caso imagenes de 24 bits (ni mas ni menos).
  • void LoadGLTextures(); función muy simple que se encarga de la transformación de archivos BMP a texturas que OpenGL puede utilizar
  • void cargar_piezas(int pieza); pone las piezas en juego y soporta la rotación de estas que se hace mediante el teclado se guia gracias a las matrices que hay en el archivo sprites.h.
  • void cargar_titulo(); Pone en pantalla el titulo de la demostración y soporta el cambio de color de sus miembros individuales.
  • void cargar_escenario(); crea el marco de trabajo con las texturas indicadas;
  • void cubo(int color, int x, int y, int z); crea la unidad de trabajo ademas de texturizarlo según el color pedido
space_sprites.h: aquí se encuentra la parte artística de todo este asunto, este archivo contiene el conjunto de sprites en matrices, que guisan a los procesos en como hacer las piezas y generar el titulo para esta demostración.


Librerias necesarias:Librerias 
Enlace descarga: tetris.rar

NOTA:

Esto es una demostración de gráficos basados en tetris se deben instalar los dos devpak
guardados en la carpeta "librerias"

1- la siguiente linea puede necesitarse como parámetro en el compilador (DEV-C++)
-DGLUT_STATIC

2- la sieguiente linea debe agregarse como parametro al linker (DEV-C++)
  -lmingw32 -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32 -lSDLmain -lSDL -lSDL_image