En anteriores entradas de esta serie hemos visto como crear un makefile y que herramientas usar, hemos visto también como instalar la biblioteca SDL base y como crear una ventana y es el momento de meternos en faena y ver como podemos mostrar un bmp (mapa de bits) dentro de una ventana.
Importante antes de comenzar es crear una serie de directorios y archivos. Aquí la receta:
$ mkdir mostrarimagen $ cd mostrarimagen $ mkdir res bin $ touch makefile mostrarimagen.c
Dentro de makefile meteremos esto:
CC := gcc
CFLAGS := -Wall
LINKER_FLAGS = `sdl2-config --cflags --libs`
test:
make clean
make build
build:
$(CC) $(CFLAGS) -o bin/mostrarimagen mostrarimagen.c $(LINKER_FLAGS)
run:
./bin/mostrarimagen
clean:
-rm bin/mostrarimagen
Dentro de mostrarimagen.c meteremos esto:
#include <SDL.h>
#include <stdio.h>
int main(void) {
SDL_Window * ventana;
SDL_Surface * imagen;
SDL_Renderer * render;
SDL_Texture * textura;
SDL_Init(SDL_INIT_VIDEO);
ventana = SDL_CreateWindow("mostrando una imagen",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_OPENGL);
if (ventana == NULL) {
printf("No se pudo crear la ventana: %s\n", SDL_GetError());
return 1;
}
render = SDL_CreateRenderer(ventana, -1, 0);
imagen = SDL_LoadBMP("res/imagen.bmp");
textura = SDL_CreateTextureFromSurface(render, imagen);
SDL_RenderCopy(render, textura, NULL, NULL);
SDL_RenderPresent(render);
SDL_Delay(33000);
SDL_DestroyTexture(textura);
SDL_FreeSurface(imagen);
SDL_DestroyRenderer(render);
SDL_DestroyWindow(ventana);
SDL_Quit();
return 0;
}
En el directorio res tenemos que meter esta imagen con el nombre imagen.bmp . Copiaremos el directorio res una vez tiene la imagen dentro del directorio bin así:
$ cp -pRv res/ bin/
Si ejecutamos el programa con «make run» o entrando en el directorio bin y ejecutando ./mostrarimagen veremos esto:

Explicando el código:
Una de las cosas que SDL2 (recordemos que estamos usando SDL2) base (sin necesidad de usar sdl_image) es mostrar un BMP. No obstante para hacer esto hemos de realizar una serie de pasos que voy a intentar explicar sin meter demasiado rollo.
SDL_Window * ventana;
SDL_Surface * imagen;
SDL_Renderer * render;
SDL_Texture * textura;
– Cargaremos la imagen imagen.bmp como surface (superficie).
– Copiaremos la surface como texture (textura).
– Copiaremos la texture como renderer.
Es por eso que primero hemos de declarar esos punteros (ventana, imagen, render, textura).
Nuestra finalidad es que lo que cargamos en memoria a la que accede la CPU (surfaces, RAM) se copie en memoria a la que accede la GPU (textures, video RAM) y lo muestre en la ventana.
Para ello usamos estas funciones:
render = SDL_CreateRenderer(ventana, -1, 0);
imagen = SDL_LoadBMP("res/imagen.bmp");
textura = SDL_CreateTextureFromSurface(render, imagen);
SDL_RenderCopy(render, textura, NULL, NULL);
SDL_RenderPresent(render);
SDL_CreateRenderer Utilizamos esta función para crear un contexto de representación 2D para una ventana llamada ventana y creada anteriormente. Si se llamase toolwindow por ejemplo pues tendríamos que indicar toolwindow, pero en nuestro caso vamos a crearlo para la ventana declarada como ventana. Le metemos -1 para que use la tarjeta gráfica que encuentre y finalmente se puede poner 0 o un flag de los siguientes wiki.libsdl.org/SDL_RendererFlags .
SDL_LoadBMP Utilizamos la función para cargar el mapa de bits imagen.bmp que se encuentra en el directorio res/imagen.bmp al puntero de tipo surface.
SDL_CreateTextureFromSurface Esta función la usaremos para crear una textura desde una surface existente. La textura estará en Vídeo RAM y será memoria para acceder desde la GPU (la tarjeta gráfica). La textura contiene la información de render (el contexto de representación) y el mapa de bits que habíamos cargado como surface).
SDL_RenderCopy Utilizaremos esta función para copiar una parte de la textura al destino de renderizado actual. En realidad vamos a copiar toda la textura al completo aunque podríamos indicar que solo se copiase una parte (mirar wiki.libsdl.org/SDL_Rect ).
SDL_RenderPresent Mostramos o actualizamos la pantalla con la imagen renderizada.
Cuando pasen x segundos que indiquemos la ventana y todo se destruirá. No es lo ideal ni lo normal.
Lo normal será gestionar eventos. Eso en la próxima entrega :).
Saludos cordiales.
