Tutoriales de SDL 2: Lección 5 - Texturas

Hola a todos y bienvenidos a la quinta lección sobre SDL 2, en la que analizaremos las texturas, simplificando el trabajo de la computadora. Puedes encontrar todas las lecciones en inglés aquí .

En la segunda versión SDL, hay una muy buena oportunidad para crear texturas y renderizarlas. El renderizado de hardware es mucho más rápido que dibujar superficies en una ventana.

Las texturas tienen su propio tipo de datos: SDL_Texture . Cuando trabajamos con texturas, necesitamos un render para renderizar. Ahora anunciaremos todo esto.

#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Renderer *ren = NULL; SDL_Texture *flower = NULL; 

Aquí anunciamos la ventana, el render y esta flor.
También conectamos bibliotecas y establecemos tamaños de ventana.

La función Init también tendrá que cambiarse.

  bool ok = true; if (SDL_Init(SDL_INIT_VIDEO) != 0) { cout << "Can't init: " << SDL_GetError() << endl; ok = false; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { cout << "Can't create window: " << SDL_GetError() << endl; ok = false; } 

Primero, cree la variable ok , para no finalizar la función inmediatamente, sino para encontrar todos los errores durante la inicialización. A continuación, inicialice el SDL y cree una ventana de manera conocida.

Es hora de declarar un render.

  ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { cout << "Can't create renderer: " << SDL_GetError() << endl; ok = false; } SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF); 

El renderizado es declarado por la función SDL_CreateRenderer . Se necesitan 3 valores: una ventana para la que se utilizará este render, un índice de controlador (o -1 si queremos encontrar el primero adecuado) y banderas. Usé las banderas SDL_RENDERER_ACCELERATED y SDL_RENDERER_PRESENTVSYNC . Aquí hay una lista de todas las banderas:

Banderas
SDL_RENDERER_SOFTWARE : reserva para;
SDL_RENDERER_ACCELERATED - uso de aceleración de hardware;
SDL_RENDERER_PRESENTVSYNC - sincronización vertical;
SDL_RENDERER_TARGETTEXTURE : soporte para renderizar a textura.

A continuación, usamos la función SDL_SetRenderDrawColor , que establece el color para dibujar primitivas.

Después de eso, inicialice el IMG y regrese ok .

  int flags = IMG_INIT_PNG; if (!(IMG_Init(flags) & flags)) { cout << "Can't init image: " << IMG_GetError() << endl; ok = false; } return ok; } 

Ahora escribimos la función de carga .

 bool load() { bool ok = true; SDL_Surface * temp_surf = NULL; temp_surf = IMG_Load("flower.png"); if (temp_surf == NULL) { cout << "Can't load image: " << IMG_GetError() << endl; ok = false; } 

Aquí también creamos la variable ok , para las mismas necesidades. Crearon una superficie temporal y cargaron imágenes de flores en ella.

Luego necesitamos hacer una textura desde la superficie.

  flower = SDL_CreateTextureFromSurface(ren, temp_surf); if (flower == NULL) { cout << "Can't create texture from surface: " << SDL_GetError() << endl; ok = false; } 

La función SDL_CreateTextureFromSurface nos ayudará a crear la textura. Toma valores de renderizado y superficie. Devuelve una instancia de la clase SDL_Texture .

Para no obstruir la memoria, necesitamos limpiar la superficie temporal. Después de eso, regrese ok y la función está lista.

La función Salir ha tomado algunas acciones más.

 void quit() { SDL_DestroyWindow(win); win = NULL; SDL_DestroyRenderer(ren); ren = NULL; SDL_DestroyTexture(flower); flower = NULL; SDL_Quit(); IMG_Quit(); } 

Aquí eliminamos la ventana, el renderizado, la textura y dejamos SDL e IMG . También configuré todos los objetos eliminados en NULL para una limpieza de memoria aún mejor.

Comenzamos a escribir la función principal .

 int main (int argc, char ** argv) { if (!init()) { quit(); return 1; } if (!load()) { quit(); return 1; } 

Escribimos inicialización y carga, no nos detenemos aquí.

El siguiente paso es crear 2 variables.

  bool run = true; SDL_Event e; 

Este programa tendrá un ciclo principal para actualizar la memoria, así que comencemos a desescribirlo.

 while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } } 

Procesó el evento de presionar la cruz y eso es todo.

Es hora de dibujar. Al usar texturas y renderizado, se utilizan diferentes funciones para renderizar de las que conocemos. Para borrar la pantalla de texturas dibujadas, se utiliza la función SDL_RenderClear . Pinta la pantalla con el color que especificamos con la función SDL_SetRenderDrawColor . La función SDL_RenderCopy se usa para representar la textura, y SDL_RenderPresent se usa para actualizar la pantalla. Los escribiremos ahora.

  SDL_RenderClear(ren); SDL_RenderCopy(ren, flower, NULL, NULL); SDL_RenderPresent(ren); } 

Analizaremos solo la función SDL_RenderCopy . Se necesitan 4 significados. El primero es un renderizado, el segundo es una textura, el tercero es un rectángulo cuya área queremos recortar para renderizar, el cuarto es un rectángulo cuyas coordenadas se usan para renderizar, y el ancho y la altura son para cambiar el tamaño de la textura.

Luego, llame a la función Salir y devuelva 0 .

  quit(); return 0; } 

Sobre esto terminaré la lección, si algo no estaba claro, escribe y me despido, ¡adiós por ahora!

Por cierto, aquí está el código completo:

 #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Renderer *ren = NULL; SDL_Texture *flower = NULL; bool init() { bool ok = true; if (SDL_Init(SDL_INIT_VIDEO) != 0) { cout << "Can't init: " << SDL_GetError() << endl; ok = false; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { cout << "Can't create window: " << SDL_GetError() << endl; ok = false; } ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { cout << "Can't create renderer: " << SDL_GetError() << endl; ok = false; } SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF); int flags = IMG_INIT_PNG; if (!(IMG_Init(flags) & flags)) { cout << "Can't init image: " << IMG_GetError() << endl; ok = false; } return ok; } bool load() { bool ok = true; SDL_Surface * temp_surf = NULL; temp_surf = IMG_Load("flower.png"); if (temp_surf == NULL) { cout << "Can't load image: " << IMG_GetError() << endl; ok = false; } flower = SDL_CreateTextureFromSurface(ren, temp_surf); if (flower == NULL) { cout << "Can't create texture from surface: " << SDL_GetError() << endl; ok = false; } SDL_FreeSurface(temp_surf); return ok; } void quit() { SDL_DestroyWindow(win); win = NULL; SDL_DestroyRenderer(ren); ren = NULL; SDL_DestroyTexture(flower); flower = NULL; SDL_Quit(); IMG_Quit(); } int main (int argc, char ** argv) { if (!init()) { quit(); return 1; } if (!load()) { quit(); return 1; } bool run = true; SDL_Event e; while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } } SDL_RenderClear(ren); SDL_RenderCopy(ren, flower, NULL, NULL); SDL_RenderPresent(ren); } quit(); return 0; } 

Lección anterior | Próxima lección

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


All Articles