Programmation en C/SDL2
Sommaire:- Bibliothèque SDL - Fixer une couleur de fond
- Placer une image à un endroit particulier de la fenêtre
- Capturer une portion d'une image et afficher plusieurs fois cette portion à l'écran
Bibliothèque SDL - Fixer une couleur de fond
Description
Nous allons fixer une couleur de fond à notre fenêtre. Pour cela nous utilisons les fonctions SDL_SetRenderDrawColor() et SDL_RenderClear().
La fonction SDL_SetRenderDrawColor() prend quatre paramètres, son prototype est le suivant :int SDL_SetRenderDrawColor(SDL_Renderer* renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Le premier paramètre sera notre objet renderer. Les trois paramètres suivants correspondent à la couleur de fond de type RGB (rouge/vert/bleu). Ils sont codés sur 8bits, et peuvent donc prendre des valeurs allant de 0 à 255 (0 pour une couleur peu prononcée). Le dernier paramètre correspond à l'alpha blending (effet de transparence) et nous le fixerons à 255 pour avoir une opacité totale.L'exemple suivant affichera par exemple une couleur rouge opaque :
int SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
Et l'exemple suivant une couleur vert opaque :
int SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
Dans l'exemple de code ci-desssous nous allons fixer un fond blanc opaque :
int SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
Une fois que nous aurons fixé la couleur voulue, nous devrons faire appel à la fonction SDL_RenderClear().
Code source
render.c
/* * Compilation: * gcc render.c -o render -lSDL2 */ #include <stdio.h> #include <SDL2/SDL.h> int main(int argc, char *argv[]) { SDL_Window *window; SDL_Renderer *renderer; SDL_Event event; int quit=0; if (SDL_VideoInit(NULL) < 0) { SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video: %s\n", SDL_GetError()); exit(1); } window = SDL_CreateWindow("Fenetre", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); while ( !quit ) { if ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_QUIT: quit=1; break; }//end switch event.type }//end if PollEvent }//end while quit SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); exit(0); }//end main
Résultat obtenu
On obtient alors la fenêtre suivante :

Placer une image à un endroit particulier de la fenêtre
Description
Nous allons déclarer une variable position de type SDL_Rect. SDL_Rect est une structure contenant quatre variables de type int. Ces variables correspondent à la position (x et y) et à la taille (w et h) de notre rectangle.
Nous allons utiliser l'image suivante (sol.bmp): . Cette image a une taille de
32 pixels en hauteur et de 64 pixels en largeur. Nous allons nous contenter dans un premier temps
d'afficher cette image dans sa totalité, en haut à gauche de la fenêtre.
La déclaration de la variable se fait de la manière suivante:
SDL_Rect position;
L'origine d'une fenêtre SDL commence en haut à gauche. L'axe des abscisses (variable x) est orienté positivement vers la droite et l'axe des ordonnées (variable y) est orienté positivement vers le bas. Autrement dit, en allant vers la droite la variable x augmente et en allant vers le bas la variable y augmente.
Pour positionner l'image en haut à gauche on utilisera donc:
position.x=0;
etposition.y=0;
Comme on veut créer un rectangle de la taille de notre image on prendra :
position.h=32;
etposition.w=64;
(h=height et w=width)On fixe la position de l'image lors de la copie du sprite dans le moteur de rendu, c'est-à dire lors de l'appel de la fonction SDL_RenderCopy()
Cette position correspond au quatrième arguments de la fonction (on laissera encore le troisième argument à NULL pour l'instant).
SDL_RenderCopy(renderer, texture, NULL, &position);
On notera qu'il faut passer l'adresse de la position en utilisant l'opérateur &.
Code source
sprite1.c
/* * Compilation et execution : * gcc sprite1.c -o sprite1 -lSDL2 && ./sprite1 */ #include <stdio.h> #include <SDL2/SDL.h> int main(int argc, char *argv[]) { SDL_Window *window; SDL_Renderer *renderer; SDL_Surface *sprite; SDL_Texture *texture; SDL_Rect position; SDL_Event event; int quit=0; if (SDL_VideoInit(NULL) < 0) { SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video: %s\n", SDL_GetError()); exit(1); } window = SDL_CreateWindow("Fenetre", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); sprite = SDL_LoadBMP("decor.bmp"); texture = SDL_CreateTextureFromSurface(renderer, sprite); position.x = 0; position.y = 0; position.w = 64; position.h = 32; //On copie le sprite SDL_RenderCopy(renderer, texture, NULL, &position); //On affiche SDL_RenderPresent(renderer); while ( !quit ) { if ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_QUIT: quit=1; break; }//end switch event.type }//end if PollEvent }//end while quit SDL_DestroyTexture(texture); SDL_FreeSurface(sprite); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); exit(0); }//end main
Résultat obtenu

Pour placer l'image à une position différente, on changera les valeurs de x et y de cette manière par exemple :
position.x=64;
etposition.y=64;
On obtiendrait alors la fenêtre suivante :

Remplir la fenêtre en répétant un motif d'une portion de l'image
Description
Cette fois-ci, nous allons prendre un motif de notre image et nous allons répéter ce motif afin de remplir tout l'écran. Dans l'exemple suivant nous choisirons la deuxième portion de l'image.C'est-à-dire que sur cette image nous sélectionnerons cette partie
Pour cela nous allons créer une deuxième variable de type SDL_Rect que nous appellerons Src (source). Cette variable contiendra la position et la taille de la portion de l'image que nous capturerons.
Code source
/* Compilation et execution: gcc sprite2.c -o sprite2 -lSDL2 && ./sprite2 */ #include <stdio.h> #include <SDL2/SDL.h> int main(int argc, char *argv[]) { SDL_Window *window; SDL_Renderer *renderer; SDL_Surface *sprite; SDL_Texture *texture; SDL_Rect Src; SDL_Rect Dest; SDL_Event event; int quit=0; if (SDL_VideoInit(NULL) < 0) { SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video: %s\n", SDL_GetError()); exit(1); } window = SDL_CreateWindow( "Fenetre", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); sprite = SDL_LoadBMP("decor.bmp"); /* * Si l'image n'existe pas le resultat prend la valeur NULL */ if (sprite!=NULL) { printf("Chargement de l'image\n"); } else { printf("Probleme dans le chargement de l'image\n"); } texture = SDL_CreateTextureFromSurface(renderer, sprite); /* La source permet de choisir la portion de l'image que l'on veut copier. Ici on choisit de copier une portion de 32x32 comme x=32 on ne copiera que la deuxieme portion de l'image (puisque celle-ci fait 64x32) Si on voulait copier la premiere on choisirait Src.x=0 (faire le test pour s'en rendre compte) */ Src.w=32; Src.h=32; Src.x=32; Src.y=0; /* En general, pour la destination on prendra en width et height la taille de l'image, ici 64x32 et on partira toujours en haut a gauche de l'ecran, x=y=0 On copiera ensuite la portion de l'image en modifiant les positions de x et y (voir la boucle ci-dessous) */ Dest.w = 64; Dest.h = 32; Dest.x = 0; Dest.y = 0; //On copie le sprite SDL_RenderCopy(renderer, texture, &Src, &Dest); // et on le copie plusieurs fois jusqu'a remplir tout l'ecran int i=0; int j=0; for (i=0; i <10;i++) { for (j=0;j<15;j++) { SDL_RenderCopy(renderer, texture, &Src, &Dest); Dest.y=Dest.y+32; } j=0; Dest.x = Dest.x + 64; Dest.y = 0; } //On affiche SDL_RenderPresent(renderer); while ( !quit ) { if ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_QUIT: quit=1; break; }//end switch event.type }//end if PollEvent }//end while quit SDL_DestroyTexture(texture); SDL_FreeSurface(sprite); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); exit(0); }//end main
Résultat obtenu

Remarque
Le fait de capturer une portion d'une image et de répéter cette portion plusieurs fois à l'écran sert de base à la théorie des tuiles. C'est ce que nous aborderons la prochaine fois.