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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    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
    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 confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    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 226
    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
    Membre confirmé
    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
    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 confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    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 226
    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
    Membre confirmé
    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
    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 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    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 confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    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 226
    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.

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