Bonjour à tous! Il s'agit de la quatrième leçon de SDL 2. J'ai décidé de combiner les deux leçons en une seule, car dans l'original, elles sont petites. Mais ils peuvent être trouvés
ici et
ici . Eh bien, commençons la leçon.
Premièrement, nous déciderons de ce que nous ferons. Aujourd'hui, nous allons apprendre à télécharger des images d'une autre extension (pas BMP), à savoir: PNG. Refaites l'image dans un format différent pour accélérer le travail et redimensionner l'image. Nous allons travailler avec cette image:
L'installation
Donc, nous apprenons d'abord comment télécharger le PNG. Dans le jeu de fonctionnalités SDL 2 standard, il n'y a pas de téléchargement d'une image au format non BMP. Pour télécharger un format différent, vous devez installer l'extension.
Voici les instructions:
WindowsVous accédez à cette
page et téléchargez les archives ZIP ou TAR.GZ à partir de la section
Bibliothèques de développement . Décompressez-les et jetez-les dans le dossier avec le compilateur.
LinuxSi votre système utilise Debian, vous devez entrer ces commandes:
apt-cache search libsdl2-image apt-get install libsdl2-image-dev
Si Yellowdog Updater, Modified est utilisé, vous entrez ces commandes:
yum search SDL2_image-devel yum SDL2_image-devel
Mac OSTéléchargez le fichier DMG et lisez le fichier Lisez-moi.
Écrire un code
Après avoir défini
SDL_image, nous commençons à écrire du code. Tout d'abord, comme toujours, nous allons connecter les bibliothèques, définir les tailles de fenêtre et créer 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;
Notez que j'ai connecté
SDL_image.h séparément, car il s'agit d'une bibliothèque distincte.
Ensuite, nous écrivons 3 fonctions, connues de nous, dans lesquelles nous allons ajouter et changer quelque chose, comme d'habitude.
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; }
Ici, nous avons ajouté l'initialisation du module SDL_image. Pour l'initialiser, créez d'abord une variable
int , nous avons des
drapeaux , et enregistrez-y tous les drapeaux que vous souhaitez utiliser pour l'initialisation.
Liste de tous les drapeauxSDL_INIT_PNG - initialise le téléchargeur d'images PNG;
SDL_INIT_JPG - initialise le téléchargeur d'images JPG;
SDL_INIT_TIF - initialise le téléchargeur d'images TIF;
Ensuite, nous écrivons cette condition:
if ( !( IMG_Init( flags ) & flags ) )
La fonction
IMG_Init () renvoie les indicateurs qu'elle a pu initialiser. Si elle a rendu les drapeaux, mais que celui que nous voulions manquait, nous renvoyons une erreur. Très simple. Notez également que j'utilise
IMG_GetError au lieu de
SDL_GetError , car nous recherchons une erreur dans la fonction du module
SDL_image , pas
SDL .
Je veux également noter que j'ai décidé d'utiliser le type
bool pour
renvoyer un - c'est une manière plus rationnelle.
Continuons à écrire notre programme, écrivons la fonction
Load () , dans laquelle nous chargeons une image PNG et la convertissons.
Charge 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; }
Ici, nous téléchargeons l'image avec la nouvelle fonction
IMG_Load .
Sa fonction est la même que celle de
SDL_LoadBMP et le résultat est le même - il renvoie une instance de la classe
SDL_Surface . Pour trouver des erreurs lors du chargement, nous utilisons également
IMG_GetError .
Il est temps de se convertir. Tout d'abord, un peu de théorie. Peu de gens le savent, mais lors du téléchargement d'une image, elle est téléchargée au format 24 bits, et la plupart des écrans modernes sont au format 32 bits. Et chaque fois que nous affichions l'image à l'écran, elle était d'abord refaite au format 32 bits. Pour les programmes simples, cela n'a pas d'importance, mais lors de la création d'une sorte de grand projet, cela affectera considérablement les performances, nous prendrons donc et au stade du chargement des images, nous les recréerons au format d'affichage. La fonction
SDL_ConvertSurface vous aidera. Il prend 3 valeurs: la surface que nous voulons formater, le format dans lequel nous voulons formater et les drapeaux. nous voulons formater l'image de la
fleur , lui passer le premier paramètre. Le deuxième paramètre est le format de la surface de la fenêtre, nous n'utiliserons pas de drapeaux. Cette fonction renvoie une copie de la surface, que nous affectons immédiatement à
flower . Pour rechercher des erreurs, nous prenons la fonction
SDL_GetError () ,
car nous travaillons déjà avec des surfaces, et elles proviennent de
SDL , et non de
SDL_image .
Ensuite, nous écrivons la fonction Quit, y ajoutons une seule fonction.
Quitter void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); }
Nous avons ajouté
IMG_Quit pour non initialiser le module SDL_image.
Principal
Maintenant, la chose la plus simple reste - la fonction
principale .
int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; }
Pour commencer, initialisez et créez tout ce dont vous avez besoin et téléchargez les fichiers nécessaires. Nous ne nous arrêterons pas ici.
SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0;
Après cela, créez un objet de classe
SDL_Rect . Nous en aurons besoin pour étirer l'image. Si vous remarquez, l'image de la fleur est 4 fois plus petite que la taille de la fenêtre (2 fois plus mince et 2 fois plus basse), et nous devons l'étirer à la taille de la fenêtre. Donc, dans la largeur du rectangle
bg_flower, écrivez la valeur de la largeur de la fenêtre, et en hauteur - la hauteur de la fenêtre. définissez les coordonnées sur 0, de sorte que l'image s'affiche dans le coin supérieur gauche.
Pour afficher des images avec redimensionné, il existe une fonction spéciale. Cela ressemble à ceci:
SDL_BlitScaled(flower, NULL, scr, &bg_flower);
Cela prend 4 significations. La première est l'image que nous voulons afficher, la seconde est le rectangle que nous voulons couper de cette image (si nous voulons prendre l'image entière, nous écrivons NULL), la troisième est la surface sur laquelle nous voulons afficher l'image, et la quatrième est le même rectangle, dimensions et les coordonnées dont nous prenons pour étirer ou compresser et afficher l'image.
Ensuite, mettez simplement à jour la surface de l'écran, définissez le délai, quittez et retournez 0.
SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
C'est là que notre programme se termine. Afin de compiler ce miracle, vous devez ajouter -lSDL2_image, comme une autre option de compilation.
Et là-dessus, nous terminerons pour aujourd'hui. Voici le code que nous avons obtenu:
#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; };
Salut tout le monde!
<< Leçon précédente || Prochaine leçon
>>