Les extensions OpenGL en VBA et VB6

Image non disponible


précédentsommairesuivant

VIII. Les Shaders

Les Shaders sont de petits programmes exécutés par la carte graphique.
Ils sont très efficaces et permettent de programmer de nombreux effets très rapides.
Ces programmes sont écrits en langage GLSL, abréviation de OpenGL Shading Language.
Ce langage est proche du C, vous en trouverez les spécifications sur le site d'OpenGL : OpenGL Shading Language.

Nous n'allons pas détailler ici le langage GLSL : nous allons « juste » apprendre à intégrer ces programmes dans notre application en VB.

VIII-A. Préparation de l'environnement de développement VB

Préparez votre application pour afficher un cube, tel qu'il est expliqué ci-dessus dans la section V : Préparation de l'environnement de développement VB.

Les Shaders sont apparus avec la version 2.0, ils sont supportés par les cartes graphiques récentes, mais pas par certaines cartes graphiques des PC bureautiques.

Commençons par vérifier que la carte graphique les supporte, en plaçant ce code avant l'appel à InitScene :

Teste le support des textures 3D
Sélectionnez
' Teste si les Shaders sont supportés
If val(LongToString(glGetString(GL_VERSION))) < 2 Then
    MsgBox "Shaders non supportés", vbOKOnly
    Exit Function 
End If

Bien entendu, Exit Function est à remplacer par Exit Sub si le test est codé dans la procédure Main d'une application VB6.
Si les Shaders ne sont pas supportés, on affiche un message et on quitte la fonction.

Importez maintenant le module ModOpenGL_2_0 qui contient les fonctions de la version 2.0.
N'oubliez pas de « mapper » ensuite les fonctions en exécutant la procédure RemapVBToGL de ce module.

Initialisation des fonctions
Sélectionnez
' Initialise les fonctions
ModOpenGL_2_0.RemapVBToGL

Nous voici prêts à programmer les Shaders !

VIII-B. Shader et Program

Il y a deux notions à connaître :

  • les Shaders ;
  • et les Programs.

Le principe est assez simple :

  1. On crée un Shader.
  2. On définit son code source en GLSL.
  3. On compile le Shader
  4. On crée un Program.
  5. On attache le Shader au Program.
  6. On génère le Program exécutable (étape de linkage).
  7. On peut utiliser le Program.

On pourra activer ou désactiver un Program au cours du rendu.

La complication en VB est la gestion des chaînes de caractères.
OpenGL utilise des chaînes de caractères multioctets alors que VB utilise des chaînes Unicode.
Nous utiliserons donc la fonction StrConv pour convertir les chaînes de caractères.
De plus les paramètres sont des pointeurs, que nous obtenons avec la fonction StrPtr ou VarPtr selon les cas.

VIII-C. Les types de Shaders

Il y a trois types de Shaders :

  • les Shaders de sommets (Vertex Shaders) qui agissent sur la position des Vertex ;
  • les Shaders de pixels (Fragement Shaders) qui agissent sur la couleur des pixels de l'image ;
  • les Shaders de géométrie (Geometry Shaders) apparus avec le Shader Model 4.0 d'OpenGL 3.

VIII-D. Mon premier Shader

Pour débuter, nous allons créer et utiliser un Shader très simple.
Celui-ci modifie la couleur de chaque pixel afin qu'il soit rouge.
Ce programme n'est pas très utile, mais a le mérite d'être simple pour un premier exemple.

Voici le code GLSL de ce Shader :

Code du Shader
Sélectionnez
void main(void)
{
gl_FragColor = vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) ;
}

Il est en effet très simple :

  • pour chaque pixel dessiné, la procédure main est appelée ;
  • gl_FragColor renvoie une couleur fixe (couleur rouge).

Voyons maintenant comment intégrer ce programme dans notre code VB.

VIII-E. Génération du programme exécutable par la carte graphique

Dans la procédure InitScene, générons un Shader.

Génération du Shader
Sélectionnez
'Génération du Shader
Dim lShader As Long
lShader = glCreateShader(GL_FRAGMENT_SHADER)

GL_FRAGMENT_SHADER désigne un Shader de pixel, car nous souhaitons agir sur la couleur des pixels.

Ensuite il faut définir le code source du Shader grâce à la fonction glShaderSource.
Nous écrivons ce code dans une variable lShaderString de type String.
Il est également possible d'écrire le code source dans un fichier texte et de le charger en VB.
On peut ainsi écrire des Shaders facilement réutilisables.

Code source du Shader
Sélectionnez
' Code source du Shader
Dim lShaderString As String	
lShaderString = "void main(void)" & _
                "{" & _
                "gl_FragColor = vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) ;" & _
                "}"

Ce code source doit être converti en multioctets :

Code source du Shader
Sélectionnez
' Conversion
lShaderString = StrConv(lShaderString, vbFromUnicode)

Puis on injecte le code source dans le Shader :

Injecte le code source dans le Shader
Sélectionnez
' Injecte le code source dans le Shader
glShaderSource lShader, 1, VarPtr(lShaderString), LenB(lShaderString)

On passe en paramètre le pointeur vers la chaîne de caractères : on obtient ce pointeur grâce à la fonction VarPtr.
Et en dernier paramètre, on précise la taille de la chaîne de caractères : il est important d'utiliser la fonction LenB.

Notez le deuxième paramètre égal à 1.
Ce paramètre précise le nombre de chaînes de caractères qui sont passées dans le troisième paramètre.
Ici on n'a qu'une seule chaîne de caractères.
Pour préciser plusieurs chaînes, il faut les stocker dans un tableau.
On donne alors :

  • en deuxième paramètre le nombre de lignes dans ce tableau ;
  • en troisième paramètre un pointeur vers le premier élément de ce tableau ;
  • et en quatrième paramètre un pointeur vers le premier élément d'un tableau contenant les tailles de chaque chaîne de caractères.

Il faut maintenant compiler le Shader :

Compile le Shader
Sélectionnez
' Compile le Shader
glCompileShader lShader

Cette compilation est effectuée par la carte graphique.
On peut ensuite lire le statut de la compilation :

Statut de compilation
Sélectionnez
' Lecture du statut de compilation
Dim lStatus As Long
glGetShaderiv lShader, GL_COMPILE_STATUS, lStatus

Si lStatus contient GL_TRUE, alors la compilation s'est correctement déroulée.
Dans le cas contraire il est possible de lire le journal de compilation :

Journal de compilation
Sélectionnez
If lStatus <> GL_TRUE Then
    ' Taille du journal
    glGetShaderiv lShader, GL_INFO_LOG_LENGTH, lSize
    ' Lecture du journal
    lLog = Space(lSize)
    glGetShaderInfoLog lShader, lSize, lSize, StrPtr(lLog)
    ' Écriture du journal dans la fenêtre de débogage
    Debug.Print StrConv(lLog, vbUnicode)
End If

La lecture de ce journal se fait en deux temps :

  1. Il faut d'abord lire la taille du journal ;
  2. Ensuite on lit le journal en spécifiant sa taille.

La chaîne de caractères qui reçoit le journal doit être d'une taille suffisante, on initialise donc la variable lLog avec autant d'espaces que la taille du journal.
Puis la fonction glGetShaderInfoLog demande un pointeur vers cette variable ; on utilise ici encore la fonction StrPtr.

Finalement, on écrit le journal en prenant soin de convertir la variable au format Unicode.

Pour tester ce journal de compilation, modifiez le code source de manière à générer une erreur.

Par contre si la compilation s'est correctement déroulée, on continue le traitement en générant le programme.

On utilise un identifant de programme déclaré en en-tête de module :

Identifiant du programme
Sélectionnez
' Identifiant du programme
Private gProgram As Long

Puis on génère le programme à la suite du code précédent :

Génère le Program
Sélectionnez
Else
    ' Génère un identifiant de programme
    gProgram = glCreateProgram
    ' Attache le shader au programme
    glAttachShader gProgram, lShader
    ' Génère le programme exécutable
    glLinkProgram gProgram
    ' Statut du liage
    glGetProgramiv gProgram, GL_LINK_STATUS, lStatus
    If lStatus <> GL_TRUE Then
        ' Taille du journal
        glGetProgramiv lShader, GL_INFO_LOG_LENGTH, lSize
        ' Lecture du journal
        lLog = Space(lSize)
        glGetProgramInfoLog lShader, lSize, lSize, StrPtr(lLog)
        ' Écriture du journal dans la fenêtre de débogage
        Debug.Print StrConv(lLog, vbUnicode)
    End If
    ' Supprime le shader
    glDeleteShader lShader
End If

glLinkProgram peut également provoquer une erreur : on récupère alors le journal de la même manière que pour la compilation du Shader.

C'est seulement lorsque cette étape de lien s'est correctement déroulée que le Program est utilisable.
On peut alors supprimer le Shader qui n'est plus utile (glDeleteShader).

VIII-F. Utilisation du programme

Il est maintenant très simple d'utiliser le programme.
Il suffit d'appeler la fonction glUseProgram afin de définir l'utilisation du programme.

Avant le dessin du cube, activez le programme :

Active le programme
Sélectionnez
' Active le programme
glUseProgram gProgram

Et après le dessin du cube, désactivez-le :

Désactive le programme
Sélectionnez
' Désactive le programme
glUseProgram 0&

Exécutez l'application : le cube est coloré en rouge.

Image non disponible

Cet effet n'est pas spectaculaire, mais en utilisant des shaders plus complexes on peut mettre en œuvre des effets comme ceux qu'on voit souvent dans les jeux vidéo.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

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 © 2009 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.