Article     Discussion     Modifier     Historique     Forums     Salon IRC

Générer une transition entre deux textures avec SDL

Un article de Games Creators Network.


Sommaire

[modifier] Principe

Le but de cet article est de montrer comment générer un dégradé entre deux textures.

Pour cela, on affiche la première texture à l'écran, on charge la seconde en mémoire et on modifie sa couche alpha pixel par pixel. Le but est de rendre la composant alpha de l'image égale à celle de l'image de transition.


[modifier] Aller plus loin: utilisation de ce principe dans un jeu 3d

Dans le cadre d'un moteur 3d supportant le multi-texturing, il est possible d'économiser le chargement en mémoire des textures de transition en générant ces transitions à la volée selon le principe appliqué dans cet article.


[modifier] Voir aussi


[modifier] Démo: générateur de dégradés

La fonction principale de ce programe GenereTransition prend quatre paramètres:

  • avant: l'image de départ du dégradé
  • apres: l'image d'arrivée du dégradé
  • file_transition: le chemin indiquant l'image de transition
  • filename: fichier dans lequel va être écrit la transition
#include <SDL/sdl.h>
 
int GenereTransition(
  SDL_Surface *avant,
  SDL_Surface *apres,
  char *file_transition,
  char *filename);
 
int main(int argc, char **argv)
{
  SDL_Surface *screen, *fond1, *fond2;
 
  SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
 
  screen = SDL_SetVideoMode(256,256,32, SDL_HWSURFACE);
  SDL_WM_SetCaption("Fondu enchaîné avec SDL - Games Creators Network (http://www.games-creators.org/)",NULL);
 
  if(argc<5)
  {
    printf("Utilisation: transition_textures.exe <texture1.bmp> <texture2.bmp> <transition>.bmp> <rendu.bmp>\n");
    SDL_Quit();
    return 0;
  }
 
  fond1=SDL_LoadBMP(argv[1]);
  fond2=SDL_LoadBMP(argv[2]);
 
  GenereTransition(fond1, fond2, argv[3], argv[4]);
printf(
"La texture '%s' a été générée. Il s'agit de la texture de transition entre '%s' et '%s' selon le schéma '%s'.\n",
argv[4], argv[1], argv[2], argv[3]);
 
  SDL_Quit();
  return 0;
}
 
int GenereTransition(
  SDL_Surface *avant,
  SDL_Surface *apres,
  char *file_transition,
  char *filename)
{
  SDL_Surface *copie, *transition;
  unsigned int rmask, gmask, bmask, amask,
               i;
  Uint32       temp,
               *pt, *pta; /* pointeurs vers les surfaces */
  Uint8        r,g,b,a;
  Uint8        comp;
 
  /* Quelques vérifications pour éviter les principales
     sources de segfault */
  if((!avant)||(!apres)) return 1;
  if(avant->w!=apres->w) return 1;
  if(avant->h!=apres->h) return 1;
 
  /* On copie la surface "avant" afin de pouvoir traviller
     dessus sans crainte */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
  rmask = 0xff000000;
  gmask = 0x00ff0000;
  bmask = 0x0000ff00;
  amask = 0x000000ff;
#else
  rmask = 0x000000ff;
  gmask = 0x0000ff00;
  bmask = 0x00ff0000;
  amask = 0xff000000;
#endif
  copie = SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 256, 32,
                                   rmask, gmask, bmask, amask);
  SDL_BlitSurface(avant, NULL, copie, NULL);
 
  /* Chargement de la transition */
  transition = SDL_LoadBMP(file_transition);
  transition = SDL_ConvertSurface(transition,copie->format,SDL_SWSURFACE|SDL_SRCALPHA);
  if(!transition)
  {
    SDL_FreeSurface(copie);
    return 1;
  }
 
  /* On fixe la transparence de la surface */
  SDL_SetAlpha(copie, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
 
  /* Affiche fond */
  SDL_BlitSurface(apres, NULL, SDL_GetVideoSurface(), NULL);
 
  /* Mise à jour de la couche alpha */
  SDL_LockSurface(copie);
  SDL_LockSurface(transition);
  pt=((Uint32*)copie->pixels);
  pta=((Uint32*)transition->pixels);
 
  for(i=0;i<(copie->w*copie->h);i++)
  {
    SDL_GetRGBA(pt[i],copie->format,&r,&g,&b,&a);
    /* je ne récupère qu'une composante... c'est du niveau de gris! */
    temp=pta[i]&transition->format->Rmask;
    temp=temp>>transition->format->Rshift;
    temp=temp<<transition->format->Rloss;
    comp=(Uint8)temp;
 
    pt[i]=SDL_MapRGBA(copie->format,r,g,b,comp);
  }
  SDL_UnlockSurface(transition);
  SDL_UnlockSurface(copie);
 
  /* On affiche la deuxième surface */
  SDL_BlitSurface(copie, NULL, SDL_GetVideoSurface(), NULL);
 
  /* Inversion des tampons */
  SDL_Flip(SDL_GetVideoSurface());
  SDL_SaveBMP(SDL_GetVideoSurface(),filename);
 
  SDL_FreeSurface(transition);
  SDL_FreeSurface(copie);
 
  return 0;
}

Cet outil s'utilise via la ligne de commande, la syntaxe est la suivante:

transition_textures.exe <texture1.bmp> <texture2.bmp> <transition.bmp> <rendu.bmp>
  • texture1.bmp: image n°1 à partir de laquelle est générée le dégradé
  • texture2.bmp: image n°2 à partir de laquelle est générée le dégradé
  • transition.bmp: fichier de transition (image au format bitmap)
  • rendu.bmp: nom du fichier dans lequel l'image générée sera sauvegardée.


Dégradé utilisé.
Dégradé utilisé.
Texture n°1.
Texture n°1.
Texture n°2.
Texture n°2.



Exemple de rendu de cet outil grâce aux trois images ci-dessus.
Exemple de rendu de cet outil grâce aux trois images ci-dessus.

 

Rechercher
Installer l'extension de recherche Plus d'informations

 

Comprendre
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. - Benjamin Franklin

 

Partager
La connaissance est la seule chose qui s'accroit lorsqu'on la partage. - Sacha Boudjema

 

Créer
L'imagination est plus importante que la connaissance. - Albert Einstein

 

 

Le wiki en images Le wiki en images Image du mois: «Snowball: un prototype de jeu développé avec NeL.