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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Afficher du texte en OpenGL en utilisant des polices TTF ?


Sujet :

OpenGL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 72
    Points : 38
    Points
    38
    Par défaut Afficher du texte en OpenGL en utilisant des polices TTF ?
    Bonjour/soir (tout dépend d'où on se place ^^ ),
    Je fais face depuis maintenant 3 heures à un problème sans réponse :
    Ce n'est pourtant pas compliqué, je veux pouvoir afficher du texte simplement en OpenGL, avec des polices que j'aurais téléchargées au préalable.
    Je suis déjà capable d'afficher du texte avec les primitives d'OpenGL, (ou c'est glut je ne sais plus enfin bref), mais là je veux pouvoir afficher du texte de n'importe quelle police...
    Je suis étonné de ne pas trouver de solution simple sur le web, et pas de topic portant sur le sujet ici (à moins que le moteur de recherche du site soit tout nul... ?)

    J'ai déjà pas mal avancé dans mes recherches et je requiers votre aide pour comprendre pourquoi mon texte ne s'affiche pas alors que mon appli fonctionne très bien.
    En clair, j'utilise Font Stash pour charger mes polices et les afficher, il est vrai que ça a l'air très facile d'utilisation, léger et plein d'options comme appliquer un flou sur le texte par exemple.
    Mon appli ne plante pas, mais elle n'affiche tout simplement pas le texte !

    Je vous joins donc un ensemble de fichiers qui correspondent à un petit projet test que j'ai créé, avec le code minimal pour créer une fenêtre OpenGL et afficher quelques bribes de texte, afin que vous voyiez ce qui ne va pas, éventuellement... Voici les 4 polices utilisées dans le programme :
    https://github.com/memononen/fontsta...nsJapanese.ttf
    https://github.com/memononen/fontsta...Serif-Bold.ttf
    https://github.com/memononen/fontsta...rif-Italic.ttf
    https://github.com/memononen/fontsta...if-Regular.ttf

    Et un des fichiers.h qui était trop lourd pour que je puisse l'uploader sur le site :
    https://github.com/memononen/fontsta...stb_truetype.h
    (Font Stash s'en sert pour fonctionner)

    Donc voilà, pour récapituler il y a :

    - le main,
    - les 4 polices,
    - les 3 fichiers .h pour écrire du texte (fontstash.h, glfontstash.h et stb_truetype.h)

    J'ai même été jusqu'à essayer de me servir de SDL_ttf ! Et bien, même résultat que Font Stash : le code fonctionne très bien mais le texte ne s'affiche pas...
    Donc je soupçonne OpenGL d'être derrière tout ça, je ne sais pas moi, peut-être qu'il y a un truc à jouer avec glutSwapBuffers(), peut-être que c'est ça qui efface le texte, mais je n'ai rien trouvé de probant sur internet...

    Merci d'avance de vous pencher sur mon cas, je commence un peu à en avoir marre de ne pas arriver à faire un truc aussi simple ^^

    P.S : Une autre solution serait apparemment d'avoir sa police sous forme d'une seule texture réunissant tous ses caractères, ensuite je chargerais seulement un extrait de cette texture pour afficher chaque lettre. Ça me semble bien également, il y a des logiciels comme FontBuilder sur Mac que j'utilise, ou encore bmGlyph. Sur Windows il y a Angel's Code BMFont (http://www.angelcode.com/products/bmfont/).
    Sauf que l'image générée à partir de la police choisie n'est pas une grille parfaite, certains caractères prennent évidemment plus de place que d'autres, et donc il faudrait que je stocke à la main les coordonnées de chaque caractère, enfin bref... La flemme ! Surtout que je ne pense pas être loin de la solution avec Font Stash/SDL_ttf

    P.S 2 : Il me semble que si vous êtes sur Windows, la ligne glutInit au début du main vous fera planter... C'est parce que je suis sous Mac et si je n'écris pas cette ligne, l'app plante !
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Je ne connais pas Font Stash donc je ne pourrais pas aider , pour SDL_tff elle marche si on sait ce qu'on fait , si tu fait un SDL_Blit forcément ça marchera pas parce que SDL_blit ne fait que écrire sur une surface , donc tant que tu n'envoie pas ta surface(texture) a l'écran tu ne la verra jamais.
    Donc avec SDL_ttf c'est assez simple , après quand on fait tu bas niveau afficher un ttf n'est pas forcément simple , même dans le jeux vidéo on a longtemps préféré un bitmap font.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Salut,
    Tout d'abord merci de ta réponse
    Ok et bien si tu penses que SDL_ttf est une solution viable, je prends ^^
    Voilà ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    void RenderText(const TTF_Font *Font, const GLubyte& R, const GLubyte& G, const GLubyte& B,
                    const double& X, const double& Y, const std::string& Text)
    {
        /*Create some variables.*/
        SDL_Color Color = {R, G, B};
        SDL_Surface *Message = TTF_RenderUTF8_Blended(const_cast<TTF_Font*>(Font), Text.c_str(), Color);
        GLuint Texture = 0;
     
        /*Generate an OpenGL 2D texture from the SDL_Surface*.*/
        glGenTextures(1, &Texture);
     
        glEnable(GL_TEXTURE_2D);
     
        glBindTexture(GL_TEXTURE_2D, Texture);
     
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Message->w, Message->h, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, Message->pixels);
     
        glPushMatrix();
            glTranslated(X, Y, 0);
            glBegin(GL_QUADS);
            glTexCoord2d(0, 0); glVertex2d(0, 0);
            glTexCoord2d(1, 0); glVertex2d(Message->w, 0);
            glTexCoord2d(1, 1); glVertex2d(Message->w, Message->h);
            glTexCoord2d(0, 1); glVertex2d(0, Message->h);
            glEnd();
        glPopMatrix();
     
        glDisable(GL_TEXTURE_2D);
     
        /*Clean up.*/
        glDeleteTextures(1, &Texture);
        SDL_FreeSurface(Message);
    }
    C'est quasiment un copier-coller de la fonction "officielle" que j'ai trouvée ici : SDL_ttf in OpenGL

    J'appelle simplement cette fonction depuis ma glutDisplayFunc et ça devrait marcher, non ?
    J'ai essayé un RenderText(ma_police, 0, 0, 0, 0, 0, "Coucou") du coup, et ça n'affiche rien...

    Pourtant j'ai vérifié et Message->w et Message->h sont bien définis et varient en fonction de la taille de la police et la longueur du message, donc ça a l'air de fonctionner !

    Merci de ton aide

  4. #4
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Moi j’enlèverais glPushMatrix(); , glPopMatrix(); .
    Oui tu dois le mettre sur ton DisplayFunc
    Si ça marche pas ça serait étrange , faudrait faire plus de test voir deja si tu peux afficher une texture , si ça marche ben le SDL_TTF est guère différent.

    Sinon je vois que tu met des variable global c'est pas très bien (encore plus en C++) même pour une démo c'est pas pardonnable justement dans un petit code comme ça c'est plus facile de faire du code propre.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Ah oui les variables globales ça pue je confirme...
    J'en utilise quelques-unes dans mon projet déjà, et là pour la petite démo j'avais la flemme de faire autrement ^^
    J'affiche déjà des textures dans mon projet et il n'y a pas de souci.

    J'ai essayé sans glPush et glPop et du coup pour mes glVertex j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     glBegin(GL_QUADS);
            glTexCoord2d(0, 0); glVertex2d(X, Y);
            glTexCoord2d(1, 0); glVertex2d(X+Message->w, Y);
            glTexCoord2d(1, 1); glVertex2d(X+Message->w, Y+Message->h);
            glTexCoord2d(0, 1); glVertex2d(X, Y+Message->h);
    glEnd();
    Mais ça ne change rien...

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Salut,

    tu peux regarder comment fait la SFML, ça te donnera une piste de solution. C'est plutôt aisé à comprendre et reprendre
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Voila un code C , je viens de le test il marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    #include <stdio.h>
    #include <stdlib.h>
     
    #include <GL/gl.h>
    #include <GL/glu.h>
     
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <SDL/SDL_ttf.h>
     
     
     
    void RenderText(TTF_Font *font, const GLubyte R, const GLubyte G, const GLubyte B,const double X, const double Y,  char  *texte);
     
    int main(int argc, char** argv)
    {
        SDL_Init(SDL_INIT_VIDEO);
        TTF_Init();
     
        TTF_Font *font = TTF_OpenFont("police.ttf",20);
        SDL_Event event;
        int quit = 0;
     
        SDL_SetVideoMode(500,500, 24,SDL_OPENGL);
     
        glClearColor(0.5,0.5,0.5,0); //Couleur du fond
     
        while(quit == 0)
        {
            SDL_PollEvent(&event);
            switch(event.type)
            {
                case SDL_QUIT:
                    quit = 1;
                break;
            }
     
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
            RenderText(font,255,0,255,-1,0,"test");
     
            SDL_GL_SwapBuffers();
            SDL_Delay(33);
        }
     
        TTF_Quit();
        SDL_Quit();
     
        return 0;
    }
     
     
    void RenderText(TTF_Font *font, const GLubyte R, const GLubyte G, const GLubyte B,
                    const double X, const double Y,  char  *texte)
    {
        /*Create some variables.*/
        SDL_Color color = {R, G, B};
        SDL_Surface *Message = TTF_RenderText_Blended(font, texte, color);
        GLuint Texture = 0;
     
        SDL_Surface *tmp = SDL_CreateRGBSurface(0,Message->w,Message->h,32,0,0,0,0);
        SDL_BlitSurface(Message,NULL,tmp,NULL);
     
        /*Generate an OpenGL 2D texture from the SDL_Surface*.*/
        glGenTextures(1, &Texture);
     
        glEnable(GL_TEXTURE_2D);
     
        glBindTexture(GL_TEXTURE_2D, Texture);
     
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     
        glTexImage2D(GL_TEXTURE_2D, 0, 4, Message->w, Message->h, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, tmp->pixels);
     
                glColor3f(1,1,1);
     
            glLoadIdentity();
            glTranslated(X, Y, 0);
            glBegin(GL_QUADS);
            glTexCoord2d(0, 0); glVertex2d(0, 0);
            glTexCoord2d(1, 0); glVertex2d(0.5, 0);
            glTexCoord2d(1, 1); glVertex2d(0.5, 0.5);
            glTexCoord2d(0, 1); glVertex2d(0, 0.5);
            glEnd();
     
        glDisable(GL_TEXTURE_2D);
     
        /*Clean up.*/
        //SDL_SaveBMP(Message,"rendu.bmp");
        glDeleteTextures(1, &Texture);
        SDL_FreeSurface(Message);
        SDL_FreeSurface(tmp);
    }
    Sinon comme solution alternative , je t'ai parlé du bitmap font pour afficher du texte.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Wow ça voudrait dire que je devrais tout passer dans une logique SDL, la création de la fenêtre, la gestion des événements, etc etc ?
    J'ai déjà tout de prévu pour ça dans OpenGL moi...
    Bien que ton exemple fonctionne !
    Mais je trouve ça trop contraignant ( et surtout crade :p) de devoir gérer mes événements claviers, souris, etc. avec SDL donc je vais voir du côté des bitmap fonts surtout que cette solution a l'air plus performante.
    Merci à vous deux !

  9. #9
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Je les gère dans mon moteur avec des atlas: c'est grosso modo comme une bitmap font sauf que tu la charges au runtime (avec FreeType dans mon cas) avec la hauteur que tu souhaites, tu crées ensuite l'image qui va contenir tes caractères et tu gères l'affichage d'un texte en modifiant un vertex buffer.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par eldoir Voir le message
    Wow ça voudrait dire que je devrais tout passer dans une logique SDL, la création de la fenêtre, la gestion des événements, etc etc ?
    J'ai déjà tout de prévu pour ça dans OpenGL moi...
    Bien que ton exemple fonctionne !
    Mais je trouve ça trop contraignant ( et surtout crade :p) de devoir gérer mes événements claviers, souris, etc. avec SDL donc je vais voir du côté des bitmap fonts surtout que cette solution a l'air plus performante.
    Merci à vous deux !
    Euh.. SFML utilise FreeType et OpenGL
    Le code qui fait l'affichage du texte, le chargement de la font, prend une centaine de lignes à tout péter.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2015
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2015
    Messages : 9
    Points : 12
    Points
    12
    Par défaut
    Sinon, sans passer par SDL, et en utilisant Freetype (un tutoriel est présent ici si jamais http://learnopengl.com/#!In-Practice/Text-Rendering), il est possible de générer des atlas à l’initialisation du programme, et des glyphes à la volée, avec différentes polices de différentes tailles (pour éviter la pixellisation du texte avec des niveaux de zoom différents). L'utilisation de l'atlas permet aussi de mieux gérer les couleurs du texte, ainsi que de lui appliquer de la transparence.
    Au niveau performance, il est de nombreux cas ou les bitmaps font sont plus efficaces, mais Freetype permet d'utiliser pas mal de different encodage de caractères (pour un traduction dans d'autres alphabets de ton application).

    Merci de me dire si le lien n'est d'aucune utilité dans ton cas, je supprimerai le post.
    Cordialement

    Edit: un post constructif sur l'utilisation d'un texture Atlas, et ses bénéfices par rapport à un bitmap font: http://wildfiregames.com/forum/index...howtopic=17365

  12. #12
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Oui c'est je que je lui est proposé au début des bitmap font simple et efficace.

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Ah oui ça m'intéresse carrément merci ! Je teste ça

Discussions similaires

  1. Réponses: 6
    Dernier message: 20/09/2012, 09h39
  2. Réponses: 3
    Dernier message: 11/07/2011, 17h51
  3. Afficher du texte avec OpenGL
    Par Happy dans le forum Contribuez
    Réponses: 0
    Dernier message: 27/09/2009, 00h29
  4. Utiliser des polices importees
    Par bractar dans le forum ActionScript 3
    Réponses: 2
    Dernier message: 03/10/2007, 18h54
  5. Réponses: 4
    Dernier message: 13/04/2007, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo