SDL en C bajo GNU/Linux 003 – Mostrando una imagen

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 la 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/

  
https://mierda.tv/wp-content/uploads/2017/05/imagen.bmp
  
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 https://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 https://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.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *