Tutoriels SDL 2: Leçon 5 - Textures

Bonjour à tous et bienvenue à la cinquième leçon sur SDL 2, dans laquelle nous analyserons les textures, simplifiant le travail de l'ordinateur. Vous pouvez trouver toutes les leçons en anglais ici .

Dans la deuxième version SDL, il existe une très bonne opportunité de créer des textures et de les rendre. Le rendu matériel est beaucoup plus rapide que le dessin de surfaces dans une fenêtre.

Les textures ont leur propre type de données - SDL_Texture . Lorsque vous travaillez avec des textures, nous avons besoin d'un rendu pour le rendu. Nous allons maintenant annoncer tout cela.

#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; 

Ici, nous avons annoncé la fenêtre, le rendu et cette fleur.
Nous avons également connecté des bibliothèques et défini des tailles de fenêtres.

La fonction Init devra également être modifiée.

  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; } 

Créez d'abord la variable ok , afin de ne pas terminer la fonction immédiatement, mais de trouver toutes les erreurs lors de l'initialisation. Ensuite, initialisez le SDL et créez une fenêtre de manière connue.

Il est temps de déclarer un rendu.

  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); 

Le rendu est déclaré par la fonction SDL_CreateRenderer . Il prend 3 valeurs: une fenêtre pour laquelle ce rendu sera utilisé, un index du pilote (ou -1 si nous voulons trouver le premier approprié) et des drapeaux. J'ai utilisé les indicateurs SDL_RENDERER_ACCELERATED et SDL_RENDERER_PRESENTVSYNC . Voici une liste de tous les drapeaux:

Drapeaux
SDL_RENDERER_SOFTWARE - solution de remplacement pour;
SDL_RENDERER_ACCELERATED - utilisation de l'accélération matérielle;
SDL_RENDERER_PRESENTVSYNC - synchronisation verticale;
SDL_RENDERER_TARGETTEXTURE - prise en charge du rendu en texture.

Ensuite, nous utilisons la fonction SDL_SetRenderDrawColor , qui définit la couleur des primitives de dessin.

Après cela, initialisez l' IMG et revenez ok .

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

Nous écrivons maintenant la fonction Load .

 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; } 

Ici, nous avons également créé la variable ok , pour les mêmes besoins. Ils ont créé une surface temporaire et y ont chargé des images de fleurs.

Ensuite, nous devons créer une texture à partir de la surface.

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

La fonction SDL_CreateTextureFromSurface nous aidera à créer la texture. Il prend des valeurs de rendu et de surface. Il renvoie une instance de la classe SDL_Texture .

Afin de ne pas obstruer la mémoire, nous devons nettoyer la surface temporaire. Après cela, revenez ok et la fonction est prête.

La fonction Quitter a effectué quelques actions supplémentaires.

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

Ici, nous avons supprimé la fenêtre, le rendu, la texture et laissé SDL et IMG . J'ai également défini tous les objets supprimés sur NULL pour un nettoyage de la mémoire encore meilleur.

Nous commençons à écrire la fonction Main .

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

Nous avons écrit l'initialisation et le chargement, nous ne nous arrêtons pas là.

L'étape suivante consiste à créer 2 variables.

  bool run = true; SDL_Event e; 

Ce programme aura un cycle principal pour rafraîchir la mémoire, alors commençons à le désécrire.

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

Traité l'événement d'appuyer sur la croix et c'est tout.

Il est temps de dessiner. Lors de l'utilisation des textures et du rendu, différentes fonctions sont utilisées pour le rendu par rapport à celles que nous connaissons. Afin d'effacer l'écran des textures dessinées, la fonction SDL_RenderClear est utilisée . Il peint l'écran avec la couleur que nous avons spécifiée avec la fonction SDL_SetRenderDrawColor . La fonction SDL_RenderCopy est utilisée pour rendre la texture, et SDL_RenderPresent est utilisée pour mettre à jour l'écran. Nous allons les écrire maintenant.

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

Nous analyserons uniquement la fonction SDL_RenderCopy . Cela prend 4 significations. Le premier est un rendu, le second est une texture, le troisième est un rectangle dont nous voulons découper la zone pour le rendu, le quatrième est un rectangle dont les coordonnées sont utilisées pour le rendu, et la largeur et la hauteur sont pour le redimensionnement de la texture.

Ensuite, appelez la fonction Quitter et retournez 0 .

  quit(); return 0; } 

Sur ce, je terminerai la leçon, si quelque chose n'était pas clair - écrivez, et je dis au revoir, au revoir pour l'instant!

Au fait, voici le code complet:

 #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; } 

Leçon précédente | Leçon suivante

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


All Articles