Vally8

Affichage d'une image

Au programme de ce second tutorial, on va afficher une image très simple, au format bitmap, à l'aide de la bibliothèque SDL.
Je ne reviendrais pas ou très peu sur ce qui à été vu au premier tutorial, reportez vous y si vous avez des problèmes.

Dans ce programme, nous voir allons les points suivants :

  • initialiser SDL.
  • creer une fenêtre d'une certaine taille.
  • charger en memoire une image contenue dans un fichier.
  • afficher l'image dans la fenetre.

Pour l'initialisation de SDL, rien de plus simple : reportez vous au premier tutorial
La seule différence et que nous y ajouterons l'initialisation du sous-système vidéo.

Le mode fenetré

Passons maintenant à la fenetre, SDL ne dispose pas d'outils très puissants pour personaliser les fenetre, mais ce n'est pas forcément une lacune, car la gestion des fenetres s'en trouve énormément simplifiée.
Pour définir le mode graphique courant (par exemple 640*480), SDL met à notre disposition la fonction SDL_SetVideoMode, qui, si on ne lui spécifie pas le mode plein ecran, fonctionne en mode fenetré et donc crée une fenetre avec une zone interne de la taille spécifié si possible.
Donc, pour creer une fenetre de 400*400, la ligne suivante suffit :
SDL_SetVideoMode(400, 400, 0, SDL_ANYFORMAT);
Si l'appel réussi, une fenetre avec une zone interne de 400*400 est crée, une profondeur de bit egale à celle courante (0), et nimporte quel format de pixel (typiquement, le format courant).

Les surfaces

Notre fenetre crée, nous allons voir comment charger notre image et aborder par la même occasion un concept fondamental de la plupart des bibliothèques 2D : les surfaces.

"Mais quoi c'est donc une surface ??" me direz vous !
"Et bien c'est tout simplement une zone de mémoire contenant une image ou un morceau d'image rectangulaire !" vous répondrais-je !!
A ce moment nous avons fini de discuter et vous m'avez passé un linchage collectif...

En fait, on peut considerer qu'une surface c'est comme une toile de peintre, mais qu'on peut effacer et repeindre à volonté.
L'avantage, c'est qu'on peut y faire des tas de trucs, une fois "qu'on y a peint" une image qui se trouvait dans un fichier, on peut la copier entièrement ou juste un bout à l'écran ou sur une autre toile.
On peut même copier que les endroits de la toile qui sont de la bonne couleur : comme à la météo, les présentateur sont sur un fond bleu et on ne voit à l'écran que le présentateur, tout ce qui est bleu n'a pas été copié et on a à la place la carte de météo avec les jolis petits soleil et les peits nuages..

Appellons maintenant cette toile une surface, voyons comment elle est représentée par SDL et deux opérations de bases que l'on peut y faire :

  • En sdl le type SDL_Surface représente une structure qui sert à stocker les information necéssaires à une surface : la taille de la surface, sont type, son contenu, ... On manipule presque exclusivement des pointeur sur des surface et jamais des surfaces directement, car les fonction SDL ne fonctionnent qu'avec des pointeurs.

  • La création d'une surface, SDL permet de créer des surfaces vides d'une taille et d'un format voulu, mais dans notre premier exemple nous nous contenterons de charger un bitmap avec la fonction SDL_LoadBMP qui s'occupe de créer la surface pour nous, il ne reste donc plus qu'a récuperer le pointeur rendu par cette fonction.

  • La copie d'une surface, elle s'effectue grace à la méthode SDL_BlitSurface (Blit = BLoc bIt Transfert), nous verrons petit à petit toutes les possibilités de cette fonction qui en à beaucoup grace à ces argument et au types de surfaces passées en paramètres.

Récapitulatif

Commencons par définir deux variables de type surface, une pour la zone d'écran, l'autre pour notre image :
SDL_Surface *ecran, *image;
Ensuite nous initialisons SDL et son sous-système vidéo :
SDL_Init(SDL_INIT_VIDEO);
Puis nous fixons le mode vidéo en fenetré 160 * 160 pixels, profondeur de bits quelconque :
ecran = SDL_SetVideoMode(160, 160, 0, SDL_ANYFORMAT);
Enfin, nous chargons le fichier bitmap dans la surface image :
image = SDL_LoadBMP("image.bmp");
Il ne nous reste plus qu'a l'afficher :
SDL_BlitSurface(image, NULL, ecran, NULL);
Pour pouvoir admirer le resultat, il faut encore dire à SDL de mettre à jour l'affichage à l'écran, car en mode fenetré, la mise à jour de la variable écran et de l'affichage n'est pas systèmatique, la fonction SDL_UpdateRect se charge de cela.
Nous l'utilisons de cette manière :
SDL_UpdateRect(ecran, 0, 0, 0, 0);

Voila le source complet, avec quelques lignes en plus pour les vérifications d'erreur :


#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"


int main()
{

	SDL_Surface *ecran, *image;

	atexit(SDL_Quit);
	
	/* initialisation de SDL_Video */
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		fprintf(stderr, "Echec d'initialisation de SDL.\n");
		return 1;
	}
	printf("Bonjour le monde, SDL est initialisé avec succès.\n");
	
	
	/*
	 * creation d'une fenetre avec une zone d'affichage de 160*160 pixels, une profondeur de bits 
  	 * egale à celle du serveur X ou de l'explorateur
	 */
	ecran = SDL_SetVideoMode(160, 160, 0, SDL_ANYFORMAT);
	if ( ecran == NULL )
	{
		fprintf(stderr, "Echec de creation de la fenetre de 160*160 : %s.\n", SDL_GetError());
		return 1;
	}
	
	/* Chargement du bitmap "image.bmp" en memoire dans la surface image */
	image = SDL_LoadBMP("image.bmp");
	if ( image == NULL )
	{
		fprintf(stderr, "Echec de chargement du fichier image.bmp : %s.\n", SDL_GetError());
		return 1;
	}
	
	/* Verification du format de l'image */
	if ( (image->w != 160) || (image->h != 160) )
	{
		fprintf(stderr, "L'image doit être de taille 160*160 pixels.\n");
		SDL_FreeSurface(image);
		return 1;
	}
	
	/* Copie de l'image à l'écran */
	SDL_BlitSurface(image, NULL, ecran, NULL);
	
	/* Mise à jour de la zone d'affichage de la fenetre */
	SDL_UpdateRect(ecran, 0, 0, 0, 0);
	
	/* attente de l'appuis sur une touche pour quitter */
	getchar();
	
	return 0;
}

Vous remarquerez que dès que vous cachez la fenêtre par une autre et que vous la remontrez, la partie de l'image qui a été cachée n'est plus visible.
Ce problème est du au fait que nous attendons un appuis sur "entrée" à la fin de notre code, le programme est "bloqué" sur la fonction getchar et SDL ne peut mettre à jour l'affichage lorsque cela lui est demandé.
Nous aborderons dans le prochain tutorial la gestion du clavier et des évenements sous SDL, et nous verrons que ce problème se résous alors de lui même.

voila le lien avec le fichier source et le makefile : image.tar.bz2

un problème ??? On peut en parler sur le forum

Retour à l'accueil
compteur

Valid HTML 4.01! Valid CSS Valid RSS feed.