Desarrollo de videojuegos en SDL II

Continuando la entrada anterior sobre el tutorial de Antonio García Alba


Inicialización de librerías adicionales
  • SDL_image
  • #include <SDL/SDL_image.h>

    compilar con -lSDL_image


  • SDL_ttf
  • #include <SDL/SDL_ttf.h>

    int TTF_Init(void); //devuelve cero si es correcto, -1 al contrario

    void TTF_Quit(void);

    compilar con -lSDL_ttf


  • SDL_mixer
  • #include <SDL/SDL_mixer.h>

    int Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize); //cero si correcto, -1 al contrario

    void Mix_CloseAudio(void);

    compilar con -lSDL_mixer


  • SDL_net
  • #include <SDL/SDL_net.h>

    int SDLNet_Init(); //cero si correcto, -1 al contrario

    void SDLNet_Quit();

    compilar con -lSDL_net


Subsistema de vídeo

Conceptos básicos

Bpp (bits per pixel)
  • 8 bpp (256 colores)
  • Se usa una paleta para determinar dichos colores

  • 16 bpp (HighColor)
  • Hay distintas combinaciones:
    • 5 bits para rojo, 6 bits para verde y 5 para el azul (el ojo distingue más verdes)
    • 4 bits para el rojo, verde y azul. Más equitativo

  • 24 bpp (TrueColor)
  • RGB puro, 8 bits para cada uno.

  • 32 bpp
  • RGB mas 8 bits para la transparencia o alpha.
Resolución de pantalla X·Y (columnas por filas de píxeles.
Se puede crear superficies en la memoria de la targeta gráfica, lo que da mayor rendimiento. Se llama RAMDAC.

Inicialización
#include <SDL/SDL.h>

SDL_Init(SDL_INIT_VIDEO);

//Se establece un modo de vídeo, el cual devuelve un "lienzo" único que será el que se vea en pantalla
SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);

Los flags disponibles son:
  • SDL_SWSURFACE
  • por defecto, la superficie se crea en la memoria principal del ordenador

  • SDL_HWSURFACE
  • Se almacenará en la memoria de vídeo.

  • SDL_ASYNCBLIT
  • Blit asíncrono. Mejora el rendimiento en multiprocesadores pero puede reducirlo en monoprocesadores.

  • SDL_ANYFORMAT
  • Debe usarse cuando creamos la superficie principal en una ventana dentro del gestor de ventanas. Si nuestro modo no está disponible, usa el mejor modo posible.

  • 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úffer. Esta opción sólo es válida junto a SDL_HWSURFACE. Para actualizar la pantalla se usa SDL_Flip() que permite cambiar los buffers. Si la función no está disponible, hace la llamada a SDL_UpdateRect().

  • SDL_FULLSCREEN
  • Intenta activar el modo a pantalla completa.

  • SDL_OPENGL
  • Crea un contexto OpenGL en la superficie creada. Se deben establecer los atributos OpenGL previamente (SDL_GL_SetAttribute()).

  • SDL_OPENGLBLIT
  • Crea un contexto OpenGL en la superficie 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 superficie pueda cambiar de tamaño. Desaconsejable en muchos casos. Se genera el evento SDL_VIDEORESIZE.

  • SDL_NOFRAME
  • Si creamos la superficie 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.
Se pueden combinar los flags con OR. Si no hubo éxito estableciendo el modo, devuelve NULL. Si nos decidimos por el modo ventana, es aconsejable un bpp=0 y ANYFORMAT.


Información de video

SDL_VideoInfo *SDL_GetVideoInfo(void);

Devuelve cero si no está disponible, 1 al contrario. Si lo llamamos antes de setear, obtendremos el mejor modo.

Es un struct:
  • Uint32 hw_available; // memoria video disponible
  • Uint32 wm_available; //gestor de ventanas disponible
  • Uint32 blit_hw; //indica si el blitting en hw está acelerado
  • Uint32 blit_hw_cc; //blitting con transparencias acelerado
  • Uint32 blit_sw; //blitting entre RAM y memoria de video
  • Uint32 blit_sw_cc; //blitting sw con transparencias acelerado
  • Uint32 blit_sw_A; //blit sw con alpha
  • Uint32 blit_fill; //indica si está acelerado el rellenado de color
  • Uint32 video_mem; //memoria total en kb
  • SDL_PixelFormat *vfmt;

char *SDL_VideoDriverName(char *namebuf, int maxlen);
//nos devuelve el nombre del driver de video.

int SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags);
//si el modo no es soportado devuelve cero, si es compatible, devuelve bpp


Estructuras básicas

SDL_Rect
Sint16 x,y; //Posición. Como dato, el sistema de coordenadas empieza en la esquina superior izquierda y va hacia abajo y a la derecha.

Uint16 w,h; //Tamaño.

Para saber si un punto está dentro de un rectángulo tiene que cumplir:
x1 >= rect.x && y1 >= rect.y
x1 < (rect.x+rect.w) && y1 < (rect.y+rect.h)

SDL no ofrece rectángulos rotados.


SDL_Color
Uint8 r,g,b;

Uint8 unused; //se puede usar para alpha u otra cosa


SDL_Palette
Esto está quedando obsoleto.
int ncolors;
SDL_Color *colors;


SDL_PixelFormat
  • SDL_Palette *palette; //NULL si bpp>8 bits
  • Uint8 BitsPerPixel, BytesPerPixel;
  • Uint32 Rmask, Gmask, Bmask, Amask;
  • Uint8 Rshift, Gshift, Bshift, Ashift;
  • Uint8 Rloss, Gloss, Bloss, Aloss; //pérdida de precisión de 8 bits que tienen a los bit usados
  • Uint32 colorkey;
  • Uint8 alpha;
Útiles funciones son para obtener un color a partir del rgb y para obtener el rgb de un color.
Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);

Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha);

void SDL_GetRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha);

void SDL_GetRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);


SDL_Surface
  • Uint32 flags;
  • SDL_PixelFormat *format;
  • int w,h; //altura y anchura visible
  • Uint16 pitch //ancho real de la superficie en memoria en bytes. Siempre mayor que w por el alineamiento x,y=(y·x·pitch)+(x·bytesPorPixel)
  • void *pixels;
  • SDL_Rect clip_rect;
  • int refcount; //conteo de referencias
El único campo modificable es flags a través de SDL_SetVideoMode y dicha función devuelve la única superficie que será visible. Todas las demás hacen de búffer, las cuales pueden usarse para objetos y/o escenas auxiliares y copiarlos al visible (blitting).

Para crear otra superficie se usa
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);

Cuyos flags tenemos
  • SDL_SWSURFACE
  • En memoria principal, permite modificar directamente, pero es más lento en blitting

  • SDL_HWSURFACE
  • En memoria de video, no tenemos acceso directo a los píxeles, es mucho más lento, pero más rápido en blitting.

  • SDL_SRCCOLORKEY
  • El color key

  • SDL_SRCALPHA
  • Activa el alpha blending


SDL_Overlay
Similar al Surface. Es usado para mostrar video YUV en streaming, por ejemplo mpg.
  • Uint32 format;
  • int w,h; //ancho,alto
  • int planes; //número de planos individuales que se superponen. Normalmente entre uno y tres.
  • Uint16 *pitches; //pitches de cada plano
  • Uint8 **pixels; //vector de punteros para cada plano
  • Uint32 hw_overlay:1; //acelerado por hardware (1) o no (0). Sólo afecta al rendimiento.

  • El campo format puede tener los siguientes valores:
    • SDL_YV12_OVERLAY
    • SDL_IYUV_OVERLAY
    • SDL_YUY2_OVERLAY
    • SDL_UYVY_OVERLAY
    • SDL_YVYU_OVERLAY


    Hay que tener muchos conocimientos sobre YUV. No va a tocarlo en el tutorial más que lo justo para usarlo.

    ¡Hasta la siguiente entrega del copy-paste!

Etiquetas: ,. Guarda el enlace permanente.

Deja un comentario ^^