Intentando programar algo gráfico, me encuentro con este pdf de tutorial sobre SDL que parece muy bueno y estoy siguiendo conjuntamente con el de Nacho Cabanes de un pdf encontrado en la librería de Open Libra y tras mucho buscar, encontré una versión más actualizada en su página web.
No voy a pararme en los pdf porque no he terminado de leerlos y tengo intención de profundizar en ellos más adelante, aquí dejo lo que me he enterado del SDL.
Lo primero de todo decir que SDL es una librería multimedia multiplataforma, gratuita y libre. Está escrita en C y trabaja nativamente con C++. También decir que lo han desarrollado gente experimentada en videojuegos, por lo que lo ha escrito gente que sabe lo que se necesita y requiere en estos proyectos.
SDL está compuesto de varios subsistemas, como son Audio, Video, CD-Rom, Timer, Joystick, red... En los videos y gráficos tenemos la posibilidad de trabajar a muy bajo nivel (pixeles) o a un nivel intermedio. Podemos también especificar si queremos usar la memoria del video u otros. Pero el sonido es el punto débil de SDL, por lo que es mejor complementar con otra librería para ese menester.
Para trabajar con SDL necesitamos un compilador de c (vale con el gcc de GNU Compiler), instalamos SDL, que suele estar en los repositorios, y por último, instalamos las librerías adicionales de SDL, como son SDL_image, SDL_mixer, SDL_ttf y SDL_net.
Para compilar, hemos de añadir un parámetro al gcc (o g++, ya no sé que diferencias hay entre un compilador y otro), y es -lSDL. Cuando usamos además otra librería de las añadidas, habrá que especificarlo también, como
-lSDL_image
-lSDL_ttf
-lSDL_mixer
-lSDL_net
Un detalle sobre los tipos, no son simplemente int, float y similares, sino que se especifica signo (Signed, Unsigned) y tamaño múltiplo de 8 (UxxxBB, ejemplo Uint32). Aconsejo echarle un vistazo al primer pdf enlazado para tener una idea.
Empezamos con código de verdad.
Para usarlo, se añade la librería con #include y lo mismo para librerías adicionales
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
...
Se inicializa la librería, especificando que subsistemas se usarán:
int SDL_Init(Uint32 ags);Se hace una sola vez, si por lo que sea necesitamos inicializar algo más después de esta línea, se usa:
SDL_InitSubSystem(SDL_INIT_AUDIO);
Al terminar el programa, necesitamos cerrarlos y liberarlos, para ello, tenemos
void SDL_Quit(void);de forma similar, si sólo queremos quitar un subsistema concreto tenemos
void SDL_QuitSubSystem(Unit32 ags);
Se usa para saber si se inicializó dicho subsistema. 0 si no se inicializó, constante representativa del subsistema si se inicializó.
Uint32 SDL_WasInit(Uint32 ags);
Proporciona un mensaje de error. Cuando utilicemos esta función en nuestro código y no ejecutemos desde consola se creará un fichero stdout.txt o stderr.txt.
char *SDL_GetError(void);
Los nombres de los subsistemas son los siguientes:
- SDL_INIT_VIDEO: Inicializa el subsistema de video.
- SDL_INIT_AUDIO: Inicializa el subsistema de audio.
- SDL_INIT_TIMER: Inicializa el subsistema de timers.
- SDL_INIT_CDROM: Inicializa el subsistema de CD-ROM.
- SDL_INIT_JOYSTICK: Inicializa el subsistema de joystick.
- SDL_INIT_EVERYTHING: Inicializa todos los subsistemas.
- SDL_INIT_NOPARACHUTE: Prepara a SDL para capturar señales de error fatal.
Son flags, por tanto podemos combinarlos como si de binario se tratara, por ejemplo, si usamos
SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO);estaremos preguntando por ambos y nos devolverá ambos, uno de ellos o cero según el resultado. Se aplica también en otras funciones.
Lo siguiente es la función atexit() que recibe como parámetro otra función. En nuestro caso la función SDL_Quit. Esto produce que a la salida de la aplicación sea cerrada la librería SDL y sus subsistemas.
Tenemos que pintar en algún sitio lo que mostraremos, y para ello tenemos el tipo SDL_Surface cuyo método de inicialización es
SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 fl ags);
Los flags son:
- SDL_SWSURFACE: La super cie de vídeo a crear se almacenará en RAM, está por defecto.
- SDL_HWSURFACE: Se almacenará en la memoria de vídeo.
- SDL_ASYNCBLIT: Establece el modo de blit asíncrono. Es decir, habilita el uso de transferencia asíncrona de bloques a la superfi cie de visualización. Sirve para mejorar el rendimiento con más de un procesador.
- SDL_ANYFORMAT: Esta bandera debe ser usada cuando creamos la super cie principal de nuestra aplicación en una ventana dentro de un gestor de ventanas. En caso de que el modo que queremos inicializar no esté disponible inicializa el mejor modo posible de profundidad de color (bpp) dentro de los disponibles.
- SDL_HWPALETTE: Proporciona a SDL acceso exclusivo a la paleta de color. Si no se usa esta bandera no siempre se podrán obtener los colores utilizando las funciones SDL_SetColors() y SDL_SetPalette().
- SDL_DOUBLEBUF: Activa el uso de doble bú fer. Esta opción sólo es válida junto a SDL_HWSURFACE.
- SDL_FULLSCREEN: Intenta activar el modo a pantalla completa.
- SDL_OPENGL: Crea un contexto OpenGL en la super cie creada. Se deben establecer los atributos OpenGL previamente (SDL_GL_SetAttribute()).
- SDL_OPENGLBLIT: Crea un contexto OpenGL en la super cie creada, permitiendo que SDL haga el renderizado de dos dimensiones, es decir permite operaciones de volcado normales de SDL.
- SDL_RESIZABLE: Permite que la ventana dónde hemos creado la super cie pueda cambiar de tamaño. Desaconsejable en muchos casos.
- SDL_NOFRAME: Si creamos la super cie en una ventana esta opción nos ofrece la posibilidad de eliminar el borde de la misma, así como la barra de título y otras decoraciones. Cuando establecemos el modo a pantalla completa se activa esta bandera automáticamente.
Y esto es todo por hoy, otro día profundizo más en SDL para hacer mejores gráficos. Por el momento, me contentaré con que sea una miseria :P