Introduction.
SDL (Simple DirectMedia Layer) est
une librairie permettant d'accéder aux ressources
multimédias (clavier, souris, accélération 3D via
openGL, ...) et de réaliser des applications portables sous
différents systèmes d'exploitation (après
recompilation évidemment) comme Linux, Windows, BeOS, MacOS
Classic, MacOS X, FreeBSD, OpenBSD, BSD/OS, Solaris, IRIX, et QNX. Il
existe aussi d'autres portages mais non officiels pour Windows CE,
AmigaOS, Dreamcast, Atari, NetBSD, AIX, OSF/Tru64, RISC OS, et
SymbianOS. Tous les renseignements sont disponibles à l'adresse
suivante :
http://www.libsd.org/.
Pour compiler un programme utilisant la librairie SDL sous linux, on
utilise la commande :
gcc
`sdl-config --libs --cflags` monprog.c -o monprog
Qui va ainsi utiliser les bonnes options de compilation pour gcc
(chemin des librairies, includes, ...).
Premiers
pas - Nous allons donc commencer par un premier exemple :
/* ----------
sdl1.c ---------- */
/* On inclus
ici les choses classiques mais aussi SDL.h */
/* Qui
contient tous les "headers" des fonctions SDL, */
/* ainsi que
les différents types
d'objets
*/
#include
<stdlib.h>
#include
<SDL.h>
int main( int
argc, char *argv[ ] ) {
/*
Creation d'un objet SDL */
SDL_Surface *screen;
/*
Initialisation de la video */
if(SDL_Init(SDL_INIT_VIDEO)==-1) {
fprintf(stderr,"Erreur SDL_Init() : %s\n",SDL_GetError());
exit(1);
}
/* Si
l'utilisateur quitte */
atexit(SDL_Quit);
/*
Notre objet d'affichage est en fait une fenetre de l'ecran */
if((screen = SDL_SetVideoMode(800,600,32,SDL_HWSURFACE))==NULL) {
fprintf(stderr,"Erreur SDL_SetVideoMode() : %s\n",SDL_GetError());
exit(1);
}
/*
Titre de fenetre */
SDL_WM_SetCaption("Application SDL",NULL);
/*
Autres fonctions */
/* On
attend 3 secondes */
SDL_Delay(3000);
exit(0);
}
SDL_init
: permet d'initialiser le media video, les parametres possibles sont
SDL_INIT_AUDIO, SDL_INIT_VIDEO, SDL_INIT_CDROM et SDL_INIT_TIMER. On
peut initialiser plusieurs média en meme temps en utilisant un
"|", exemple SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO);
SDL_SetVideoMode
: permet de créer une zone d'affichage sur l'ecran en utlisant
une fenetre, les parametres donnent la taille en largeur, en hauteur
(on utilise en general des tailles classiques comme 640x480, 800x600,
1024x768, ...), le nombre de bits par pixel pour la couleur, et
d'éventuels options (flags), ici
SDL_HWSURFACE.
Si l'on veut
travailler en plein ecran, on utilisera par exemple
SDL_FULLSCREEN.
On
peut combiner les options (flags) avec le caractère '|', par
exemple :
SDL_FULLSCREEN|SDL_HWSURFACE.
SDL_WM_SetCaption("Application
SDL",NULL) permet de donner un titre à la fenetre.
SDL_Delay(3000)
permet ensuite une attente de 3 secondes.
Exercice 1
:
Tapez et compilez ce programme.
Pour remplir une partie d'une surface d'une couleur on utilise la
fonction :
SDL_FillRect(surface,
rectangle_concerné,
couleur);
La surface est du type SDL_Surface, le rectangle est un type SDL_Rect
SDL_Rect (contenant 4 variables x, y , w et h renseignant sur la
position x et y du rectangle et la taille w et h) ou NULL pour la
surface totale, la couleur est du type Uint32. Pour
obtenir le code d'une couleur spécifique en fonction des
composantes
RGB, on peut utiliser la fonction :
SDL_MapRGB(surface->format,
R, G, B);
Exercice 2
:
Modifiez votre programme pour afficher un rectangle de fond d'ecran
d'une certaine couleur.
Attention : Pour préciser à SDL de mettre à jour
l'écran il faut faire un appel a
SDL_UpdateRect(screen,0,0,0,0);
Les images
Pour charger une image on utilisera la fonction
SDL_LoadBMP(),
qui
prend en unique parametre le nom de l'image BMP (avec le chemin
eventuel), et nous renvoi un objet de type SDL_Surface, que nous avons
vu precedemment. Une fois l'image chargee, il faudra la copier (blit)
sur l'ecran par l'appel a la fonction
SDL_BlitSurface(),
puis
rafraichir l'ecran par un appel a
SDL_UpdateRect().
Enfin, nous
pourrons liberer l'espace memoire reserve a l'image en utilisant la
fonction
SDL_FreeSurface().
...
SDL_Surface *screen,*image;
...
/*
Autres fonctions */
/* On
charge notre image image.bmp */
if((image=SDL_LoadBMP("image.bmp"))==NULL) {
fprintf(stderr,"Erreur SDL_LoadBMP() : %s\n",SDL_GetError());
exit(1);
}
/* On
copie par defaut toute l'image a l'ecran en position 0,0 */
SDL_BlitSurface(image,NULL,screen,NULL);
/* On
libere l'espace reserve a l'image */
SDL_FreeSurface(image);
/* On
rafraichit l'ecran */
SDL_UpdateRect(screen,0,0,0,0);
...
Exercice 3
:
Modifiez votre programme pour qu'il affiche l'image :
image.bmp.
En ce qui concerne les arguments 2 et 4 de
SDL_BlitSurface(),
il s'agit
de rectangles de type
SDL_Rect
qui permettent respectivement de
préciser la zone source et la zone de destination. On aurait pu
avoir dans le programme :
...
SDL_Rect rectsrc,rectdst;
...
rectsrc.x=30;
rectsrc.y=20;
rectsrc.w=50;
rectsrc.h=70;
rectdst.x=130;
rectdst.y=120;
SDL_BlitSurface(image,&rectsrc,screen,&rectdst);
...
Il en va de meme pour la fonction
SDL_UpdateRect(),
qui permet de
specifier la zone a rafraichir.
Exercice 4
:
Modifiez votre programme pour qu'il n'affiche qu'une portion de l'image.
Autres types d'images.
Pour pouvoir utiliser d'autres types d'images que les bmp, on peut
utiliser la librairie
SDL_image
qui n'est pas inclus par défaut,
pour cela il faut include en début de programme :
#include
<SDL_image.h>
Puis utiliser la ligne de compilation suivante pour utiliser la
librairie lors de l'édition de liens :
gcc
`sdl-config --libs --cflags` -lSDL_image monprog.c -o monprog
Et pour charger une image quelconque on utilisera pour un png (valable
pour tous les types de format) :
image=IMG_Load("image.png");
Exercice 5
:
Modifiez votre programme pour faire défiler l'image tux.png de la
gauche vers la droite. Comment supprimer la trace ?
Fonctions supplémentaires.
Pour dessiner un pixel, il n'existe pas de fonctions spécifique,
mais on utilise directement le pointeur de la surface, et plus
particulièrement la propriétée "pixels", exemple
pour afficher un point en x,y :
*((Uint32*)screen->pixels+x+y*screen->w)=SDL_MapRGB(screen->format,0,0,255);
Autres fonctions utiles :
SDL_Surface
*SDL_DisplayFormat(SDL_Surface *surface) : Qui convertit une
surface dans le format d'affichage, tres utile pour accelerer
l'affichage des images.
SDL_SetAlpha(SDL_Surface
*surface, SDL_SRCALPHA | SDL_RLEACCEL, entier) : Permet de
rendre une surface transparente, l'entier donne le degré de
transparence.
SDL_SetColorKey(SDL_Surface
*surface, Uint32 flag, Uint32 key) : Qui permet de supprimer une
couleur à l'affichage d'une surface, le flag est une combinaison
de SDL_SRCCOLORKEY et SDL_RLEACCEL.
On peut creer une surface vide avec la fonction :
new_surface=SDL_CreateRGBSurface(type_surface,largeur,hauteur,profondeur,0,0,0,0);
Le type de surface peut etre SDL_HWSURFACE ou SDL_SWSURFACE pour une
surface en mémoire video ou en mémoire classique.
ATTENTION : Il faut penser a supprimer la surface en quittant le
programme par un appel a
SDL_FreeSurface().
Exercice 6
:
Faire un programme qui fait défiler le motif tux.png sur le fond
d'ecran image.bmp, en prenant en compte évidemment
les problèmes de traces.