Partage
  • Partager sur Facebook
  • Partager sur Twitter

SDL_ttf et openGL

Si près du but...

Sujet résolu
    22 août 2007 à 14:28:03

    Bonjour,

    Je cherche à afficher du texte 2D devant une scène 3D générée avec openGL.
    Etant donné que je connais bien la SDL_ttf (j'y ai même élaboré tout un système de classes en C++), je tiens vraiment à l'utiliser plutôt que la gestion du texte intégrée dans openGL.
    Après de très longues recherches et tentatives, mon texte ne s'affiche toujours pas : à la place, j'ai le rectangle blanc ci-dessous :
    Image utilisateur

    Voici mon code brièvement commenté :
    1. //J'ai créé une classe CTexture afin de gérer la génération/suppression des textures automatiquement ; ici le constructeur à partir d'une instance de la classe CText ; je pense que les noms parlent d'eux-mêmes
    2. CTexture::CTexture(CText text)
    3. {
    4.     unsigned int
    5.         w = (int)floor(pow(2, ceil(log(text.getWidth()) / log(2)))),
    6.         h = (int)floor(pow(2, ceil(log(text.getHeight()) / log(2))));
    7. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
    8.     Uint32
    9.         RMask = 0xff000000,
    10.         GMask = 0x00ff0000,
    11.         BMask = 0x0000ff00,
    12.         AMask = 0x000000ff;
    13. #else
    14.     Uint32
    15.         RMask = 0x000000ff,
    16.         GMask = 0x0000ff00,
    17.         BMask = 0x00ff0000,
    18.         AMask = 0xff000000;
    19. #endif
    20.     SDL_Surface *temp = SDL_CreateRGBSurface
    21.     (
    22.         SDL_HWSURFACE,
    23.         w,
    24.         h,
    25.         32,
    26.         RMask,
    27.         GMask,
    28.         BMask,
    29.         AMask
    30.     );
    31.     if (!temp)
    32.     {
    33.         SDL_FreeSurface(temp);
    34.         cerr << "Fatal error : unable to create texture from SDL surface : " << SDL_GetError() << endl;
    35.         bool error;
    36.         throw error;
    37.     }
    38.     SDL_Rect position;
    39.     position.x = 0; position.y = 0;
    40.     {
    41.         CSurface temp2(temp);//La classe CSurface correspond à une SDL_Surface*
    42.         text.blit(&position, &temp2);//CText hérite de CSurface, la méthode blit() correspond à SDL_BlitSurface()
    43.     }
    44.     SDL_PixelFormat format = text.getFormat();
    45.     format.BitsPerPixel  = 32;
    46.     format.BytesPerPixel = 4;
    47.     format.Rmask         = RMask;
    48.     format.Gmask         = GMask;
    49.     format.Bmask         = BMask;
    50.     format.Amask         = AMask;
    51.     text.convert(&format, SDL_SWSURFACE);//correspond à SDL_ConvertSurface()
    52.     text.flip();//Je vous ai posté le code de cette méthode plus bas
    53.     glGenTextures(1, &texture);//texture est un attribut GLuint de CTexture
    54.     glBindTexture(GL_TEXTURE_2D, texture);
    55.     glTexImage2D
    56.     (
    57.         GL_TEXTURE_2D,
    58.         0,
    59.         GL_RGBA,
    60.         temp->w,
    61.         temp->h,
    62.         0,
    63.         GL_BGRA,
    64.         GL_UNSIGNED_BYTE,
    65.         temp->pixels
    66.     );
    67.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    68.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    69. }

    A propos de la méthode CSurface::flip() :
    1. void CSurface::flip()
    2. {
    3.     int current_line,pitch;
    4.     SDL_Surface * fliped_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
    5.                                    surface->w,surface->h,//surface est un attribut SDL_Surface* de la classe CSurface
    6.                                    surface->format->BitsPerPixel,
    7.                                    surface->format->Rmask,
    8.                                    surface->format->Gmask,
    9.                                    surface->format->Bmask,
    10.                                    surface->format->Amask);
    11.     SDL_LockSurface(surface);
    12.     SDL_LockSurface(fliped_surface);
    13.     pitch = surface->pitch;
    14.     for (current_line = 0; current_line < surface->h; current_line ++)
    15.     {
    16.         memcpy(&((unsigned char* )fliped_surface->pixels)[current_line*pitch],
    17.                &((unsigned char* )surface->pixels)[(surface->h - 1  -
    18.                                                     current_line)*pitch],
    19.                pitch);
    20.     }
    21.     SDL_UnlockSurface(fliped_surface);
    22.     SDL_UnlockSurface(surface);
    23.     SDL_FreeSurface(surface);
    24.     surface = fliped_surface;
    25. }

    Vous l'aurez peut-être reconnue, c'est en fait la fonction flipSurface() du tutoriel de Kayl.
    Enfin, le code du main.cpp lui-même :
    1. //2D mode
    2.             glEnable2D();//voir plus bas
    3.             glDisable(GL_DEPTH_TEST);
    4.             //drawReference();
    5.             glColor3d(1, 1, 1);
    6.             hello.bind();//correspond à glBindTexture(), hello étant de type CTexture
    7.             glBegin(GL_QUADS);
    8.                 glTexCoord2f(0.0f, 1.0f); glVertex2f(position.x    , position.y);
    9.                 glTexCoord2f(1.0f, 1.0f); glVertex2f(position.x + w, position.y);
    10.                 glTexCoord2f(1.0f, 0.0f); glVertex2f(position.x + w, position.y + h);
    11.                 glTexCoord2f(0.0f, 0.0f); glVertex2f(position.x    , position.y + h);
    12.             glEnd();
    13.             glEnable(GL_DEPTH_TEST);
    14.             glDisable2D();//voir plus bas

    Enable/Disable2D :
    1. void glEnable2D()
    2. {
    3.     int vPort[4];
    4.     glGetIntegerv(GL_VIEWPORT, vPort);
    5.     glMatrixMode(GL_PROJECTION);
    6.     glPushMatrix();
    7.     glLoadIdentity();
    8.     glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
    9.     glMatrixMode(GL_MODELVIEW);
    10.     glPushMatrix();
    11.     glLoadIdentity();
    12. }
    13. void glDisable2D()
    14. {
    15.     glMatrixMode(GL_PROJECTION);
    16.     glPopMatrix();  
    17.     glMatrixMode(GL_MODELVIEW);
    18.     glPopMatrix();  
    19. }

    Je ne vous poste pas le code de chargement du texte par SDL_ttf qui utilise d'autres classes que j'ai créées, je pense que le problème n'y est pas et que vous avez suffisamment de code comme ça :D .
    Il ne me reste plus qu'à vous demander : où est mon erreur ?
    Merci d'avance !
    • Partager sur Facebook
    • Partager sur Twitter
      22 août 2007 à 14:45:52

      hum.
      ça peut venir de ta texture Hello qui est mal chargée.
      Essaie, juste pour voir, de texturer tes cubes derriere avec la texture Hello, pour voir.
      Ou alors l'inverse, essaie de mettre tes textures de cubes sur ton Quad porteur (le blanc) pour voir.
      (dans les 2 cas, il suffit de binder l'autre texture)
      Tu seras ainsi fixé sur le fait de savoir si ça vient de la texture qui est mal chargée ou pas.

      Dis moi ce que donnent ces tests, on verra en conséquence :)
      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        22 août 2007 à 14:55:39

        Image utilisateurImage utilisateur

        La première capture avec "hello" en texture, la seconde avec cube.bmp. Voili voilou !
        • Partager sur Facebook
        • Partager sur Twitter
          22 août 2007 à 15:26:55

          ok, donc ça confirmerait que ça vient de ta surface qui est mal chargée.
          Examine ta fonction de chargement de texture :
          - vérifie que ton nom de fichier appelé est correct
          - vérifie que ta fonction de SDL_ttf qui te genere la font ne renvoie pas NULL
          - vérifie tes parametres pour glTexImage2D.

          Au besoin, décactive ton traitement ".flip", qui retourne l'image, pour voir.
          • Partager sur Facebook
          • Partager sur Twitter

          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

            22 août 2007 à 15:49:10

            J'ai déjà implémenté et validé 2 classes CFont et CText, en cas de nom de fichier incorrect ou tout autre problème j'aurais eu un message d'erreur, ce qui n'est pas le cas. Je te poste le chargement de texte, a priori mes noms de méthodes sont assez explicites pour que tu devines leur role, je vais néanmoins commenter brièvement :
            1. //Setting text
            2.         CFont     font("georgia.ttf", 30);//se contente d'appeler TTF_OpenFont() et d'en vérifier le retour
            3.         SDL_Color color;
            4.         color.r = 255; color.g = 255; color.b = 255;
            5.         CText text("Hellolololol", &font, color, BLENDED);//appelle TTF_RenderText_Blended() ; CText hérite de CSurface qui contient un attribut SDL_Surface*
            6.         SDL_Rect position;
            7.         position.x = 100; position.y = 100;
            8. unsigned int
            9.             w = (int)floor(pow(2, ceil(log(text.getWidth()) / log(2)))),
            10.             h = (int)floor(pow(2, ceil(log(text.getHeight()) / log(2))));
            11.         //Creating textures
            12.         CTexture
            13.             cube("cube.bmp"),
            14.             hello(text);//constructeur à partir d'un CText que j'ai posté plus haut

            Quant aux paramètres pour glTexImage2D(), je ne suis pas très familier avec les différents flags possibles, il n'est pas impossible qu'il y ait une erreur, que me conseilles-tu de rentrer comme paramètres ?
            Concernant mon traitement ".flip", le désactiver ne provoque pas d'erreur mais me laisse sur mon rectangle blanc.
            • Partager sur Facebook
            • Partager sur Twitter
              22 août 2007 à 16:11:23

              Alors c'est peut etre une erreur au niveau de glTexImage2D(). Je n'utilise quasiement plus cette fonction : j'utilise du mipmapping.
              Je te propose la fonction que j'utilise personnellement pour convertir une texture SDL en Texture OpenGL.

              1. TexOGL TexMount(SDL_Surface* s,int mag,int min)
              2. {
              3.         int depth=s->format->BitsPerPixel;
              4.         TexOGL numtexture;
              5.         glGenTextures(1,&numtexture);   
              6.         glBindTexture(GL_TEXTURE_2D,numtexture);
              7.         if (depth!=32)
              8.                 return 0;
              9.         gluBuild2DMipmaps(GL_TEXTURE_2D,4, s->w, s->h,GL_RGBA,GL_UNSIGNED_BYTE,s->pixels);
              10.         glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER,min);
              11.         glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER,mag);
              12.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
              13.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
              14.         return numtexture;
              15. }


              Avec TexOGL = unsigned int.
              min et max sont les filtres que tu veux appliquer :
              avec comme bon compromis :
              int mag=GL_LINEAR,int min=GL_LINEAR_MIPMAP_NEAREST
              • Partager sur Facebook
              • Partager sur Twitter

              Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                22 août 2007 à 16:22:52

                Merci, cela fonctionne, même si ce n'est pas joli joli !
                Image utilisateur

                Existe-t-il un moyen d'améliorer le rendu et d'enlever le fond noir ?
                Je me demande si je ne vais pas finalement me tourner vers l'affichage de texte via openGL directement, je ne suis même pas certain de pouvoir continuer à utiliser SDL_ttf pour du texte 3D...
                • Partager sur Facebook
                • Partager sur Twitter
                  22 août 2007 à 16:43:02

                  OpenGL ne sait pas gérer des textes en natif, glut sait le faire, mais c'est bien plus laid :)

                  Pour enlever le fond :
                  j'utilise l'alpha-test : c'est a dire que je demande au PC de ne pas afficher le pixel si son canal alpha est plus grand que 128 (par exemple)

                  Pour activer ça :
                  1. glEnable(GL_ALPHA_TEST);
                  2.         glAlphaFunc(GL_LESS ,128);


                  Et tu vas me dire : oui, mais je définis ou les pixels qui seront a alpha>128 ?

                  Quand tu as encore ta texture SDL : donc avant de la monter en mémoire avec OpenGL, appelle cette fonction (qui fait un peu comme ta méthode flip, finalement : tu traitement au niveau des pixels)

                  Je te laisse adapter les fonctions par contre

                  1. void SetTransColor(SDL_Surface* tmp,uchar r,uchar v,uchar b)
                  2. {
                  3.         int i,j;
                  4.         ulong key = Color(r,v,b,0);  // construit le ulong a partir de r,v,b
                  5.         ulong aliaseBorder = Color(0,0,0,255); // pixel qui remplacera
                  6.         ulong pix;
                  7.         Lock(tmp); // SDL_LockSurface
                  8.         for(j=0;j<tmp->h;j++)
                  9.                 for(i=0;i<tmp->w;i++)
                  10.                 {
                  11.                         if (GetPixel(tmp,i,j)==key)
                  12.                         {
                  13.                                 PutPixel(tmp,i,j,aliaseBorder);
                  14.                         }
                  15.                         if (i==0 || j==0 || j==tmp->h-1 || j==tmp->w-1)
                  16.                         {
                  17.                                 pix = GetPixel(tmp,i,j);
                  18.                                 PA(pix)=255; // composante Alpha de pix modifiée
                  19.                                 PutPixel(tmp,i,j,pix);
                  20.                         }
                  21.                         else
                  22.                                 PA(pix)=0;
                  23.                 }
                  24.         Unlock(tmp); // UNLockSurface
                  25. }


                  Pour un exemple de cela fini, regarde mon programme Klostro-Laby, que tu trouveras dans ma signature : il utitise cette méthode de rendu de texte.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                    22 août 2007 à 18:15:10

                    Alors là cela devient compliqué, la scène 3D n'apparaît plus :
                    Image utilisateur

                    En m'appropriant un peu ta fonction, voici ce que j'obtiens :
                    1. void CSurface::setTransColor(Uint8 r,Uint8 v,Uint8 b)
                    2. {
                    3.     unsigned int
                    4.         i = 0,
                    5.         j = 0;
                    6.     Uint32
                    7.         oldPixel = SDL_MapRGBA(surface->format, r, v, b, 0),//Si j'ai bien compris, tes "Color" correspondent à SDL_MapRGBA() qui renvoit un Uint32 et demande des Uint8
                    8.         newPixel = SDL_MapRGBA(surface->format, 0, 0, 0, 255),
                    9.         pix;
                    10.     SDL_LockSurface(surface);
                    11.     while (j < surface->h)
                    12.     {
                    13.         while (i < surface->w)
                    14.         {
                    15.             if (getPixel(surface, i, j) == oldPixel)//J'ai trouvé les fonctions getPixel() et putPixel sur la documentation officielle de la SDL
                    16.             {
                    17.                 putPixel(surface, i, j, newPixel);
                    18.             }
                    19.             //Je n'ai pas saisi l'utilité du code qui suit, je suppose que PA signifie PutAlpha, mais à quoi sert donc la variable pix ? Elle n'est jamais utilisée dans le reste du code de la fonction...
                    20.             /*if (i == 0 || j == 0 || j == surface->h - 1 || j==surface->w-1)
                    21.             {
                    22.                 pix = getPixel(surface, i, j);
                    23.                 PA(pix)=255; // composante Alpha de pix modifiée
                    24.                 putPixel(surface,i,j,pix);
                    25.             }
                    26.             else
                    27.             PA(pix)=0;*/
                    28.             i++;
                    29.         }
                    30.         i = 0;
                    31.         j++;
                    32.     }
                    33.     SDL_UnlockSurface(surface);
                    34. }

                    Il faut noter qu'avec ou sans appel à cette fonction, le résultat est le même... J'ai dû faire plusieurs erreurs :-°
                    Je n'ai pas pu lancer ton jeu car je suis sous linux, mais d'après la capture d'écran la police semble lissée et jolie, pourquoi est-ce que j'obtiens quelque chose "beurré" ?
                    Autre question : pourquoi ne pas utiliser SDL_SetColorKey() avec le flag SDL_SRCCOLORKEY ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      22 août 2007 à 18:25:59

                      Il est a noter que c'est la surface ou il y a le texte a traiter pour l'alpha, et non pas la surface d'écran.

                      Ben faut faire d'autres tests :)
                      "pourquoi ne pas utiliser SDL_SetColorKey() avec le flag SDL_SRCCOLORKEY ? "
                      --> openGL n'utilise pas la meme gestion de textures/surfaces que SDL. A partir de la, je doute que SDL_SetColorKey fonctionne. Mais tu peux essayer !
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                        22 août 2007 à 18:47:51

                        Bon déjà j'ai réglé le problème de la scène 3D :
                        Image utilisateur

                        Demeure encore le fond noir...

                        Citation : Fvirtman

                        Il est a noter que c'est la surface ou il y a le texte a traiter pour l'alpha, et non pas la surface d'écran.


                        Que veux-tu dire exactement ? J'ai ajouté le traitement alpha comme ci-dessous, l'ai-je mal positionné ?
                        1. <...>
                        2. SDL_PixelFormat format = text.getFormat();
                        3.     format.BitsPerPixel  = 32;
                        4.     format.BytesPerPixel = 4;
                        5.     format.Rmask         = RMask;
                        6.     format.Gmask         = GMask;
                        7.     format.Bmask         = BMask;
                        8.     format.Amask         = AMask;
                        9.     text.setTransColor(0, 0, 0);
                        10.     text.convert(&format, SDL_SWSURFACE);
                        11.     text.flip();
                        12.     glGenTextures(1, &texture);
                        13.     glBindTexture(GL_TEXTURE_2D, texture);
                        14. <...>

                        Citation : Fvirtman

                        openGL n'utilise pas la meme gestion de textures/surfaces que SDL. A partir de la, je doute que SDL_SetColorKey fonctionne. Mais tu peux essayer !


                        A vrai dire j'avais déjà essayé, le résultat était le même... J'aurais juste pensé que SDL_SetColorKey() effectuait exactement la même chose que la fonction setTransColor() ; après tout, cette dernière agit également sur le texte en tant que surface SDL, et non en tant que texture openGL, donc il serait normal qu'elle ne fonctionne pas puisque "openGL n'utilise pas la meme gestion de textures/surfaces que SDL"...
                        Je serais justement plutôt tenté de réécrire setTransColor() à partir de la texture openGL si cela est possible, mais puisque tu as réussi à faire ton programme sans c'est que la solution n'est pas là...
                        • Partager sur Facebook
                        • Partager sur Twitter
                          22 août 2007 à 18:55:51

                          Ton dernier code a l'air bon :) c'est bien sur "test" que tu appliques transcolor, c'est ça que je voulais dire :)

                          Tu as bien enablé GL_ALPHA_TEST et la fonction qui va avec comme je t'ai dit plus haut ?
                          Surement que tu dois etre tout pret du but maintenant :)
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                            22 août 2007 à 19:46:07

                            J'ai trouvé !!!
                            En finale il y a plus simple que l'alpha-test, il faut bien utiliser SDL_SetColorKey() (m'est avis que tu l'as recodée à travers SetTransColor()), combinée avec SDL_DisplayFormatAlpha().
                            De plus j'avais fait des erreurs au niveau des différentes surfaces temp, voici le code complet brièvement commenté de la très controversée conversion surface SDL/texture openGL, enfin fonctionnelle :
                            1. CTexture::CTexture(CText text)
                            2. {
                            3.     unsigned int
                            4.         w = (int)floor(pow(2, ceil(log(text.getWidth()) / log(2)))),
                            5.         h = (int)floor(pow(2, ceil(log(text.getHeight()) / log(2))));
                            6. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                            7.     Uint32
                            8.         RMask = 0xff000000,
                            9.         GMask = 0x00ff0000,
                            10.         BMask = 0x0000ff00,
                            11.         AMask = 0x000000ff;
                            12. #else
                            13.     Uint32
                            14.         RMask = 0x000000ff,
                            15.         GMask = 0x0000ff00,
                            16.         BMask = 0x00ff0000,
                            17.         AMask = 0xff000000;
                            18. #endif
                            19.     SDL_Surface *temp = SDL_CreateRGBSurface
                            20.     (
                            21.         SDL_HWSURFACE,
                            22.         w,
                            23.         h,
                            24.         32,
                            25.         RMask,
                            26.         GMask,
                            27.         BMask,
                            28.         AMask
                            29.     );
                            30.     if (!temp)
                            31.     {
                            32.         SDL_FreeSurface(temp);
                            33.         cerr << "Fatal error : unable to create texture from SDL surface : " << SDL_GetError() << endl;
                            34.         bool error;
                            35.         throw error;
                            36.     }
                            37.     SDL_Rect position;
                            38.     position.x = 0; position.y = 0;
                            39.     CSurface temp2(temp);
                            40.     text.blit(&position, &temp2);
                            41.     //Toutes les instructions suivantes sont en fait inutiles
                            42.     /*SDL_PixelFormat format = text.getFormat();
                            43.     format.BitsPerPixel  = 32;
                            44.     format.BytesPerPixel = 4;
                            45.     format.Rmask         = RMask;
                            46.     format.Gmask         = GMask;
                            47.     format.Bmask         = BMask;
                            48.     format.Amask         = AMask;
                            49.     temp2.setTransColor(0, 0, 0);
                            50.     temp2.convert(&format, SDL_SWSURFACE);
                            51.     temp2.flip();*/
                            52.     SDL_Color color;
                            53.     color.r = 0; color.g = 0; color.b = 0;
                            54.     //Les 2 lignes suivantes permettent la transparence du fond noir
                            55.     temp2.setColorKey(SDL_SRCCOLORKEY, color);//appelle SDL_SetColorKey()
                            56.     temp2.displayFormatAlpha();//appelle SDL_DisplayFormatAlpha()
                            57.     glGenTextures(1, &texture);
                            58.     this->bind();
                            59.     gluBuild2DMipmaps(GL_TEXTURE_2D, 4, temp2.getWidth(), temp2.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, temp2.getPixels());//j'avais utilisé la CSurface text, alors qu'il faut bien la nouvelle CSurface temp2 de dimensions compatibles openGL (en puissance de 2)
                            60.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                            61.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                            62. }

                            Qui donne le résultat suivant :
                            Image utilisateur

                            Ah j'oubliais : il faut activer GL_BLEND ponctuellement pour l'affichage du texte.
                            Voili voilou ! Un grand merci à toi Fvirtman ! ;)
                            Dommage que je manque de temps libre, cela fait un parfait petit sujet de mini-tuto utile à beaucoup je pense !

                            [EDIT] Dernière petite parenthèse : il semble que mon texte ne soit pas antialiasé... Pourtant j'écris en mode Blended et j'utilise le mipmapping... Comment y remédier ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              24 août 2007 à 12:26:13

                              J'ai réussi à antialiaser mon texte, mais je rencontre encore un autre problème :
                              Image utilisateur

                              L'alpha n'a lui pas été antialiasé, ce qui me donne des bords noirs plutôt moches autour des lettres...
                              Voici mon code actuel :
                              1. CTexture::CTexture(const CText* text)
                              2. {
                              3.     unsigned int
                              4.         w = (int)floor(pow(2, ceil(log(text->getWidth()) / log(2)))),
                              5.         h = (int)floor(pow(2, ceil(log(text->getHeight()) / log(2))));
                              6. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                              7.     Uint32
                              8.         RMask = 0xff000000,
                              9.         GMask = 0x00ff0000,
                              10.         BMask = 0x0000ff00,
                              11.         AMask = 0x000000ff;
                              12. #else
                              13.     Uint32
                              14.         RMask = 0x000000ff,
                              15.         GMask = 0x0000ff00,
                              16.         BMask = 0x00ff0000,
                              17.         AMask = 0xff000000;
                              18. #endif
                              19.     SDL_Surface *temp = SDL_CreateRGBSurface
                              20.     (
                              21.         SDL_HWSURFACE,
                              22.         w,
                              23.         h,
                              24.         32,
                              25.         RMask,
                              26.         GMask,
                              27.         BMask,
                              28.         AMask
                              29.     );
                              30.     if (!temp)
                              31.     {
                              32.         SDL_FreeSurface(temp);
                              33.         cerr << "Fatal error : unable to create texture from SDL surface : " << SDL_GetError() << endl;
                              34.         bool error;
                              35.         throw error;
                              36.     }
                              37.     SDL_Rect position;
                              38.     position.x = 0; position.y = h - text->getHeight();
                              39.     CSurface temp2(temp);
                              40.     SDL_Color color;
                              41.     color.r = 0; color.g = 0; color.b = 0;
                              42.     temp2.fill(color);
                              43.     text->blit(&position, &temp2);
                              44.     temp2.setColorKey(SDL_SRCCOLORKEY, color);
                              45.     temp2.displayFormatAlpha();
                              46.     glGenTextures(1, &texture);
                              47.     this->bind();
                              48.     gluBuild2DMipmaps(GL_TEXTURE_2D, 4, temp2.getWidth(), temp2.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, temp2.getPixels());
                              49.     //glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, temp2.getWidth(), temp2.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp2.getPixels());
                              50.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                              51.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                              52. }

                              Avant d'afficher le texte, j'utilise les paramètres suivants :
                              1. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                              2.     glEnable(GL_BLEND);

                              Existe-t-il une fonction SDL permettant d'antialiaser l'alpha, où dois-je le faire manuellement ?
                              • Partager sur Facebook
                              • Partager sur Twitter
                                26 août 2007 à 10:22:09

                                Normalement c'est fait non?
                                Si ça ne le fait pas, change de bibliothèque pour le texte.
                                Mais au lieu de faire de l'alpha, fait du blend.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  26 août 2007 à 13:19:34

                                  Le probleme avec le blend, c'est que c'est plus calculatoire que l'alpha test, et il me semble que tu peux avoir des problemes avec le Z-buffer avec.
                                  L'alpha test est sympa car il fait un "tout ou rien" en ce qui concerne le rendu de chaque pixel.
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                    26 août 2007 à 18:19:49

                                    En l'occurrence, le tout-ou-rien ne me satisfait pas, puisque les bords noirs sont sensés être des pixels rouges semi-transparents vis-à-vis de la scène 3D, non vis-à-vis du fond noir...
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      26 août 2007 à 18:21:18

                                      C'est pas possible d'appeler 2 fois la fonction qui définit la couleur de transparence avec 2 couleurs différentes ?
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
                                        26 août 2007 à 18:37:36

                                        La méthode manuelle que je propose plus haut "SetTransColor" modifie les alpha en fonction d'une condition ou une autre.
                                        Si tu veux utiliser cette méthode, alors oui, c'est possible :) il te suffit de modifier la fonction pour la personnaliser.

                                        Si tu utilises une méthode toute faite, il faut voir ce qu'elle propose :)
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                          27 août 2007 à 8:41:07

                                          J'ai enfin la solution ! Le texte est bien antialiasé et sans bords noirs :
                                          1. CTexture::CTexture(CText* text)
                                          2. {
                                          3.     unsigned int
                                          4.         w = (int)floor(pow(2, ceil(log(text->getWidth()) / log(2)))),
                                          5.         h = (int)floor(pow(2, ceil(log(text->getHeight()) / log(2))));
                                          6. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                                          7.     Uint32
                                          8.         RMask = 0xff000000,
                                          9.         GMask = 0x00ff0000,
                                          10.         BMask = 0x0000ff00,
                                          11.         AMask = 0x000000ff;
                                          12. #else
                                          13.     Uint32
                                          14.         RMask = 0x000000ff,
                                          15.         GMask = 0x0000ff00,
                                          16.         BMask = 0x00ff0000,
                                          17.         AMask = 0xff000000;
                                          18. #endif
                                          19.     SDL_Surface *temp = SDL_CreateRGBSurface
                                          20.     (
                                          21.         SDL_HWSURFACE,
                                          22.         w,
                                          23.         h,
                                          24.         32,
                                          25.         RMask,
                                          26.         GMask,
                                          27.         BMask,
                                          28.         AMask
                                          29.     );
                                          30.     if (!temp)
                                          31.     {
                                          32.         SDL_FreeSurface(temp);
                                          33.         cerr << "Fatal error : unable to create texture from SDL surface : " << SDL_GetError() << endl;
                                          34.         bool error;
                                          35.         throw error;
                                          36.     }
                                          37.     text->setAlpha(0, 0);//Appel à SDL_SetAlpha()
                                          38.     CSurface temp2(temp);
                                          39.     SDL_Rect position;
                                          40.     position.x = 0; position.y = h - text->getHeight();
                                          41.     text->blit(&position, &temp2);
                                          42.     glGenTextures(1, &texture);
                                          43.     this->bind();
                                          44.     //gluBuild2DMipmaps(GL_TEXTURE_2D, 4, temp2.getWidth(), temp2.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, temp2.getPixels());
                                          45.     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, temp2.getWidth(), temp2.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp2.getPixels());
                                          46.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
                                          47.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
                                          48.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                                          49.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                                          50.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                                          51. }

                                          Puis
                                          1. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                                          2.     glEnable(GL_BLEND);

                                          Merci à vous !
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          SDL_ttf et openGL

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown