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

Découvrez OpenGL 1.1 en VB6/VBA

Image non disponible


précédentsommairesuivant

XVII. L'affichage de textes

Il y a deux façons d'afficher du texte :

  • afficher un bitmap (c'est-à-dire une image) représentant chaque lettre du texte ;
  • afficher chaque lettre du texte en 3D avec des vertices.

Si le texte est fixe, il est également possible de créer le texte sous forme d'une image (avec Paint par exemple), et d'appliquer une texture sur un rectangle blanc pour afficher ce texte.

Si on souhaite afficher un texte dynamique, il faut afficher chaque lettre du texte sur un rectangle.
On crée alors une texture contenant la table des caractères et on précise les coordonnées de texture correspondant au caractère à dessiner.

XVII-A. Affichage d'un texte bitmap statique

Voici l'image de texture utilisée :

Image non disponible

C'est un simple texte rouge sur fond noir créé avec Paint.

Comme pour les autres textures, on la charge et on sauvegarde l'identifiant dans une variable :

En en-tête de module
Sélectionnez
' Identifiant de la texture du texte statique
Private gTextureTexte As Long
Chargement de la texture du texte statique dans InitScene
Sélectionnez
gTextureTexte = TextureAddFromFile(CurrentProject.Path & "\texte.bmp")

Ensuite, à la fin de la procédure de rendu Render, on crée un rectangle et on lui applique la texture :

Création du rectangle avec le texte statique en texture
Sélectionnez
' Affichage d'un texte sur un rectangle
' Sauvegarde la matrice
glPushMatrix
' Affecte la texture
glBindTexture GL_TEXTURE_2D, gTextureTexte
' Filtrage de la texture
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
' Dessin d'un rectangle
glColor3VB vbWhite
glBegin GL_QUADS
    glTexCoord2d 0, 0
    glVertex2d -3, -0.5
    glTexCoord2d 1, 0
    glVertex2d -1, -0.5
    glTexCoord2d 1, 1
    glVertex2d -1, 0.5
    glTexCoord2d 0, 1
    glVertex2d -3, 0.5
glEnd
' N'affecte aucune texture
glBindTexture GL_TEXTURE_2D, 0
' Restaure la matrice
glPopMatrix

Ne pas oublier d'affecter une couleur blanche au rectangle (car on est en mode GL_MODULATE pour l'application des textures).

Le texte est alors affiché sur un rectangle qui est éclairé et qui tourne avec le reste de la scène :

Image non disponible

On souhaite afficher un texte d'information qui est éclairé en permanence uniformément.
On va donc déjà désactiver la lumière avant l'affichage du texte,et la réactiver ensuite.

Avant le dessin du texte
Sélectionnez
' Désactive la lumière
glDisable GL_LIGHTING
Après le dessin du texte
Sélectionnez
' Active la lumière
glEnable GL_LIGHTING

Ainsi le rectangle est éclairé par la lumière ambiante par défaut.

Si on souhaite rendre le fond noir transparent, il faut :

  • charger la texture avec le noir transparent (deuxième paramètre) :
    gTextureTexte = TextureAddFromFile(CurrentProject.Path & "\texte.bmp", vbBlack);
  • activer la gestion de la transparence avant rendu du texte (ou à l'initialisation de la scène si on laisse la transparence activée tout le temps) :
    glEnable GL_BLEND
    glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA.
Création du rectangle avec le texte statique en texture et avec transparence
Sélectionnez
' Affichage d'un texte sur un rectangle
' Désactive la lumière
glDisable GL_LIGHTING
' Sauvegarde la matrice
glPushMatrix
' Affecte la texture
glBindTexture GL_TEXTURE_2D, gTextureTexte
' Filtrage de la texture
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
' Active la transparence
glEnable GL_BLEND
glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
' Dessin d'un rectangle
glColor3VB vbWhite
glBegin GL_QUADS
    glTexCoord2d 0, 0
    glVertex2d -3, -0.5
    glTexCoord2d 1, 0
    glVertex2d -1, -0.5
    glTexCoord2d 1, 1
    glVertex2d -1, 0.5
    glTexCoord2d 0, 1
    glVertex2d -3, 0.5
glEnd
' N'affecte aucune texture
glBindTexture GL_TEXTURE_2D, 0
' Restaure la matrice
glPopMatrix
' Active la lumière
glEnable GL_LIGHTING
' Désactive la transparence
glDisable GL_BLEND

Le texte est maintenant affiché sur un fond transparent :

Image non disponible

La méthode avec GL_BLEND est générique, car elle permet de gérer l'affichage translucide.
Pour un affichage totalement transparent, préférez l'utilisation de l'alpha-test (GL_ALPHA_TEST).

On souhaite maintenant afficher un texte d'information à un endroit précis de l'écran.
C'est-à-dire qu'on souhaite que le texte s'affiche par exemple en bas à gauche, et ne se déplace pas lorsqu'on tourne ou redimensionne la scène.

Pour y arriver, on va passer en mode de projection orthonormée le temps de dessiner le texte.
On met en place une projection orthonormée (glOrtho) dont le plan est défini par les coordonnées (-1,-1) et (1,1).

Puis on se place (gluLookAt) au centre un peu en retrait.

On peut alors définir notre rectangle en fonction du plan de projection, (-1,-1) étant le point en bas à gauche :

Création du rectangle avec le texte statique en texture, avec transparence, et fixe en bas à gauche
Sélectionnez
' Affichage d'un texte statique sur un rectangle
' Passage en matrice de projection
glMatrixMode GL_PROJECTION
' Projection orthonormée
glLoadIdentity
glOrtho -1, 1, -1, 1, 0, 0
' Retour en matrice de visualisation-modélisation
glMatrixMode GL_MODELVIEW
glLoadIdentity
gluLookAt 0, 0, 1, 0, 0, 0, 0, 1, 0
' Désactive la lumière
glDisable GL_LIGHTING
' Sauvegarde la matrice
glPushMatrix
' Affecte la texture
glBindTexture GL_TEXTURE_2D, gTextureTexte
' Filtrage de la texture
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameterf GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
' Active la transparence
glEnable GL_BLEND
glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
' Dessin d'un rectangle en bas à gauche
glColor3VB vbWhite
glBegin GL_QUADS
    glTexCoord2d 0, 0
    glVertex2d -1, -1
    glTexCoord2d 1, 0
    glVertex2d -0.4, -1
    glTexCoord2d 1, 1
    glVertex2d -0.4, -0.8
    glTexCoord2d 0, 1
    glVertex2d -1, -0.8
glEnd
' N'affecte aucune texture
glBindTexture GL_TEXTURE_2D, 0
' Restaure la matrice
glPopMatrix
' Active la lumière
glEnable GL_LIGHTING
' Désactive la transparence
glDisable GL_BLEND

Le texte est dessiné en bas à gauche, et y reste même si on tourne autour de la scène :

Image non disponible

Voici donc une méthode assez simple pour afficher un texte statique, qui peut également être utilisée pour afficher un logo par exemple.

XVII-B. Affichage d'un texte bitmap dynamique avec freeGLUT

Pour la suite, nous souhaitons afficher le frame rate non plus dans la barre de titre de la fenêtre, mais sur l'image en haut à gauche.
freeGLUT met à notre disposition une fonction très facile à utiliser : glutBitmapString.

Pour positionner le texte, il faut utiliser une fonction glRasterPos* (car la fonction de dessin de texte de freeGLUT utilise la fonction glBitmap).

On conserve notre projection orthonormée : donc pour placer le texte en haut à gauche il faut le placer :

  • en X à -1 ;
  • en Y à 1 - (la hauteur du texte).

La hauteur du texte peut être récupérée en pixels avec la fonction glutBitmapHeight.
La hauteur de la fenêtre peut être récupérée en pixels avec la fonction glutGet(GLUT_WINDOW_HEIGHT).

Une division nous donnera la taille du texte dans l'unité openGL.

D'après la définition du plan de la projection :

  • le bas de la fenêtre est à une ordonnée de -1 ;
  • le haut de la fenêtre est à une ordonnée de 1.

Donc on a 1 unité pour une demi-hauteur d'une fenêtre :
Image non disponible   glutBitmapHeight(GLUT_BITMAP_TIMES_ROMAN_24) / (glutGet(GLUT_WINDOW_HEIGHT) / 2) est la taille du texte en unités OpenGL

Commençons par retirer le frame rate de la barre de titre.
Après calcul, on le sauvegarde dans une variable.

En en-tête de module
Sélectionnez
' Frame rate
Private gFrameRate As Double
Calcul et sauvegarde le frame rate
Sélectionnez
' Calcul et affichage du frame rate
gDisplayCount = gDisplayCount + 1
If gDisplayCount = 100 Then
    gFrameRate = gDisplayCount / (glutGet(GLUT_ELAPSED_TIME) - gElapsedTime) * 1000
    gDisplayCount = 0
    gElapsedTime = glutGet(GLUT_ELAPSED_TIME)
End If

Et on affiche ce frame rate en haut à gauche, en couleur bleue :
(Ajoutez ce code dans la procédure render.)

Affichage du frame rate en haut à gauche
Sélectionnez
' Affichage du frame rate
glColor3VB vbBlue
glRasterPos2d -1, 1 - glutBitmapHeight(GLUT_BITMAP_TIMES_ROMAN_24) / (glutGet(GLUT_WINDOW_HEIGHT) / 2)
glutBitmapString GLUT_BITMAP_TIMES_ROMAN_24, "Frame rate : " & format(gFrameRate, "0,0")

Au lieu de GLUT_BITMAP_TIMES_ROMAN_24, on peut choisir :

GLUT_BITMAP_9_BY_15, GLUT_BITMAP_8_BY_13 , GLUT_BITMAP_TIMES_ROMAN_10, GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10, GLUT_BITMAP_HELVETICA_12 ou GLUT_BITMAP_HELVETICA_18.

Pour positionner le texte, on peut également utiliser glutBitmapLength pour obtenir la largeur du texte.

Voici le frame rate affiché sur l'image :

Image non disponible

freeGLUT nous offre donc une fonction très simple pour afficher du texte.

XVII-C. Affichage d'un texte bitmap dynamique avec Windows

Sous Windows, nous avons à notre disposition la fonction wglUseFontBitmaps.
Cette fonction permet de générer des listes d'affichage contenant les caractères d'une police.

Il faut d'abord créer une police de caractères avec gdi32.
Ensuite l'appel à wglUseFontBitmaps génère les listes d'affichage.
Et enfin on affiche le texte en appelant ces listes avec glCallLists.

Image non disponible   Importez le module standard ModOpenGLFontTools
Ce module contient deux fonctions VB de gestion des textes :

  • une fonction CreateFontBitmap qui crée les listes ;
  • une fonction DrawText qui affiche le texte.

La création d'une police de caractères se fait avec la fonction gdi32 CreateFont.

Il nous suffit maintenant :

  • d'ajouter en en-tête du module principal la déclaration de l'identifiant de liste d'affichage :
En en-tête de module
Sélectionnez
' Identifiant de la liste pour le texte
Private gListTexte As Long
  • de créer les listes d'affichage dans la procédure d'initialisation InitScene :
Dans InitScene
Sélectionnez
' Création des listes pour le texte
gListTexte = CreateFontBitmap("Arial")
  • et enfin d'appeler la fonction DrawText (au lieu de glutBitmapString) pour afficher le texte :
Dessin du texte affichant le frame rate
Sélectionnez
' Affichage du frame rate
glColor3VB vbBlue
glRasterPos2d -1, 1 - 20 / (glutGet(GLUT_WINDOW_HEIGHT) / 2)
DrawText "Frame rate : " & format(gFrameRate, "0,0"), gListTexte

Nous n'avons pas ici de fonction simple à notre disposition pour retrouver la taille du texte.
J'ai mis 20 empiriquement.

XVII-D. Affichage d'un texte 3D dynamique avec Windows

Sous Windows, nous avons à notre disposition la fonction wglUseFontOutlines.
Cette fonction permet de générer des listes d'affichage contenant les caractères d'une police sous forme 3D.
C'est-à-dire avec des vertices et même une épaisseur.

Il faut d'abord, comme pour la fonction précédente, créer une police de caractères avec gdi32.
Ensuite l'appel à wglUseFontOutlines génère les listes d'affichage.
Et enfin on affiche le texte en appelant ces listes avec glCallLists.

Image non disponible   Importez le module standard ModOpenGLFontTools
Ce module contient une fonction VB de gestion des textes 3D, la fonction CreateFontOutline qui crée les listes.

Il nous suffit maintenant :

  • de remplacer l'appel à CreateFontBitmap par un appel à CreateFontOutline :
Dans InitScene
Sélectionnez
' Création des listes pour le texte
' On extrude de 0.3 pour donner de la profondeur au texte
gListTexte = CreateFontOutline("Arial", 0.3)
  • et de modifier le positionnement du texte.

On utilise pour les textes 3D les fonctions de transformation de la matrice de modélisation-visualisation :

Dessin du texte 3D affichant le frame rate
Sélectionnez
' Affichage du frame rate
glColor3VB vbYellow
glPushMatrix
glTranslated -1, 1 - 20 / (glutGet(GLUT_WINDOW_HEIGHT) / 2), 0
glScaled 0.2, 0.2, 0.2
DrawText "Frame rate : " & format(gFrameRate, "0,0"), gListTexte
glPopMatrix

On ne voit pas beaucoup de changement, le texte semble toujours en 2D.
C'est normal, car on dessine le texte avec une projection orthonormée.
Pour voir le texte en 3D, il faut l'afficher avant le passage dans cette projection.

Dessin du texte 3D affichant le frame rate, avant le changement de projection
Sélectionnez
' Affichage du frame rate en 3D
glColor3VB vbYellow
glPushMatrix
glTranslated -3, 2, 2
DrawText "Frame rate : " & format(gFrameRate, "0,0"), gListTexte
glPopMatrix

Le texte s'affiche alors en 3D, et suit les transformations de la scène :

Image non disponible

XVII-E. Affichage d'un texte bitmap dynamique : méthode générique

Les techniques que nous venons de voir nécessitent freeGLUT ou Windows.
Comment faire pour dessiner du texte de manière plus générique ?

Il faut générer « à la main » les listes d'affichage.
Pour nous aider, on peut utiliser des outils de création de textures à partir de polices de caractères.
Par exemple : Bitmap Font Builder permet de générer une image contenant une table de caractères.
On obtient une image de ce type :

Image non disponible

Et en parallèle on peut extraire la taille de chaque caractère dans un fichier texte.

Il faut ensuite générer une liste par caractère.
Chaque liste est un quad contenant quatre vertices et les quatre coordonnées de la texture qui correspondent au caractère.
La taille du quad et les coordonnées de texture sont fonction de la position du caractère dans la table et de la largeur de ce caractère.

L'idée est de se créer un module réutilisable de gestion des textures pour faire toutes ces opérations.

Si vous avez bien suivi jusqu'ici, vous devriez être capable de programmer un tel module.


précédentsommairesuivant

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