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:
BanderasSDL_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
→