OpenGL 3.x : un point sur les nouveautés

Michaël Gallego

Cette nouvelle série de tutoriels a pour but de vous présenter les nouveautés apportées par OpenGL 3.x et, surtout, comment les utiliser. Ce premier chapitre vous présente une liste non-exhaustive de ces nouveautés.

- Titre : OpenGL 3.x : un point sur les nouveautés

- Auteur : Michaël Gallego

- Parution : 21 juin 2009

- Licence :

Sommaire

- 0. Introduction

- I. OpenGL 3.0

- I-A. Déprécation

- I-B. Framebuffer objects

- I-C. Texture arrays

- I-D. Nouveaux formats de texture

- I-E. Vertex Array Object

- I-F. Mise à jour du langage de shader

- II. OpenGL 3.1

- II-A. Suppression du pipeline fixe

- II-B. Texture buffer object

- II-C. Texture rectangle

- II-D. Uniform buffer object

- II-E. Mise à jour du langage de shader

- III. Comment profiter d'OpenGL 3.x ?

- IV. Conclusion

- V. Liens

- VI. Remerciements

0 - Introduction

Officiellement standardisé en 1992 par l'OpenGL Architecture Review Board (ARB), OpenGL a, depuis la version 2.1 sortie en 2006, connu que peu de changements et, de ce fait, lui a fait prendre beaucoup de retard par rapport à son concurrent direct, DirectX.

La sortie d'OpenGL 3.0 en août 2008 et, plus récemment, celle d'OpenGL 3.1 en mars 2009, marquent un retour sur le devant de la scène d'OpenGL, poussée par de nombreuses améliorations qui le rapproche de nouveau de son ennemi de toujours.

Ce premier tutoriel a pour unique vocation de faire un point rapide sur les nouveautés apportées par ces deux nouvelles versions.

I - OpenGL 3.0

Sortie en août 2008, la version 3.0 a longtemps créé la polémique. Devant être une refonte complète de l'API (nom de code « Long Peaks »), cette nouvelle version n'a finalement été qu'une (grosse) évolution de l'API. Voici une liste non exhaustive de ces nouveautés :

I-A - Déprécation

OpenGL 3.0 a pour vocation de supprimer au maximum le pipeline fixe en obligeant le programmeur à utiliser le plus possible les shaders, même pour un simple programme affichant un cube, ce qui ne facilite évidemment pas son apprentissage pour les débutants.

C'est pourquoi OpenGL 3.0 a introduit un système de déprécation : plutôt que de supprimer toutes ces fonctionnalités, elles sont plutôt marquées comme dépréciées, ce qui signifie que le programmeur est invité à ne plus les utiliser, mais qu'il peut le faire s'il le souhaite.

Dans ce tutoriel, nous allons éviter toute utilisation de fonctions dépréciées.

I-B - Framebuffer objects

Pour effectuer un rendu off-screen sous OpenGL 2.1, on utilisait, de manière générale, l'extension GL_EXT_framebuffer_object. Celle-ci était parfois couplée avec les extensions GL_EXT_framebuffer_blit, GL_EXT_packed_depth_stencil et GL_ EXT_framebuffer_multisample.

Cette extension a dorénavant été acceptée par l'ARB, et les 4 extensions citées précédemment font maintenant parties d'une seule et même extension : GL_ARB_framebuffer_object. A part quelques points modifiés (notamment, il est dorénavant possible d'attacher des textures de formats différents à un même FBO), son fonctionnement reste similaire aux extensions précédentes.

I-C - Texture arrays

Cette nouvelle fonctionnalité, introduite par l'extension GL_EXT_texture_array, permet d'avoir des « tableaux » de textures à 1 ou 2 dimensions, afin de réduire le nombre d'envois et d'appels à glUniform*.

I-D - Nouveaux formats de texture

Restons dans les textures avec l'extension GL_ARB_texture_rg, très utile et dont le but est d'être utilisée conjointement avec les FBO, et qui ajoute de nouveaux formats à 1 et 2 champs (en gros, en plus des formats GL_RGB ou GL_RGBA, on dispose maintenant des formats GL_RED et GL_RG).

I-E - Vertex Array Object

Cette extension, nommée GL_ARB_vertex_array_object, permet de simplifier l'utilisation des VBO (Vertex Buffer Object) en évitant de nombreux appels redondants à glVertexPointer ou glNormalPointer (ces fonctions sont d'ailleurs dépréciées en OpenGL 3, nous verrons par quoi les remplacer dans un futur tutoriel de cette série).

Cette extension sera également présentée dans un autre tutoriel de la série.

I-F - Mise à jour du langage de shader

Enfin, OpenGL 3.0 apporte une mise à jour du langage de shader, OpenGL Shading Language (ou GLSL, pour faire plus court), qui passe en version 1.30. Celui-ci offre notamment de nouvelles fonctions built-in (trunc(), round(). Pour plus de détails, je vous suggère de lire la documentation officielle de GLSL 1.30).

II - OpenGL 3.1

OpenGL 3.1 marque un nouveau tournant dans l'histoire d'OpenGL, comme nous allons le voir dans les parties qui suivent.

II-A - Suppression du pipeline fixe

Le modèle de déprécation d'OpenGL 3.0 dont nous parlions plus haut n'existe désormais plus en OpenGL 3.1. A la place, toutes ces fonctionnalités sont supprimées. Bien sûr, cela pose un problème dans les entreprises qui, notamment, ont des dizaines de milliers de lignes de code qui reposent sur le pipeline fixe. Pour eux, OpenGL 3.1 a introduit une extension nommée GL_ARB_compatibility qui offre toutes ces fonctionnalités, mais elles ne sont désormais plus accessibles sans l'usage de cette extension. De plus, les fabricants qui produiront du hardware compatible OpenGL 3.1 pourront éventuellement ne pas implémenter cette extension. Toutefois, compte tenu de l'utilisation massive de le pipeline fixe, il y a fort à parier que les « gros » constructeurs continueront à supporter le pipeline fixe via cette extension pendant encore de longues années.

Bien sûr, je vous suggère de NE PAS utiliser cette extension.

II-B - Texture buffer object

Cette fonctionnalité est introduite par l'extension GL_ARB_texture_buffer_object. Elle permet de créer un nouveau type de texture 1D qui, bien que n'imposant aucune contrainte concernant la taille (notamment, elle permet un stockage très important), ne supportent pas le mipmapping ou n'importe quel type de filtrage. Cette extension peut s'avérer utile dans le cas de calcul générique à effectuer sur le GPU.

II-C - Texture rectangle

Longtemps utilisable via l'extension GL_EXT_texture_rectangle, cette fonctionnalité est enfin introduite officiellement dans le coeur d'OpenGL via l'extension GL_ARB_texture_rectangle. Elle permet de créer des textures de n'importe quelle taille dont l'accès aux différents texels dans un shader ne se fait pas avec des coordonnées normalisées.

II-D - Uniform buffer object

Autre nouveauté très importante introduite par OpenGL 3.1 : les uniform buffer object (ou UBO). Cette fonctionnalité sera traitée dans un tutoriel de cette série. Auparavant, l'envoi de variables uniform à un shader s'effectuait obligatoirement par des appels à la fonction glUniform.

Pour faire simple, les variables uniform peuvent à présent être stockées dans un buffer (on remarque au passage que, après les VBO, IBO et autre FBO, les variables uniform ont aussi le droit à leur buffer ;)). On ne met à jour le buffer que lorsque les variables changent, autrement il n'est pas nécessaire de le modifier (ce qui évite de nombreux appels inutiles à glUniform).

II-E - Mise à jour du langage de shader

Comme tout le temps, le langage de shader GLSL est mis à jour et passe en version 1.40, afin de refléter notamment les ajouts du langage (UBO par exemple).

III - Comment profiter d'OpenGL 3.x ?

Tout ça, c'est bien beau, mais comment profiter de toutes ces nouveautés ? Tout d'abord, il convient de télécharger les derniers drivers de votre carte graphique. A l'heure où j'écris, nVidia et AMD disposent de drivers entièrement OpenGL 3.0, et seul nVidia a développé des drivers compatibles, en partie, OpenGL 3.1 (ceci ne devrait pas tarder pour AMD).

Deuxièmement, il faut créer un contexte compatible avec ces nouvelles versions d'OpenGL. Le contexte peut être créé manuellement grâce à l'utilisation de l'extension WGL_ARB_create_context introduite avec OpenGL 3.0. Toutefois, les bibliothèques de fenêtrage les plus célèbres disposent déjà de version permettant de créer ces contextes de manière automatique.

A l'heure où j'écris ces lignes, la version alpha 1.3 de la SDL permet de créer un contexte OpenGL 3, tandis que la version expérimentale de la SFML (version 2.0) disponible sur le site officie permet également de créer un contexte OpenGL 3 de manière totalement transparente. Quoi qu'il en soit, pour vérifier que le contexte créé soit bien compatible avec OpenGL 3, il suffit d'appeler la fonction glGetString avec la constante GL_VERSION. Si la chaîne de caractère retournée est quelque chose comme 3.0.xxxx ou 3.1.xxxx, alors le contexte est compatible.

Dernière étape, il faut pouvoir charger toutes ces nouvelles extensions. La manière la plus simple est d'utiliser une bibliothèque tierce comme GLEE (disponible ici : http://elf-stone.com/glee.php) ou GLEW (disponible ici : http://glew.sourceforge.net/). A l'heure actuelle, ces deux bibliothèques offrent un support complet d'OpenGL 3.0 mais pas encore d'OpenGL 3.1 (mais cela ne saurait tarder, je suppose.).

Parlons également du fichier d'en-tête. Traditionnellement, pour utiliser OpenGL, on incluait le fichier d'en-tête GL/gl.h. Si on utilisait une bibliothèque comme GLEW, on incluait alors uniquement le fichier GL/glew.h, qui incluait lui-même GL/gl.h, GL/glu.h ainsi que GL/glext.h. Toutefois, procéder ainsi avec OpenGL 3.x ne nous empêche en rien d'utiliser des fonctionnalités dépréciées (puisque ces fonctions sont encore disponibles dans les fichiers d'en-tête traditionnel). De plus, le fichier de base gl.h commençait à devenir sérieusement obsolète avec des fonctions peu ou plus utilisées.

Dorénavant, la spécification officiel d'OpenGL 3.1 nous invite à utiliser un nouveau fichier d'en-tête, gl3.h, à placer dans le dossier GL3, et donc d'avoir uniquement cette ligne :

#include <GL3/gl3.h>

Ce nouveau fichier d'en-tête est déjà disponible en version expérimentale sur le site officielle d'OpenGL, et peut être téléchargé à cette adresse : http://www.opengl.org/registry/api/gl3.h. Bien que ce fichier ne soit pas encore totalement finalisé, il a l'avantage d'être déjà très propre et surtout vous empêche d'utiliser des fonctions dépréciées. Pour les versions futures d'OpenGL, un nouveau fichier sera mis en ligne, nommé simplement gl3ext.h, qui contiendra les points d'entrées et les constantes des extensions futures.

Pour les personnes souhaitant utiliser le pipeline fixe, elles devront continuer à utiliser les traditionnels GL/gl.h et GL/glext.h puisque l'extension GL_ARB_compatibility n'est pas présente dans le fichier GL/gl3.h.

Bref, une bonne pratique à faire est donc de télécharger le fichier gl3.h, créer un nouveau dossier GL3. Pour utiliser ces extensions, il vous suffira donc de linker à votre application les fichiers opengl32.lib et glew32.lib, et de n'inclure que le fichier gl3.h (et non glew.h, puisque celui-ci contient encore toutes les fonctions dépréciées). Lorsque de nouvelles extensions sortirons, ajoutez simplement le fichier gl3ext.h que vous pourrez télécharger sur le site d'OpenGL, mettez à jour votre version de GLEW ou GLEE afin d'obtenir le dernier .lib, et voilà ! Comme ça, plus d'utilisation accidentelle de fonctionnalités dépréciées !

Reste un tout dernier point à aborder : parmi les fonctionnalités apportées par OpenGL 3.x, certaines concernent des extensions qui étaient déjà présentes, mais qui n'ont été que validées par l'ARB (et éventuellement agrémentées de quelques fonctionnalités supplémentaires), tandis que d'autres sont des extensions toutes nouvelles. Dans le premier cas, si votre carte graphique les supportait auparavant, ces fonctionnalités le seront également avec OpenGL 3.x. Dans le deuxième cas, cela dépend des extensions. L'extension GL_ARB_uniform_buffer_object ou GL_ARB_vertex_array_object devraient, par exemple, être compatibles avec des cartes graphiques plus anciennes, tandis que des extensions comme GL_ARB_geometry_shader4 ne le seront qu'avec des cartes graphiques récentes. Il convient donc, avant d'utiliser certaines extensions, de vous assurer que votre matériel les supporte. Toutefois, à partir de la série 8 chez les GeForce et à partir de la série HD200 chez les Radeon, il ne devrait y avoir aucun problème à supporter toutes les extensions apportées par OpenGL 3.0 et 3.1.

IV - Conclusion

L'objectif de ce court article était d'offrir une brève introduction à certaines nouvelles fonctionnalités introduites par les versions 3.0 et 3.1 d'OpenGL. Comme je l'ai dit, ces deux versions ont apporté beaucoup plus (via d'autres extensions que je n'ai pas citées).

Pour plus d'informations, je vous suggère de lire les documentations officielles d'OpenGL 3.1 et de GLSL 1.40, très complètes, et qui vous permettent d'avoir une référence fiable (cela s'avère notamment très utile pour connaître les cas dans lesquels des erreurs sont générées). Les liens sont disponibles dans la section suivante.

V - Liens

Documentation OpenGL 3.1 : www.opengl.org/registry/doc/glspec31.20090324.pdf

Documentation GLSL 1.40 : www.opengl.org/registry/doc/GLSLangSpec.Full.1.40.05.pdf

VI - Remerciements

Merci à IrmatDen pour sa relecture.