Apprendre OpenGL moderne


précédentsommairesuivant

III. OpenGL

Avant de commencer, il nous faut présenter ce qu’est OpenGL. OpenGL est considéré comme une API (Application Program Interface) qui offre un vaste ensemble de fonctions permettant de manipuler des objets graphiques et des images. Cependant, OpenGL en lui-même n’est pas une API, mais simplement une spécification, développée et maintenue par le Khronos Group.

Logo OpenGL

La spécification OpenGL décrit exactement ce que sont les entrées et sorties de chaque fonction et comment elles doivent s’exécuter. C’est ensuite aux développeurs d’implémenter ces fonctions pour produire une solution. Puisque la spécification d’OpenGL ne donne pas les détails d’une implémentation, les implémentations peuvent présenter des différences tant que les résultats correspondent à la spécification (et apparaissent identiques pour l’utilisateur).

Les développeurs des bibliothèques OpenGL sont généralement les constructeurs de cartes graphiques. Chaque carte graphique présente ainsi sa propre version d’OpenGL, développée spécialement pour ce matériel. Lorsque l’on utilise OpenGL sur un système Apple, la bibliothèque OpenGL est maintenue par Apple lui-même ; sous Linux, il existe un mélange de versions fournies par les constructeurs, mais aussi des adaptations par des développeurs particuliers. Si l’on constate un comportement curieux d’OpenGL, cela est probablement la faute du fournisseur de la carte graphique (ou de ceux chargés de son développement ou de sa maintenance).

Lorsque l’on constate un bogue, cela se résout très généralement en mettant à jour les pilotes (drivers) de la carte graphique ; ces pilotes incluent les dernières versions d’OpenGL pour votre carte. Voilà pourquoi il est conseillé de mettre à jour régulièrement ses pilotes.

Khronos propose publiquement tous les documents de spécification pour toutes les versions d’OpenGL. Le lecteur intéressé peut trouver la spécification de la version 3.3 (celle que nous utiliserons) ici : une bonne lecture pour se plonger dans les détails d’OpenGL (notez que cela ne donne pas l’implémentation). Les spécifications donnent aussi la définition exacte de ce que doit réaliser chaque fonction.

III-A. Core-profile et Immediate mode

Avant, utiliser OpenGL impliquait de développer en mode immédiat (aussi appelé le fixed function pipeline). C’était une méthode assez facile pour créer des graphiques. La plupart des fonctionnalités étaient cachées dans les bibliothèques et les développeurs n’avaient pas beaucoup de liberté sur la façon d’opérer d’OpenGL. Les développeurs ont souhaité plus de flexibilité et ainsi les spécifications se sont assouplies, donnant aux développeurs plus de contrôle. Le mode immédiat est facile à comprendre et à utiliser, mais reste peu efficace. Pour cette raison, la spécification a commencé à déprécier le mode immédiat à partir de la version 3.2 et on a encouragé les développeurs à travailler avec le core-profile qui constitue une rupture dans la spécification d’OpenGL et qui supprime toutes les fonctionnalités à bannir.

Dans la version core-profile d’OpenGL, on est obligé d’utiliser des méthodes modernes. Si l’on essaie d’utiliser une fonction obsolète, OpenGL lève une erreur et s’arrête. L’avantage d’apprendre la méthode moderne est d’avoir un résultat plus flexible et efficace, mais cela est aussi plus difficile. Le mode immédiat cache bon nombre d’opérations, alors qu’avant, bien que plus facile à appréhender, il était difficile de savoir comment travaillait OpenGL. L’approche moderne demande au développeur de vraiment comprendre OpenGL et la programmation graphique. Bien que cela soit un peu difficile, cela autorise plus de flexibilité, d’efficacité, et surtout une meilleure compréhension de la programmation graphique.

Pour ces raisons, nos tutoriels sont tournés vers la version 3.3 d’OpenGL Core-Profile. Bien que plus compliqué, cela vaut vraiment l’effort.

Aujourd’hui, des versions plus élaborées d’OpenGL sont disponibles (4.5 à la date de ce document) et vous pouvez donc vous demander : pourquoi apprendre OpenGL 3.3 alors qu’on en est à 4.5 ? La réponse est assez simple. Toutes les versions futures d’OpenGL à partir de 3.3 ajouteront des fonctionnalités sans changer le mécanisme du noyau. Les versions récentes seront simplement légèrement plus efficaces ou fourniront des moyens plus faciles pour certaines tâches, mais tous les concepts et les techniques resteront les mêmes dans les versions d’OpenGL moderne ; il est ainsi légitime d’apprendre avec la version 3.3. Avec plus d’expérience, vous pourrez profiter sans difficultés des dernières améliorations d’OpenGL.

Si vous utilisez les fonctionnalités des dernières versions d’OpenGL, seules les cartes graphiques les plus récentes pourront faire fonctionner votre application. C’est pourquoi les développeurs utilisent des versions moins récentes et ne présentent les fonctionnalités plus récentes qu’en option.

Dans certains chapitres, vous pourrez trouver des fonctionnalités plus récentes, elles seront alors indiquées comme telles.

III-B. Les extensions

Une caractéristique importante d’OpenGL est sa capacité à supporter des extensions. Quand un fabricant de cartes propose une nouvelle technique ou une optimisation de rendu, cela se trouve souvent dans une extension, implémentée dans le pilote (driver). Si le matériel supporte cette amélioration, le développeur peut utiliser cette fonctionnalité pour un meilleur résultat, sans attendre qu’OpenGL l’inclue dans une version ultérieure. Il suffit de vérifier que cette extension est supportée par la carte graphique. Lorsqu’une extension devient courante ou se révèle utile, OpenGL l’intègre dans sa nouvelle version.

Le développeur devra donc interroger OpenGL pour savoir si l’extension est disponible (ou encore utiliser une bibliothèque d’extension d’OpenGL) :

 
Sélectionnez
if(GL_ARB_extension_name)
{
    // Utiliser les trucs récents supportés par le matériel
}
else
{
    // Extension non supportée : on utilise la vieille méthode
}

Avec OpenGL 3.3, nous aurons rarement besoin d’une extension, mais lorsque ce sera nécessaire, le moyen de l’utiliser sera présenté.

III-C. Machine à états

OpenGL est une énorme machine à états : un ensemble de variables qui définissent comment OpenGL doit fonctionner, nommé contexte OpenGL. On modifie souvent cet état au moyen d’options, en manipulant des tampons (buffers), pour finalement effectuer un rendu dans le contexte en cours.

Par exemple, si l’on souhaite afficher des lignes plutôt que des triangles, on changera l’état d’OpenGL en modifiant une variable de contexte qui impose à OpenGL sa façon de dessiner.

Nous verrons plusieurs fonctions qui changent le contexte OpenGL et d’autres fonctions qui réalisent des opérations en fonction de ce contexte. Si vous gardez à l’esprit qu’OpenGL est une machine à état, la plupart des fonctionnalités vous apparaîtront plus claires.

III-D. Les objets

Les bibliothèques OpenGL sont écrites en C et permettent d’utiliser d’autres langages, mais cela reste un noyau en C. Comme beaucoup de fonctionnalités du C ne se traduisent pas si bien dans d’autres langages, OpenGL a été développé en tenant compte de plusieurs abstractions. L’une d’entre elles est la notion d’objet.

Un objet dans OpenGL est un ensemble d’options qui représente un sous-ensemble de l’état d’OpenGL. Par exemple, on trouvera un objet qui représente les paramètres d’affichage d’une fenêtre. On peut ainsi définir sa taille, le nombre de couleurs, etc. Un objet peut être visualisé comme une structure en C :

 
Sélectionnez
struct object_name {
    float  option1;
    int    option2;
    char[] name;
};

Pour utiliser un objet, cela ressemblera à ceci (le contexte d’OpenGL étant vu comme une grande structure) :

 
Sélectionnez
// Etat d’OpenGL
struct OpenGL_Context {
        ...
        object* object_Window_Target;
        ...     
};

// créer l’objet
unsigned int objectId = 0;
glGenObject(1, &objectId);

// relier cet objet à GL_WINDOW_TARGET
glBindObject(GL_WINDOW_TARGET, objectId);

// définir les options voulues pour cet objet
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);

// remettre les options par défaut
glBindObject(GL_WINDOW_TARGET, 0);

Ce petit bout de code est un schéma que l’on trouvera souvent en travaillant avec OpenGL. On crée d’abord un objet et l’on mémorise une référence à cet objet dans un entier (les données réelles de l’objet sont cachées). On relie ensuite cet objet à l’endroit cible du contexte (ici GL_WINDOW_TARGET). Ensuite, on positionne les options voulues et finalement on détache cet objet en spécifiant 0 comme id de l’objet. Les options sont mémorisées dans l’objet référencé par objectId et sont réappliquées dès lors que l’on relie à nouveau cet objet à GL_WINDOW_TARGET.

Ce qui est important avec l’utilisation de ces objets est la possibilité de définir plusieurs objets dans notre application, de définir les options qu’il contiendra, et lorsque l’on fera une opération utilisant l’état d’OpenGL, il suffira de relier cet objet à la cible correspondante pour disposer des options contenues dans cet objet. Il y a des objets qui sont par exemple des conteneurs pour les données d’un modèle 3D (une maison ou un simple caractère), et lorsque l’on voudra l’afficher, il suffira de relier cet objet. Disposer de plusieurs objets nous permettra de référencer plusieurs modèles et pour les utiliser nous relierons l’objet souhaité avant d’effectuer le rendu, sans avoir besoin de préciser à nouveau toutes les options.

III-E. On peut commencer

Maintenant, vous savez ce qu’est OpenGL, comment cela fonctionne à peu près et connaissez quelques trucs pour l’utiliser. Pas de souci si vous n’avez pas tout compris, nous avancerons pas à pas dans ces tutoriels et vous disposerez d’exemples pour vous familiariser avec OpenGL. Nous allons créer une première fenêtre dans le chapitre suivant.

III-F. Ressources supplémentaires

  • opengl.org : site officiel d’OpenGL.
  • OpenGL registry : spécifications et extensions pour toutes les versions d’OpenGL.

III-G. Remerciements

Ce tutoriel est une traduction réalisée par Jean-Michel Fray dont l’original a été écrit par Joey de Vries et qui est disponible sur le site Learn OpenGL.


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 © 2018 Joey de Vries. 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.