Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques
API graphiques Forum d'entraide sur les API et bibliothèques graphiques 2D et 3D
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 14/04/2011, 02h27   #1
Davidlouiz
Nouveau Membre du Club
 
Inscription : avril 2007
Messages : 64
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 64
Points : 36
Points : 36
Par défaut Afficher du texte avec SDL_ttf dans un environnement OpenGL

Bonjour,

Il y a quelques jours, j'ai rencontré un problème d'affichage de texte sur l'un de mes PC. Sur le PC sur lequel je développe je ne rencontre pas ce problème d'affichage. J'ai testé sur le PC d'un copain, il n'y avait pas de problème.

Je ne sais pas du tout d'où peut venir le problème. J'aimerais donc avoir de l'aide.

Le seul symptôme apparent que je peux vous fournir est le suivant : Sur le PC en question, le texte s'affiche salement uniquement lorsque l'application d'une texture précède l'application du texte à l'écran.

Pour essayer de clarifier les choses, je me suis ramené à un programme simple qui affiche une image de fond puis un texte. Lorsque l'image de fond n'est pas appliqué à l'écran, le texte s'affiche correctement, autrement, j'ai ça :



Sur le PC sur lequel le programme fonctionne bien, j'ai ça :



Pour afficher mon texte à l'écran, je créé un SDL_Surface comportant mon texte à afficher. Je créé une texture OpenGL à partir de cette surface. Puis j'applique la texture à l'écran.

Pour l'image de fond, c'est grossièrement la même chose, sauf qu'au lieu de créer la SDL_Surface avec la fonction TTF_RenderText_Blended(), je la créé avec la fonction SDL_LoadBMP().

La grande différence notable entre une image et un texte, c'est que ce dernier comporte de la transparence.

Si vous voyez d'où peut venir le problème, merci de me le faire savoir.

Voici à disposition la source du programme simplifié.

Code :
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <GL/gl.h>
#include <GL/glu.h>
 
void chargerTexture(const char* nomFichier, GLuint* texture, int* largeur, int* hauteur)
{
    SDL_Surface *surface;
    GLenum formatTexture;
    GLint  octetsParPixel;
 
    // Creationde la surface SDL a partir du fichier de la texture
    surface = SDL_LoadBMP(nomFichier);
 
    if (NULL != surface)
    {
 
        // Verification de la largeur
        if ( 0 != (surface->w & (surface->w - 1)) )
        {
            printf("Attention : la largeur de %s n'est pas une puissance de 2\n ", nomFichier);
        }
 
        // Verification de la hauteur
        if ( 0 != (surface->h & (surface->h - 1)) )
        {
            printf("Attention : la hauteur de %s n'est pas une puissance de 2\n ", nomFichier);
        }
 
        // Recuperation du nombre d'octets par pixel
        octetsParPixel = surface->format->BytesPerPixel;
 
        if (octetsParPixel == 4) // Contient une composante alpha
        {
            if (surface->format->Rmask == 0x000000ff)
            {
                formatTexture = GL_RGBA;
            }
            else
            {
                #ifndef GL_BGRA
                    #define GL_BGRA 0x80E1
                #endif
                formatTexture = GL_BGRA;
            }
        }
        else if (octetsParPixel == 3) // Pas de composante alpha
        {
            if (surface->format->Rmask == 0x000000ff)
            {
                formatTexture = GL_RGB;
            }
            else
            {
                #ifndef GL_BGR
                    #define GL_BGR 0x80E0
                #endif
                formatTexture = GL_BGR;
            }
        }
        else
        {
            printf("Attention : l'image n'est pas en couleur vraie\n");
            SDL_FreeSurface(surface);
            return;
        }
 
        // Activation des textures
        glEnable(GL_TEXTURE_2D);
 
        // Generation de la texture
        glGenTextures(1, texture);
 
        // Selection de la texture
        glBindTexture(GL_TEXTURE_2D, *texture);
 
        // Initialisation des propriétés de la texture
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
        // Chargement de la texture
        gluBuild2DMipmaps(GL_TEXTURE_2D, octetsParPixel, surface->w, surface->h, formatTexture,GL_UNSIGNED_BYTE, surface->pixels);//AJ
 
        // Recuperation de la taille de la texture
        *largeur = surface->w;
        *hauteur = surface->h;
 
        // Liberation de la surface SDL de la texture
        SDL_FreeSurface(surface);
    }
    else
    {
        printf("SDL ne peut pas charger l'image %s : %s\n", nomFichier, SDL_GetError());
        *texture = 0;
        *largeur = 1;
        *hauteur = 1;
    }
}
 
void creerTextureTexte(const char* texte, GLuint* textureTexte, const char* policeTexte, unsigned int taille, int* largeurTexte, int* hauteurTexte)
{
    // Creation de l'image du texte avec la police associee
    SDL_Color couleurTexte = {50, 50, 50};
    TTF_Font* police = TTF_OpenFont(policeTexte, taille);
    SDL_Surface* texteEtiquette = TTF_RenderText_Blended(police, texte, couleurTexte);
    TTF_CloseFont(police);
    if (NULL == texteEtiquette)
    {
        printf("Impossible de créer le texte de l'etiquette");
    }
 
    // Activation de la transparence
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
    // Generation de la texture du texte
    glGenTextures(1, textureTexte);
 
    // Selection de la texture generee
    glBindTexture(GL_TEXTURE_2D, *textureTexte);
 
    // Parametrage
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
    // Detection du codage des pixels
    GLenum codagePixel;
    if (texteEtiquette->format->Rmask == 0x000000ff)
    {
        codagePixel = GL_RGBA;
    }
    else
    {
        #ifndef GL_BGRA
            #define GL_BGRA 0x80E1
        #endif
        codagePixel = GL_BGRA;
    }
 
    // Chargement de la texture du texte precedament creee
    glTexImage2D(GL_TEXTURE_2D, 0, 4, texteEtiquette->w, texteEtiquette->h, 0,
                  codagePixel, GL_UNSIGNED_BYTE, texteEtiquette->pixels);
 
    //Recuperation des dimentions du texte
    *largeurTexte = texteEtiquette->w;
    *hauteurTexte = texteEtiquette->h;
 
    // Liberation de l'image du texte du bouton
    SDL_FreeSurface(texteEtiquette);
}
 
int main()
{
    // Demarrage de SDL avec le module video
    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();
 
    // Creation de la fenetre initialisee pour fonctionner avec OpenGL
    #define LARGEUR_FENETRE 640
    #define HAUTEUR_FENETRE 480
    SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE, 32, SDL_OPENGL);
 
    // Chargement de l'image de fond du menu
    GLuint textureFondMenu;
    int largeurFondMenu, hauteurFondMenu;
    chargerTexture("fond_menu.bmp", &textureFondMenu, &largeurFondMenu, &hauteurFondMenu);
 
    // Creation de la texture du texte a afficher
    GLuint textureTexte;
    int largeurTexte, hauteurTexte;
    creerTextureTexte("Mon texte a afficher", &textureTexte, "Cartonsix NC.ttf", 65, &largeurTexte, &hauteurTexte);
 
    // Boucle principale
    int continuer = 1;
    while (continuer)
    {
        // Gestion des evenements
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            if(SDL_QUIT == event.type)
            {
                continuer = 0;
            }
        }
 
        // En 2D
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
 
        // Definition de la fenetre
        gluOrtho2D(0.0, (GLdouble)LARGEUR_FENETRE, 0.0, (GLdouble)HAUTEUR_FENETRE);
 
        // Desactivation du test de profondeur
        glDisable(GL_DEPTH_TEST);
 
        // Vidage de l'image
        glClear(GL_COLOR_BUFFER_BIT);
 
        // Selection de l'image de fond
        glBindTexture(GL_TEXTURE_2D, textureFondMenu);
 
        // Application de l'image de fond
        glBegin(GL_QUADS);
            glTexCoord2d(0, 0); glVertex2f(0, HAUTEUR_FENETRE);
            glTexCoord2d(0, 1); glVertex2f(0, 0);
            glTexCoord2d(1, 1); glVertex2f(LARGEUR_FENETRE, 0);
            glTexCoord2d(1, 0); glVertex2f(LARGEUR_FENETRE, HAUTEUR_FENETRE);
        glEnd();
 
        // Selection du texte
        glBindTexture(GL_TEXTURE_2D, textureTexte);
 
        // Application du texte
        #define POSITION_X (LARGEUR_FENETRE/2)
        #define POSITION_Y (HAUTEUR_FENETRE/2)
        glBegin(GL_QUADS);
            glTexCoord2i(0, 0); glVertex2i( POSITION_X - (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y + (hauteurTexte/2));
            glTexCoord2i(0, 1); glVertex2i( POSITION_X - (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y - (hauteurTexte/2));
            glTexCoord2i(1, 1); glVertex2i( POSITION_X + (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y - (hauteurTexte/2));
            glTexCoord2i(1, 0); glVertex2i( POSITION_X + (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y + (hauteurTexte/2));
        glEnd();
 
        // Affichage du dessin
        glFlush();
        SDL_GL_SwapBuffers();
 
        SDL_Delay(10);
    }
 
    // Suppression des textures
    glDeleteTextures(1, &textureFondMenu);
    glDeleteTextures(1, &textureTexte);
 
    // Arret de la SDL
    SDL_Quit();
 
    return 0;
}
Merci pour l’intérêt porté à ce sujet.
Davidlouiz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2011, 13h28   #2
Kannagi
Membre émérite
 
Avatar de Kannagi
 
Homme
Inscription : mai 2010
Messages : 465
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : mai 2010
Messages : 465
Points : 844
Points : 844
Envoyer un message via MSN à Kannagi
Je pense que le code est bon , mais que c'est un problème de compatibilité avec Opengl ,je que je dis ne résoudra peut être pas ton problème mais tu peux essayer.
Mon ordi supporte mal les textures qui ne sont pas en puissance de 2^N et il a du mal avec GLBind ,donc peut être que tu devrai essayer de mettre directement glTexImage2D, et de mettre ton image en puissance 2^N ,en remplissant par exemple le surplus par un alpha transparent(j'avais répondu dans un autre post comment faire).

En espérant avoir pu t’être utile.
Kannagi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2012, 22h52   #3
Davidlouiz
Nouveau Membre du Club
 
Inscription : avril 2007
Messages : 64
Détails du profil
Informations forums :
Inscription : avril 2007
Messages : 64
Points : 36
Points : 36
En effet, ça venait de là. Merci.

Voici le code avec les modifications.

Code :
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <cmath>

void chargerTexture(const char* nomFichier, GLuint* texture, int* largeur, int* hauteur)
{
    SDL_Surface *surface;
    GLenum formatTexture;
    GLint  octetsParPixel;

    // Creationde la surface SDL a partir du fichier de la texture
    surface = SDL_LoadBMP(nomFichier);

    if (NULL != surface)
    {

        // Verification de la largeur
        if ( 0 != (surface->w & (surface->w - 1)) )
        {
            printf("Attention : la largeur de %s n'est pas une puissance de 2\n ", nomFichier);
        }

        // Verification de la hauteur
        if ( 0 != (surface->h & (surface->h - 1)) )
        {
            printf("Attention : la hauteur de %s n'est pas une puissance de 2\n ", nomFichier);
        }

        // Recuperation du nombre d'octets par pixel
        octetsParPixel = surface->format->BytesPerPixel;

        if (octetsParPixel == 4) // Contient une composante alpha
        {
            if (surface->format->Rmask == 0x000000ff)
            {
                formatTexture = GL_RGBA;
            }
            else
            {
                #ifndef GL_BGRA
                    #define GL_BGRA 0x80E1
                #endif
                formatTexture = GL_BGRA;
            }
        }
        else if (octetsParPixel == 3) // Pas de composante alpha
        {
            if (surface->format->Rmask == 0x000000ff)
            {
                formatTexture = GL_RGB;
            }
            else
            {
                #ifndef GL_BGR
                    #define GL_BGR 0x80E0
                #endif
                formatTexture = GL_BGR;
            }
        }
        else
        {
            printf("Attention : l'image n'est pas en couleur vraie\n");
            SDL_FreeSurface(surface);
            return;
        }

        // Activation des textures
        glEnable(GL_TEXTURE_2D);

        // Generation de la texture
        glGenTextures(1, texture);

        // Selection de la texture
        glBindTexture(GL_TEXTURE_2D, *texture);

        // Initialisation des propriétés de la texture
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // Chargement de la texture
        gluBuild2DMipmaps(GL_TEXTURE_2D, octetsParPixel, surface->w, surface->h, formatTexture,GL_UNSIGNED_BYTE, surface->pixels);//AJ

        // Recuperation de la taille de la texture
        *largeur = surface->w;
        *hauteur = surface->h;

        // Liberation de la surface SDL de la texture
        SDL_FreeSurface(surface);
    }
    else
    {
        printf("SDL ne peut pas charger l'image %s : %s\n", nomFichier, SDL_GetError());
        *texture = 0;
        *largeur = 1;
        *hauteur = 1;
    }
}

int puissance2sup(int i)
{
    double logbase2 = log(i) / log(2);
    return (int)round(pow(2.0, ceil(logbase2)));
}

void creerTextureTexte(const char* texte, GLuint* textureTexte, const char* policeTexte, unsigned int taille, int* largeurTexte, int* hauteurTexte)
{
    // Creation de l'image du texte avec la police associee
    SDL_Color couleurTexte = {50, 50, 50};
    TTF_Font* police = TTF_OpenFont(policeTexte, taille);
    SDL_Surface* texteEtiquette = TTF_RenderText_Blended(police, texte, couleurTexte);
    TTF_CloseFont(police);
    if (NULL == texteEtiquette)
    {
        printf("Impossible de créer le texte de l'etiquette");
    }

    // Activation de la transparence
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Generation de la texture du texte
    glGenTextures(1, textureTexte);

    // Selection de la texture generee
    glBindTexture(GL_TEXTURE_2D, *textureTexte);

    // Parametrage
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Detection du codage des pixels
    GLenum codagePixel;
    if (texteEtiquette->format->Rmask == 0x000000ff)
    {
        codagePixel = GL_RGBA;
    }
    else
    {
        #ifndef GL_BGRA
            #define GL_BGRA 0x80E1
        #endif
        codagePixel = GL_BGRA;
    }

    // Chargement de la texture du texte precedament creee
    glTexImage2D(GL_TEXTURE_2D, 0, 4, puissance2sup(texteEtiquette->w), puissance2sup(texteEtiquette->h), 0, codagePixel, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texteEtiquette->w, texteEtiquette->h, codagePixel, GL_UNSIGNED_BYTE, texteEtiquette->pixels);

    //Recuperation des dimentions du texte
    *largeurTexte = texteEtiquette->w;
    *hauteurTexte = texteEtiquette->h;

    // Liberation de l'image du texte du bouton
    SDL_FreeSurface(texteEtiquette);
}

int main(int argc, char* argv[])
{
    // Demarrage de SDL avec le module video
    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();

    // Creation de la fenetre initialisee pour fonctionner avec OpenGL
    #define LARGEUR_FENETRE 640
    #define HAUTEUR_FENETRE 480
    SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE, 32, SDL_OPENGL);

    // Chargement de l'image de fond du menu
    GLuint textureFondMenu;
    int largeurFondMenu, hauteurFondMenu;
    chargerTexture("fond_menu.bmp", &textureFondMenu, &largeurFondMenu, &hauteurFondMenu);

    // Creation de la texture du texte a afficher
    GLuint textureTexte;
    int largeurTexte, hauteurTexte;
    creerTextureTexte("Mon texte a afficher", &textureTexte, "Cartonsix NC.ttf", 65, &largeurTexte, &hauteurTexte);

    // Boucle principale
    int continuer = 1;
    while (continuer)
    {
        // Gestion des evenements
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            if(SDL_QUIT == event.type)
            {
                continuer = 0;
            }
        }

        // En 2D
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);

        // Definition de la fenetre
        gluOrtho2D(0.0, (GLdouble)LARGEUR_FENETRE, 0.0, (GLdouble)HAUTEUR_FENETRE);

        // Desactivation du test de profondeur
        glDisable(GL_DEPTH_TEST);

        // Vidage de l'image
        glClear(GL_COLOR_BUFFER_BIT);

        // Selection de l'image de fond
        glBindTexture(GL_TEXTURE_2D, textureFondMenu);

        // Application de l'image de fond
        glBegin(GL_QUADS);
            glTexCoord2d(0, 0); glVertex2f(0, HAUTEUR_FENETRE);
            glTexCoord2d(0, 1); glVertex2f(0, 0);
            glTexCoord2d(1, 1); glVertex2f(LARGEUR_FENETRE, 0);
            glTexCoord2d(1, 0); glVertex2f(LARGEUR_FENETRE, HAUTEUR_FENETRE);
        glEnd();

        // Selection du texte
        glBindTexture(GL_TEXTURE_2D, textureTexte);

        // Application du texte
        #define POSITION_X (LARGEUR_FENETRE/2)
        #define POSITION_Y (HAUTEUR_FENETRE/2)
        glBegin(GL_QUADS);
            glTexCoord2f(0, 0); glVertex2i( POSITION_X - (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y + (hauteurTexte/2));
            glTexCoord2f(0, hauteurTexte / (float)puissance2sup(hauteurTexte)); glVertex2i( POSITION_X - (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y - (hauteurTexte/2));
            glTexCoord2f(largeurTexte / (float)puissance2sup(largeurTexte), hauteurTexte / (float)puissance2sup(hauteurTexte)); glVertex2i( POSITION_X + (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y - (hauteurTexte/2));
            glTexCoord2f(largeurTexte / (float)puissance2sup(largeurTexte), 0); glVertex2i( POSITION_X + (largeurTexte/2), HAUTEUR_FENETRE - POSITION_Y + (hauteurTexte/2));
        glEnd();

        // Affichage du dessin
        glFlush();
        SDL_GL_SwapBuffers();

        SDL_Delay(10);
    }

    // Suppression des textures
    glDeleteTextures(1, &textureFondMenu);
    glDeleteTextures(1, &textureTexte);

    // Arret de la SDL
    SDL_Quit();

    return 0;
}
Davidlouiz est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 00h15.


 
 
 
 
Partenaires

Hébergement Web