Pour gagner du temps nous allons voir en une fois comment implémenter l'éclairage d'une scène et l'affichage d'un texte en 3D, ainsi qu'un mixage de 3D et de 2D.

OpenGL demotextelum

Il existe 2 manières principales d'afficher du texte en OpenGL :

  • Affichage volumétrique : On convertit les données de la fonte qu'on appelle des glyphes en coordonnées spatiales en leur donnant une profondeur.
  • Affichage par texture : On utilise simplement une texture représentant les caractères à afficher.

En ce qui concerne l'éclairage il faut comprendre que la luminosité d'un pixel est le résultat d'une opération impliquant à la fois les paramètres de la texture et ceux de la lumière. On peut de plus activer plusieurs spots de lumières.

Afficher un texte 3D

Déclarer les types de données nécessaires :

On a besoin de la structure GLYPHMETRICSFLOAT et des constantes WGL_FONT_POLYGONS et WGL_FONT_LINES

OpenGL-TEL-TypeEtConstant

Il faut créer un tableau GLYPHMETRICSFLOAT qui recevra les données des glyphes, il doit être dimensionné avec le nombre de caractères désirés, si nous voulons tous les caractères de l'espace (Ascii 32) à z (Ascii 122) il faut écrire :

Global GMF(122 - 32 + 1) As GLYPHMETRICSFLOAT

Notez que ce n'est pas ce tableau qui va servir pour l'affichage mais qu'il est nécessaire pour initialiser des "Display List" (listes d'instructions d'affichage).

Les listes OpenGL sont des groupes d'instructions stockés directement dans la carte graphique pour un usage ultérieur. De ce fait l'affichage est plus rapide.

Récupérer les coordonnées des glyphes.

  • La fonte utilisée sera celle de la fenêtre dont nous passons le handle du device context en 1er paramètre.
  • On indique quel est le 1er code Ascii (32)
  • Le nombre de caractères à analyser : 122-32+1
  • A quel index de liste on commence (on peut mettre 1000 sans se poser de question, si on a pas généré d'autres listes avant, ou très peu)
  • La "déviation" du texte, une valeur différente de zéro indique qu'on veut une version simplifiée de la fonte.
  • Le style 3D du texte : WGL_FONT_LINES pour une version fil-de-fer, WGL_FONT_POLYGONS pour un volume.
  • Et enfin l'adresse du tableau GLYPHMETRICSFLOAT (notez qu'à la place on aurait pu aussi réserver un bloc mémoire avec Malloc()).

Void wglUseFontOutlines(Me.hDC, 32, 122 - 32 + 1, 1000, 0, 10, WGL_FONT_POLYGONS , V:GMF(0))

Une fois la fonction exécutée, GMF() contient les données des glyphes, et des listes OpenGL contenant les instructions d'affichages (glVertex(),glNormal(),glTranslate(),...) sont crées.

Affichage lors du rendu.

Les listes générées contiennent toutes une instruction glTranslate(), à moins de vouloir utiliser la fin du texte comme repère il faut toujours encapsuler l'appel à ces listes avec glPushMatrix() et glPopMatrix().

Pour afficher un seul caractère :

glCallList(1000 + (CodeAscii-32))

Pour afficher une chaine de caractères :

OpenGL-TEL-CallLists

L'éclairage

On active l'éclairage avec glEnable(GL_LIGHTING) puis on allume un ou plusieurs spots lumineux numérotés de 0 à 7 avec par exemple glEnable(GL_LIGHT0) pour le premier.

Comme dit en introduction il faut paramétrer les matériaux ET les lumières, les deux sont combinés par la fonction d'éclairage d'OpenGL. Pour accéder aux fonctions de paramétrage nous allons redéclarer les fonction glLightfv() et glMaterialfv() avec un alias afin de pouvoir y accéder en utilisant un vecteur de 4 single. La déclaration des ces fonctions souffrant d'un paramètre non-conforme au sein de la librairie OpenGL.inc.lg32. Notez qu'on pourrait aussi copier la source de la librairie et la recompiler avec la correction adéquate.

Pour les déclarer il faudra écrire :

OpenGL-TEL-Typev4fDeclare

Pour plus de facilité on va écrire la fonction v4f pour construire rapidement un vecteur de 4 single :

OpenGL-TEL-Funcv4f

Un paramètre important pour le matériau est GL_SHININESS. Il sert à spécifier un exposant pour la lumière spéculaire. Il peut prendre des valeurs de 0 à 128. Plus l'exposant est élevé plus le niveau de lumière spéculaire est diffus.

Autre point important : le positionnement des spots doit se faire avec la matrice MODEL_VIEW, elle doit en principe être placée dans la matrice inverse de la matrice de projection. Le plus simple étant de mémoriser les transformations afin de les appliquer dans le sens inverse dans la matrice MODEL_VIEW. Dans la pratique le mieux est d'implémenter des fonctions de transformation mémorisant une pile d'instruction. Il est possible aussi d'obtenir une matrice inverse avec des fonctions OpenGL. Pour l'exemple j'ai simplifié à l'extrême avec une simple rotation inverse.

Programme de démonstration

OpenGL-TexteEnLumiere

 

 

 

 

 

 

 

 

 

Comments est propulsé par CComment