IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ SDL

FAQ SDLConsultez toutes les FAQ

Nombre d'auteurs : 6, nombre de questions : 67, création le 10 mai 2013 

 
OuvrirSommaireAffichage de texte

SDL_ttf est une bibliothèque complémentaire à SDL, qui permet d'afficher du texte dans une application SDL via une police TrueType.

Cela est très utile et permet :

  • d'afficher dynamiquement du texte ;
  • de l'afficher de la taille que l'on veut, avec la police que l'on veut, etc. ;
  • de s'affranchir d'une gestion compliquée avec des polices graphiques, qui sont moins flexibles.

Pour installer SDL_ttf, il suffit d'aller sur le site officiel et de télécharger la version correspondant à votre système. Ensuite, il y a les habituels en-têtes et bibliothèques à ajouter dans le répertoire de SDL.

Créé le 17 mars 2006  par Fiquet

Lien : Site officiel

Il est très simple d'afficher du texte grâce à cette bibliothèque. Il faut tout d'abord initialiser SDL_ttf (après SDL bien sûr). Ensuite, il ne reste plus qu'à créer une police (TTF_Font), et rendre un texte pour en faire une SDL_Surface.

Voici un code qui regroupe ces différentes étapes et qui affiche avec un mode de rendu simple (rendu plein) :

 
Sélectionnez
/* Après initialisation de SDL, de la fenêtre, etc. */


/* Initialisation de SDL_ttf */
if(TTF_Init() < 0 )
{
    printf("Impossible d'initialiser SDL_ttf : %s", TTF_GetError());
    return 1;
}

/* Charge une police depuis un fichier, avec une taille de point à 50 */
TTF_Font* Font = TTF_OpenFont("comic.ttf", 50);

/* Si la police est nulle, il y a eu une erreur */
if(!Font)
{
    printf("Erreur de création de la police : %s", TTF_GetError());
    return 1;
}

/* Couleur du texte (ici rouge) */
SDL_Color TextColor;
TextColor.r = 255
TextColor.g = 0;
TextColor.b = 0;

/* On rend un texte sur une surface SDL, en utilisant notre police et notre couleur */
SDL_Surface* TextSurface = TTF_RenderText_Solid(Font, "Salut tout le monde !", TextColor);

/* Si la surface est nulle, il y a eu une erreur */
if(!TextSurface)
{
    printf("Erreur de rendu du texte : %s", TTF_GetError());
    return 1;
}

/* On peut maintenant blitter notre surface comme n'importe quelle autre */
SDL_Rect DstRect;
DstRect.x = 0;
DstRect.y = 0;
DstRect.w = TextSurface->w;
DstRect.h = TextSurface->h;

/* Affiche toute la surface en 0,0 */
SDL_BlitSurface(TextSurface, NULL, MainScreen, &DstRect);

/* Libère notre surface et notre police */
SDL_FreeSurface(TextSurface);
TTF_CloseFont(Font);

/* Fermeture de SDL_ttf */
TTF_Quit();
Créé le 17 mars 2006  par Fiquet

SDL_ttf propose trois types de rendus :

  • rendu plein (solid) ;
  • rendu avec fond (shaded) ;
  • rendu transparent (blended).

Le premier (utilisé dans la question précédente https://jeux.developpez.com/faq/sdl/?page=texte#TEXTE_comment) dessine simplement le texte dans la couleur définie et donne une couleur de fond transparente. C'est le mode de rendu le plus simple, le plus rapide, mais aussi le moins précis, car il est très crénelé (aliased). Il peut être utile pour afficher du texte voué à changer souvent (par exemple affichage de FPS ou de points).

 
Sélectionnez
/* Dessine un texte en mode de rendu plein */
SDL_Surface* TextSurface = TTF_RenderText_Solid(Font, "Mon texte", TextColor);

Le deuxième permet d'ajouter une couleur de fond. Le résultat est beaucoup plus joli, anticrénelé (antialiased), mais le rendu dure plus longtemps. Cependant, une fois que la surface est créée, celle-ci ne prendra pas plus de temps à blitter qu'en mode plein. Il peut donc être utile pour un texte qui ne se modifie pas souvent ou jamais (un menu, une introduction…).

 
Sélectionnez
/* Dessine un texte en mode de rendu avec fond */
SDL_Surface* TextSurface = TTF_RenderText_Shaded(Font, "Mon texte", TextColor, BackgroundColor);

Enfin, le dernier mode rend du texte comme le précédent, mais en ajoutant un canal alpha, donc il n'y a plus de couleur de fond comme avant (et plus le paramètre correspondant). Ce mode est lent, mais dessine du texte de haute qualité. Le blit est aussi plus lent, car il utilise la transparence alpha. Il est bien entendu aussi destiné à des textes plutôt statiques et nécessitant un rendu plus chouette.

 
Sélectionnez
/* Dessine un texte en mode de rendu avec transparence */
SDL_Surface* TextSurface = TTF_RenderText_Blended(Font, "Mon texte", TextColor);
Créé le 17 mars 2006  par Fiquet

Avant de commencer à appeler les fonctions SDL_TTF, il faut générer un identifiant de texture OpenGL et on l'active avec la fonction glBindTexture.

La puissance de 2 supérieure
Sélectionnez
                glGenTextures (1, &(txt->surface));
                glBindTexture (GL_TEXTURE_2D, txt->surface);

Lorsque nous voulons créer une surface OpenGL, il faut s'assurer que l'image a des dimensions en puissance de 2. Pour cela, il faut déjà calculer la puissance 2 supérieure à un nombre n quelconque :

La puissance de 2 supérieure
Sélectionnez
int puissance2sup(int i)
{
    double logbase2 = log(i) / log(2);
    return (int) floor(pow(2.0, ceil(logbase2)));
}

Une fois qu'on est capable d'avoir la puissance de 2 supérieure d'un nombre quelconque, on va pouvoir créer la surface texte compatible pour la transformer en texture OpenGL. Tout d'abord, on commence par appeler la fonction TTF_RenderText_Solid :

Appel à TTF_RenderText_Solid
Sélectionnez
temp = TTF_RenderText_Solid(police, message, couleur);

Ensuite, il faudra transformer cette surface en une surface avec des dimensions en puissance de 2 :

Création d'une surface plus grande
Sélectionnez
               if(temp != NULL) {
                    //Calcul de taille
                    int w = puissance2sup(temp->w);
                    int h = puissance2sup(temp->h);

                    SDL_Surface *temp2=SDL_CreateRGBSurface(
                            SDL_HWSURFACE,
                            w,
                            h,
                            24,
                            temp->format->Rmask,
                            temp->format->Gmask,
                            temp->format->Bmask,
                            temp->format->Amask);

                    if(temp2 == NULL) {
                        SDL_FreeSurface(temp);
                        return 0;
                    }

Puisque nous ne voulons pas une couleur transparente, nous utilisons simplement 24 bits pour la surface.

Ce code crée donc une surface plus grande qui aura des dimensions en puissance de 2. Une fois que cette surface est créée, nous allons copier la surface de base sur cette nouvelle surface :

Copie de la surface
Sélectionnez
                    txt->textx = temp->w;
                    txt->textx /= w;
                    txt->texty = temp->h;
                    txt->texty /= h;
                    txt->width = temp->w;
                    txt->height = temp->h;

                    SDL_BlitSurface(temp, NULL, temp2, NULL);

Enfin, on appelle glTexImage2D pour transformer la surface en texture et on libère les surfaces SDL.

Copie de la surface
Sélectionnez
                    // Jonction entre OpenGL et SDL.
                    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, temp2->w, temp2->h, 0,
                            GL_RGB, GL_UNSIGNED_BYTE, temp2->pixels);

                    SDL_FreeSurface(temp);
                    SDL_FreeSurface(temp2);

Nous avons enfin terminé et la variable txt contiendra donc l'identifiant de cette texture. Attention, si vous utilisez ce code, n'oubliez pas d'appeler glDeleteTextures pour libérer les textures si vous ne vous en servirez plus.

Créé le 3 mai 2007  par fearyourself

La technique pour transformer une surface TTF_Blended en texture OpenGL ressemble à https://jeux.developpez.com/faq/sdl/?page=texte#TEXTE_OpenGL à part ces quelques points.

Pour transformer une surface transparente en surface OpenGL, on utilisera la fonction TTF_RenderText_Blended à la place de TTF_RenderText_Solid.

Appel à TTF_RenderText_Blended
Sélectionnez
temp = TTF_RenderText_Blended(police, message, couleur);

Pour la création de la nouvelle surface, nous allons utiliser 32 bits par pixel à la place de 24 :

Création de la nouvelle surface
Sélectionnez
                    SDL_Surface *temp2=SDL_CreateRGBSurface(
                            SDL_HWSURFACE,
                            w,
                            h,
                            32,
                            temp->format->Rmask,
                            temp->format->Gmask,
                            temp->format->Bmask,
                            temp->format->Amask);

Enfin, l'appel à la fonction glTexImage2D est différent :

Appel à TTF_RenderText_Solid
Sélectionnez
                    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, temp2->w, temp2->h, 0,
                            GL_RGBA, GL_UNSIGNED_BYTE, temp2->pixels);
Créé le 3 mai 2007  par fearyourself

Si un appel SDL_TTF est fait avant l'appel à TTF_Init, le comportement est indéfini. Il faut faire attention aux appels SDL qui se trouvent dans les constructeurs puisque, souvent, l'initialisation de la SDL et de la SDL_TTF se fait dans la fonction main et si un objet est déclaré en global, le constructeur sera appelé avant la première instruction du main.

Pour éviter ce genre de problème, ne mettez pas d'appels SDL_TTF dans les constructeurs.

Créé le 3 mai 2007  par fearyourself

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006-2012 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.