Académique Documents
Professionnel Documents
Culture Documents
par Loka
C'est ici que dbute notre apprentissage de SDL avec la cration de nos deux premiers programmes.
II - Dbuts avec SDL II-A - Crer une fentre SDL II-B - Hello World - Blitting
-2Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Pour se familiariser avec les diffrentes fonctions que nous offrent SDL et ses extensions, nous allons procder pas pas. Pour commencer, dans le chapitre II-A, nous allons apprendre crer une fentre SDL vierge, ce qui nous apprendra initialiser SDL et quitter SDL correctement.
Ensuite, dans le chapitre II-B, nous allons apprendre charger des images sur la fentre SDL et de les appliquer les unes sur les autres, cela s'appelle le blitting
Par la suite, dans les chapitres IV (Gestion des vnements) et XV (gestion des vnements avancs), je vais tenter de vous expliquer comment marche la gestion des vnements sous SDL et ainsi que vous puissiez crer une application qui puisse ragir lorsque l'utilisateur appuie sur une touche, clique un endroit prcis, etc..
Le chapitre V quant lui vous permettra d'apprendre utiliser une fonction particulire de SDL : SDL_SetColorKey(), qui vous sera trs utile si vous souhaitez crer un jeu ou mme pour plein d'autres applications concrtes dans lesquels vous avez besoin de manipuler des images.
Nous finirons notre familiarisation de SDL avec la cration d'une feuille de sprite et son utilisation dans une application SDL (chapitre VI).
-3Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
fentre SDL
if( screen == NULL ) { printf( "Can't set video mode: %s\n", SDL_GetError( ) ); return EXIT_FAILURE; } SDL_Delay( 3000 ); return EXIT_SUCCESS; }
Dans les 2 premires lignes, on inclut le fichier d'en-tte ncessaire pour l'utilisation de la SDL (SDL.h) et la librairie stdlib.h pour l'utilisation de exit() et atexit().
Ensuite vient la fonction bien connue int main() avec ces 2 arguments obligatoire pour un programme SDL (nous y reviendrons dans le chapitre suivant).
Une ligne plus bas on peut dj trouver le premier type inconnu, SDL_Surface, qui est utilis ici pour une surface d'cran. Ensuite viens la premire fonction inconnue, elle est nomme: int SDL_Init(Uint32 flags) et est utilise pour initialiser la SDL o le paramtre flags est(sont) le(s) subsystem(s) qui doit(-vent) tre initialis(s). La combinaison de plusieurs flags est possible en introduisant des '|' entre chaque subsystem, donc peut tre de la forme : SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO), qui initialisera le subsystem de la vido et de l'audio. Les flags possibles sont:
Nous n'initialiserons que le sous-systme de la vido puisque nous n'utilisons pas encore d'autres fonctions que celle de la vido. Pour ceux qui utilisent tous les sous-systmes peuvent par contre simplement dclarer SDL_INIT_EVERYTHING qui les initialisent tous.
-4Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Pour les curieux la SDL donne galement la possibilit d'utiliser la fonction int SDL_InitSubSystem(Uint32 flags) qui est peut tre trs utile lorsque vous ne voulez pas initialiser un subsystem que lorsque celui-ci est choisi en option, ou bien que vous ne l'utilisez que plus tard dans le programme.
Un bon exemple pour a est par exemple le joystick, car on sait rarement ds le dbut du jeu que l'utilisateur veut utiliser son joystick (s'il en possde un). Donc on place cela dans les options et si l'utilisateur dcide de l'utiliser, le sous-systme sera initialis.
Pour fermer les sous-systmes il faut utiliser int SDL_Quit( ) qui ferme tous les sous-systmes initialiss, mais si vous ne voulez en fermer qu'un seul vous pouvez utiliser void SDL_QuitSubSystem(Uint32 flags). Il est tout de mme possible que l'initialisation retourne -1 et donc rate, c'est pour cela que nous faisons un test. Quand cela se passe, on met un message dans la console d'erreur de la SDL, avec SDL_GetError() qui retourne l'erreur qui s'est produite. Dans le cas o il y a une erreur, nous terminons le programme en retournant 1
Si aucune erreur n'est intervenue, on appelle la fonction atexit() avec en paramtre SDL_Quit, ce qui veut dire que quand le programme est termin il doit utiliser SDL_Quit. Puisque l'initialisation s'est bien passe et que tout notre programme se trouve en mmoire, avec SDL_Quit on libre tout lors de l'arrt du programme.
Maintenant, donnons le paramtrage vido avec la fonction SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) qui prend comme paramtres la largeur de l'cran, sa hauteur, son nombre de bits par pixel et les flags. Les trois premiers devraient normalement tre bien connus, tandis que le quatrime est tout nouveau, puisqu'il n'accepte pas du tout les mmes flags que SDL_Init. Ne nous attardons pas trop l-dessus pour l'instant.
Comme vous avez pu le constater dans le prototype de la fonction SDL_SetVideoMode, celle-ci retourne un pointeur qui pointe vers l'adresse de la plate-forme vido. C'est d'ailleurs pour cela que nous avons mis notre pointeur screen en tant que SDL_Surface.
Nous devons encore une fois tester si notre pointeur pointe bien quelque part. Car il est bien possible que certains modes vido ne sont pas accepts pas certaines cartes graphiques ou systme# Quand quelque chose tourne mal avec la fonction SDL_SetVideoMode, ici screen vaudra NULL, donc aucune adresse n'est retourne et le pointeur screen reste non valide.
Si tout s'est bien pass, nous devrions maintenant avoir un cran noir qui s'ouvre lors de l'excution de l'application, pour que cette fentre ne disparaisse pas tout de suite, nous utilisons la fonction void SDL_Delay(Uint32 ms) qui, dans notre cas, fait attendre 3000 millisecondes l'application avant de quitter (soit 3 secondes).
-5Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Maintenant que nous savons faire a, on va essayer de mettre quelques trucs dans notre fentre comme des images par exemple. C'est l'objet de la partie ci-dessous.
-6Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
SDL.h est inclu parce que bien sur nous allons utiliser des fonctions SDL ^^ string quand lui ben... c'est juste que je prfre std::string plutt que char*.
Ensuite nous allons dfinir les diffrents attributs de notre cran. attributs de l'cran
//Les const const const attributs de notre cran int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; int SCREEN_BPP = 32;
Je pense que vous comprenez ce que dfinissent SCREEN_WIDTH et SCREEN_HEIGHT. SCREEN_BPP dfinit le nombre de bits par pixel. Dans cet exemple, nous utilisons des couleurs 32 bits.
Aprs avoir dfini les attributs pour notre cran, il nous faut dfinir les surfaces que nous allons utiliser. Nous allons avoir besoin de 3 surfaces : la surface de l'cran qu'on appellera screen la surface qui servira de fond d'cran (background) la surface qui servira afficher notre "Hello World" qui sera une image bitmap avec crit Hello World dessus
Remarque : c'est une bonne ide de toujours mettre ses pointeurs NULL s'ils pointent sur rien.
Nous avons termin la partie dfinition des diffrentes variables dont nous aurons besoin, maintenant passons dans le vif du sujet : le chargement d'image. Nous allons construire une fonction qui chargera une image partir de son nom. Voici le prototype de la fonction : protoype fonction load_image
SDL_Surface *load_image( std::string filename )
-7Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Cette fonction retourne un pointeur vers la version optimis de l'image charge. Pourquoi la version optimise ? Comme nous avons dfinit notre cran en 32bits, si le bitmap est en 24bits, il va nous falloir faire quelques petits changements sur l'image. En effet, bien que SDL soit capable d'appliquer une image d'un format diffrent sur une autre, il faut pour cela qu'il change de lui mme le format " l'arrache" ce qui peut causer quelques ralentissements. Comme vous le voyez, ce n'est pas une bonne ide d'essayer de blitter une surface sur une autre si les 2 sont dans des formats diffrents.
Voici comment nous allons donc procder : Tout d'abord il va nous falloir dfinir 2 variables, une variable qui servira de tampon pour stocker l'image charge temporairement et une autre o on mettra l'image optimise. Il va nous falloir charger l'image en utilisant la fonction SDL_LoadBMP(char *) qui s'occupera de charger l'image au format Bitmap et de la mettre dans notre variable tampon. Si le chargement s'est bien pass, il nous faut crer l'image optimise. La fonction SDL_DisplayFormat(SDL_Surface *) va nous permettre de crer une image dans le mme format que notre cran.
Nous allons donc, comme le montre le petit schma ci-dessus, nous retrouver avec 2 surfaces : l'ancienne surface et la version optimise.
-8Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Il va donc nous falloir faire un peu de mnage. On va se servir de la fonction SDL_FreeSurface(SDL_Surface *) afin de librer proprement l'ancienne surface
pour finir, comme notre fonction retourne la version optimise de l'image, il ne faut pas oublier... de la retourner ^^.
Par la suite, il nous faut blitter la surface, nous allons donc crer une nouvelle fonction qui se chargera de cette tche. Notre fonction prendra en paramtre les coordonnes o l'on veut blitter notre surface, la surface que nous allons
-9Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
appliquer ainsi que la surface sur laquelle nous allons appliquer notre surface. Voici quoi cela va ressembler au dbut : debut fonction apply_surface
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination ) { SDL_Rect offset; offset.x = x; offset.y = y;
Voila donc le dbut de notre fonction de blitting. Nous faisons ainsi car SDL_BlitSurface() accepte seulement les offsets dans un SDL_Rect.
Un SDL_Rect est un type de donne reprsentant un rectangle. Il possde 4 membres reprsentant les offsets X et Y, la largeur (Width) et la hauteur (Height) du rectangle. Ici nous avons seulement besoin des donnes membres X et Y.
Ensuite il nous faut donc blitter la surface (c'est tout de mme la finalit de cette fonction), pour cela nous allons utiliser la fonction SDL_BlitSurface() de cette faon : SDL_BlitSurface
//On blitte la surface SDL_BlitSurface( source, NULL, destination, &offset ); }
Comme vous pouvez le remarquer, ce bout de code est la suite directe, et la fin, de celui mit juste avant. Notre fonction est donc dj termin.
Le premier argument de SDL_BlitSurface est la surface que nous allons utiliser. Ne vous souciez pas encore du second argument, laissez le NULL pour le moment. Le troisime argument est la surface sur laquelle nous allons appliquer la surface que nous allons utiliser. Le quatrime et dernier argument contient l'offset d'o notre surface sera appliqu sur la surface de destination.
Bon nous avons fini avec les fonctions dont nous allons avoir besoin pour faire notre petit programme, maintenant nous allons passer au main(). Tout d'abord, lorsque vous utilisez SDL, vous devrez toujours utiliser : main avec SDL
int main( int argc, char* args[] ) ou
- 10 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Sous windows, n'utilisez jamais int main(), void main(), ou autre chose qui ne marchera pas.
Bien, maintenant que l'on sait tout a, on va se lancer dans le main en commenant par initialiser SDL : init SDL
int main( int argc, char* args[] ) { //Initialisation de tous les sous-systmes de SDL if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return EXIT_FAILURE; }
Ici nous initialisons SDL en utilisant SDL_Init(). Nous donnons comme paramtre SDL_Init() SDL_INIT_EVERYTHING, qui dmarre tous les sous-systmes SDL(Vido, Audio, etc...). Les sous-systmes SDL sont les moteurs individuels utiliss pour fabriquer un jeu. Nous n'allons pas utiliser tous ces sous-systmes, mais cela ne nous gnera pas si nous les initialisons tout de mme.
Si SDL ne peut pas s'initialiser, il retourne -1. Dans ce cas, nous attrapons l'erreur en retournant EXIT_FAILURE, qui termine le programme.
Aprs l'initialisation de SDL, il est temps de fabriquer notre cran et de rcuprer un pointeur sur cet cran afin de pouvoir blitter des surfaces dessus. SDL_SetVideoMode
//Mise en place de l'cran screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
Vous connaissez dj les 3 premiers arguments si vous avez suivi normalement. Le quatrime argument cre la surface cran dans la mmoire systme. Il nous faut ensuite vrifier si notre pointeur sur surface screen n'est pas NULL, ce qui voudrait dire que a s'est mal pass. test ecran
//S'il y a une erreur dans la cration de l'cran if( screen == NULL ) { return EXIT_FAILURE; }
On va agrmenter notre fentre en ajoutant une lgende sur le haut de la fentre : legende ecran
//Mise en place de la barre caption
- 11 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
legende ecran
SDL_WM_SetCaption( "Hello World", NULL );
il est maintenant temps d'utiliser notre deuxime fonction qui va se charger d'appliquer l'image de fond sur l'cran : background
//On applique le fond sur l'cran apply_surface( 0, 0, background, screen );
- 12 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Quand vous appliquez une surface, vous copiez les pixels de l'un sur l'autre surface. Donc maintenant l'cran ressemble l'image background que nous venions de charger.
Nous allons donc continuer en appliquant maintenant la surface qui contient notre message "Hello World" message
//On applique le message sur l'cran apply_surface( 180, 140, message, screen );
Comme vous le voyez sur le code ci-dessus, nous appliquons notre surface sur l'cran en X=180 et Y=140. Ce qu'il faut comprendre c'est que le systme de coordonnes de SDL ne fonctionne pas ainsi :
- 13 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Ainsi quand vous appliquez la surface message, celle-ci va se placer 180 pixels sur la droite et 140 pixels vers le bas par rapport au coin haut gauche. Voici une illustration afin de mieux comprendre :
- 14 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Le systme de coordonnes de SDL peut vous paratre effrayant au dbut, mais vous vous y ferez vite. Bien que nous avons appliquer nos surfaces, dans l'tat actuel, l'cran restera noir. En effet, il nous faut mettre jour l'cran en utilisant la fonction SDL_Flip() pour que l'cran ressemble celui que nous avons en mmoire. SDL_Flip
//Mise jour de l'cran if( SDL_Flip( screen ) == -1 ) { return EXIT_FAILURE; }
Si il y a une erreur, la fonction retourne -1. Nous pouvons presque dire que le travail est fini, il nous reste encore 2 choses faire : laisser l'cran s'afficher quelques secondes et terminer notre application correctement. En effet, si nous lanons notre programme, celui-ci disparatra de votre cran si rapidement que vous n'aurez mme pas le temps d'admirer votre travail... Pour maintenir l'cran quelques temps, nous allons utiliser la fonction SDL_Delay() qui prend en paramtre un temps en millisecondes
SDL_Delay
//On attend 2 secondes SDL_Delay( 2000 );
Dans l'exemple ci-dessus, l'cran restera affich pendant 2000 millisecondes soit 2 secondes.
- 15 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
SDL_FreeSurface() est utilis pour librer la surface que nous avons charg et que nous n'utiliserons plus. Si vous ne librez pas la mmoire utilis, cela provoquera une fuite mmoire. Ensuite nous appelons SDL_Quit() pour quitter SDL. Il nous reste retourner 0 pour terminer l'application.
Remarque :
- 16 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app
Si vous lancez le programme, que les images ne se voient pas, que l'cran de l'application n'apparat que trs brivement et que vous trouvez dans le fichier stderr.txt : Fatal signal: Segmentation Fault (SDL Parachute Deployed), c'est parce que le programme tente d'accder un espace mmoire qui n'est pas suppos tre. Ce phnomne trange est du au fait qu'il essaye d'accder NULL quand apply_surface() est appel. Ce qui veut dire que vous devez vrifier que vos fichiers image Bitmap soient bien dans le mme rpertoire que votre programme.
<= Retour au chapitre I : Installation de SDL -=Index Tutos SDL==> Accder au chapitre III : SDL_TTF
- 17 Ce document est issu de http://www.developpez.com et reste la proprit exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise l'obtention pralable de l'autorisation de l'auteur.
http://loka.developpez.com/tutoriel/sdl/premiere_app