OpenGL Moderne

Tutoriel 12 : extensions OpenGL

Opengl-tutorial.org

Traducteur

Alexandre Laurent

Avec chaque nouvelle génération, les performances des GPU augmentent, permettant ainsi d'afficher plus de triangles et plus de pixels. Néanmoins, la performance brute n'est pas le seul intérêt. NVIDIA, AMD et Intel améliorent aussi leurs cartes graphiques en y ajoutant des fonctionnalités.

Commentez

- Titre : OpenGL Moderne

- Auteur : Opengl-tutorial.org

- Traducteur : Alexandre Laurent

- Parution : 10 juin 2014

- Licence : 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 ® 2014 opengl-tutorial.org. Aucune reproduction, même partielle, ne peut être faite de ce site et 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.

Sommaire

- Navigation

- I. Extensions

- I-A. ARB_fragment_program

- I-B. ARB_debug_output

- I-C. Récupérer une extension - la méthode difficile

- I-D. Récupérer une extension - la méthode facile

- I-E. ARB vs EXT vs…

- II. Concevoir avec les extensions

- II-A. Le problème

- II-B. Choisir la limite

- III. Conclusion

- IV. Pour continuer

- V. Remerciements

- Navigation

Navigation

Tutoriel précédent : texte en 2D

Sommaire

Tutoriel suivant : application des normales

I - Extensions

Avec chaque nouvelle génération, les performances des GPU augmentent, permettant ainsi d'afficher plus de triangles et plus de pixels. Néanmoins, la performance brute n'est pas le seul intérêt. NVIDIA, AMD et Intel améliorent aussi leurs cartes graphiques en y ajoutant des fonctionnalités. En voici quelques exemples.

I-A - ARB_fragment_program

En 2002, les GPU n'avaient pas de vertex shader ni de fragment shader : tout était codé en dur dans la puce. C'était ce que l'on appelait le pipeline à fonctionnalités fixes (Fixed-Function Pipeline (FFP)). La plus récente version de la bibliothèque, qui était alors OpenGL 1.3, ne proposait aucun moyen de créer, manipuler et utiliser les « shaders », car ils n'existaient même pas. Mais NVIDIA a décidé que cela pourrait être pratique de décrire le processus de rendu avec du code, à la place de la centaine d'indicateurs et de variables d'états. C'est ainsi qu'a été créé ARB_fragment_program : il n'y avait pas de GLSL, mais à la place, vous pouviez écrire des trucs comme :

!!ARBfp1.0 MOV result.color, fragment.color; END

Évidemment, pour indiquer à OpenGL d'utiliser un tel code, vous aviez besoin de fonctions spéciales, qui n'étaient pas encore dans OpenGL. Avant de plonger dans les explications, un autre exemple.

I-B - ARB_debug_output

Ok, vous vous dites que ce ARB_fragment_program est trop vieux, et que vous n'avez certainement plus besoin de ce truc ? En fait, il y a de nouvelles extensions qui sont très pratiques. L'une d'entre elles est ARB_debug_output, qui expose une fonctionnalité qui n'existait pas dans OpenGL 3.3 mais que vous pouvez/devez tout de même utiliser. Elle définit des symboles comme GL_DEBUG_SYNCHRONOUS_ARB ou GL_DEBUG_SEVERITY_MEDIUM_ARB et des fonctions comme DebugMessageCallbackARB. Le bon point de cette extension est qu'à chaque fois que vous écrivez un code incorrect, comme :

glEnable(GL_TEXTURE); // Incorrect ! Vous voulez sûrement utiliser GL_TEXTURE_2D !

vous pouvez avoir une erreur et l'emplacement exact du problème.

Vous avez donc appris que :

- les extensions sont très utiles, même en OpenGL 3.3 moderne ;

- il faut utiliser ARB_debug_output ! Voir les liens ci-dessous.

I-C - Récupérer une extension - la méthode difficile

La méthode « manuelle » pour vérifier si une extension est disponible est d'utiliser ce morceau de code (provenant du wiki OpenGL.org) :

int NumberOfExtensions;
glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
for(i=0; i<NumberOfExtensions; i++) {
const GLubyte *ccc=glGetStringi(GL_EXTENSIONS, i);
if ( strcmp(ccc, (const GLubyte *)"GL_ARB_debug_output") == 0 ){
// L'extension est supporté par la machine et le pilote
// Essaie de récupérer la fonction "glDebugMessageCallbackARB" :
glDebugMessageCallbackARB  = (PFNGLDEBUGMESSAGECALLBACKARBPROC) wglGetProcAddress("glDebugMessageCallbackARB");
}
}

I-D - Récupérer une extension - la méthode facile

Somme toute, c'est très compliqué. Les bibliothèques comme GLEW, Glee, gl3w, etc. rendent cela plus facile. Par exemple, avec GLEW, vous n'avez qu'à appeler glewInit() après avoir créé la fenêtre et les variables pratiques comme :

if (GLEW_ARB_debug_output){ // Ta-Dah ! }

sont créées.

debug_output est spéciale, car vous devez l'activer à la création du contexte. Dans GLFW, cela est fait avec glfwOpenWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1);

I-E - ARB vs EXT vs…

Le nom de chaque extension contient des informations sur sa disponibilité :

GL_ : toutes les plates-formes ;

GLX_ : Linux et Mac seulement (X11) ;

WGL_ : Windows seulement ;

EXT : une extension générique ;

ARB : l'extension a été acceptée par tous les membres du OpenGL Architecture Review Board (les extensions EXT sont souvent promues ARB au bout d'un moment) ;

NV/AMD/INTEL : assez évident =).

II - Concevoir avec les extensions

II-A - Le problème

Disons que votre application OpenGL 3.3 nécessite d'afficher quelques lignes larges. Vous pouvez écrire un vertex shader compliqué pour ce faire, ou simplement vous reposer sur GL_NV_path_rendering, qui gère tous les problèmes pour vous.

Vous aurez donc un code qui ressemble à ceci :

if ( GLEW_NV_path_rendering ){
glPathStringNV( ... ); // Affiche la forme. Facile !
}else{
// Sinon quoi ? Vous avez toujours besoin d'afficher des lignes
// sur les machines NVIDIA plus vieilles, sur les machines AMD, sur les machines INTEL !
// Donc, vous devez tout de même l'implémenter vous-même !
}

II-B - Choisir la limite

Une possibilité est de choisir d'utiliser une extension lorsque le gain dans la qualité du rendu ou la performance dépasse les souffrances de la maintenance de deux codes.

Par exemple, Braid (le jeu 2D où vous voyagez dans le temps) possède plein d'effets de déformation d'images, lorsque vous jouez avec le temps, qui ne sont simplement pas affichés avec du matériel plus ancien.

Avec OpenGL 3.3 et supérieur, vous avez déjà 99 % des outils dont vous allez avoir besoin. Quelques extensions peuvent être utiles, comme GL_AMD_pinned_memory, mais c'est souvent différent d'il y a quelques années, lorsqu'avoir GL_ARB_framebuffer_object (utilisé pour le rendu sur texture), pouvait rendre le jeu dix fois plus beau.

Si vous devez gérer le plus vieux matériel, alors OpenGL 3.3 ne sera pas disponible et vous allez avoir à utiliser OpenGL 2+ à la place. Vous ne pourrez pas supposer que vous avez toutes ces extensions fantaisistes et vous allez devoir vous débrouiller sans.

Pour plus de détails, regardez par exemple la version OpenGL 2.1 du quatorzième tutoriel - rendu sur texture, ligne 152, où je dois vérifier la présence de GL_ARB_framebuffer_object à la main.

III - Conclusion

Les extensions OpenGL fournissent une méthode efficace pour étendre les capacités d'OpenGL, suivant le GPU de l'utilisateur.

Bien que les extensions soient principalement utilisées pour les usages avancés depuis que la plupart des fonctionnalités sont déjà présentes dans le cœur, il reste important de connaître comment elles fonctionnent et comment vous pouvez les utiliser pour améliorer votre logiciel - avec le coût d'une maintenance plus chère.

IV - Pour continuer

- tutoriel debug_output par Aks, vous pouvez passer la première étape grâce à GLFW ;

- le registre des extensions OpenGL, toutes les spécifications des extensions. La bible ;

- GLEW, le OpenGL Extension Wrangler Library ;

- gl3w, simple chargement de profil cœur OpenGL 3/4.

V - Remerciements

Cet article est une traduction autorisée dont le texte original peut être trouvé sur opengl-tutorial.org.

Navigation

Tutoriel précédent : texte en 2D

Sommaire

Tutoriel suivant : application des normales