Lecciones sobre SDL 2: Lecci贸n 4 - Estirando PNG

Hola a todos! Esta es la cuarta lecci贸n en SDL 2. Decid铆 combinar las dos lecciones en una sola, ya que en el original son peque帽as. Pero se pueden encontrar aqu铆 y aqu铆 . Bueno, comencemos la lecci贸n.

Primero, decidiremos qu茅 haremos. Hoy aprenderemos c贸mo cargar im谩genes de otra extensi贸n (no BMP), a saber: PNG. Vuelva a hacer la imagen en un formato diferente para acelerar el trabajo y cambiar el tama帽o de la imagen. Trabajaremos con esta imagen:

imagen

Instalaci贸n


Entonces, primero aprendemos c贸mo descargar PNG. El conjunto de caracter铆sticas est谩ndar de SDL 2 no carga im谩genes que no sean de formato BMP. Para descargar un formato diferente, debe instalar la extensi贸n.

Aqu铆 est谩n las instrucciones:

Ventanas
Vaya a esta p谩gina y descargue los archivos ZIP o TAR.GZ de la secci贸n Bibliotecas de desarrollo . Desempaquete y t铆relos a la carpeta con el compilador.

Linux
Si su sistema usa Debian, entonces necesita ingresar estos comandos:

apt-cache search libsdl2-image apt-get install libsdl2-image-dev 

Si se utiliza Yellowdog Updater, Modified, entonces ingresa estos comandos:

 yum search SDL2_image-devel yum  SDL2_image-devel 


Mac OS
Descargue el archivo DMG y lea el archivo L茅ame.

Escribir un c贸digo


Despu茅s de configurar SDL_image, comenzamos a escribir c贸digo. Primero, como siempre, conectaremos las bibliotecas, estableceremos los tama帽os de las ventanas y crearemos 3 variables globales.

 #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL; 

Tenga en cuenta que conect茅 SDL_image.h por separado, ya que es una biblioteca separada.

A continuaci贸n, escribimos 3 funciones, conocidas por nosotros, en las que agregaremos y cambiaremos algo, como de costumbre.

Init ()
 bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; } 


Aqu铆 agregamos la inicializaci贸n del m贸dulo SDL_image. Para inicializarlo, primero creamos una variable int , tenemos banderas y guardamos all铆 todas las banderas que desea usar para la inicializaci贸n.

Lista de todas las banderas
SDL_INIT_PNG : inicializa el descargador de im谩genes PNG;
SDL_INIT_JPG : inicializa el descargador de im谩genes JPG;
SDL_INIT_TIF : inicializa el descargador de im谩genes TIF;

A continuaci贸n, escribimos esta condici贸n:

 if ( !( IMG_Init( flags ) & flags ) ) 

La funci贸n IMG_Init () devuelve los indicadores que pudo inicializar. Si ella devolvi贸 las banderas, pero faltaba la que quer铆amos, devolvemos un error. Muy simple Adem谩s, tenga en cuenta que uso IMG_GetError en lugar de SDL_GetError , ya que estamos buscando un error en la funci贸n del m贸dulo SDL_image , no SDL .

Tambi茅n quiero se帽alar que decid铆 usar el tipo bool para devolver a - esta es una forma m谩s racional.

Continuemos escribiendo nuestro programa, escribamos la funci贸n Load () , en la que cargamos una imagen PNG y la convertimos.

Carga
 bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; } 


Aqu铆 cargamos la imagen con la nueva funci贸n IMG_Load . Su funci贸n es la misma que la de SDL_LoadBMP y el resultado es el mismo: devuelve una instancia de la clase SDL_Surface . Para encontrar errores durante la carga, tambi茅n utilizamos IMG_GetError .

Es hora de convertir. Primero, una peque帽a teor铆a. Pocas personas lo saben, pero al descargar una imagen, se descarga en formato de 24 bits, y la mayor铆a de las pantallas modernas est谩n en formato de 32 bits. Y cada vez que mostramos la imagen en la pantalla, primero se rehizo en formato de 32 bits. Para programas simples, esto no importa, pero al crear alg煤n tipo de proyecto grande, afectar谩 en gran medida el rendimiento, por lo que tomaremos y en la etapa de carga de im谩genes las rehaceremos en el formato de visualizaci贸n. La funci贸n SDL_ConvertSurface ayudar谩. Toma 3 valores: la superficie que queremos formatear, el formato en el que queremos formatear y las banderas. queremos formatear la imagen de la flor , pasarle el primer par谩metro. El segundo par谩metro es el formato de la superficie de la ventana, no utilizaremos banderas. Esta funci贸n devuelve una copia de la superficie, que asignamos inmediatamente a flower . Para encontrar errores, tomamos la funci贸n SDL_GetError () , porque ya estamos trabajando con superficies, y son de SDL , y no de SDL_image .

A continuaci贸n, escribimos la funci贸n Salir, agregamos solo una funci贸n.

Salir
 void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); } 


Agregamos IMG_Quit para no inicializar el m贸dulo SDL_image.

Principal


Ahora queda lo m谩s simple: la funci贸n principal .

 int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; } 

Para comenzar, inicialice y cree todo lo que necesita y cargue los archivos necesarios. No nos detendremos aqu铆.

  SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0; 

Despu茅s de eso, cree un objeto de la clase SDL_Rect . Lo necesitaremos para estirar la imagen. Si observa, la imagen de la flor es 4 veces m谩s peque帽a que la ventana (2 veces m谩s delgada y 2 veces m谩s baja), y debemos estirarla hasta la ventana. Entonces, en el ancho del rect谩ngulo bg_flower, escriba el valor del ancho de la ventana, y en altura, la altura de la ventana. establezca las coordenadas en 0, de modo que la imagen se muestre en la esquina superior izquierda.

Para mostrar im谩genes con cambio de tama帽o, hay una funci贸n especial. Se ve as铆:

  SDL_BlitScaled(flower, NULL, scr, &bg_flower); 

Se necesitan 4 significados. El primero es la imagen que queremos mostrar, el segundo es el Rect谩ngulo que queremos cortar de esta imagen (si queremos tomar la imagen completa, escribimos NULL), el tercero es la superficie en la que queremos mostrar la imagen, y el cuarto es el mismo rect谩ngulo, dimensiones y las coordenadas de las cuales tomamos para estirar o comprimir y mostrar la imagen.

A continuaci贸n, solo actualice la superficie de la pantalla, configure el retraso, salga y regrese 0.

  SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; }; 

Aqu铆 es donde termina nuestro programa. Para compilar este milagro, debe agregar -lSDL2_image, como otra opci贸n de compilaci贸n.

Y en esto terminaremos por hoy. Aqu铆 est谩 el c贸digo que obtuvimos:

 #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL; bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; } bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; } void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); } int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; } SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0; SDL_BlitScaled(flower, NULL, scr, &bg_flower); SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; }; 

隆Adi贸s a todos!

<< Lecci贸n anterior || Pr贸xima lecci贸n >>

Source: https://habr.com/ru/post/456656/


All Articles