Équipe Analyse/Synthèse |
GLX est une bibliotheque permettant l'utilisation de openGL a travers un serveur X. Cette bibliotheque permet d'effectuer l'affichage a l'interieur de drawables X comme les pixmaps, mais elle offre egalement un mode de connexion direct, qui n'utilise pas le serveur X, dans le but d'accelerer l'affichage.
Enfin, GLU (GL Utilities) est une bibliotheque de haut niveau, reposant sur GL, qui permet par exemple le trace de NURBS et de tous types d'objet complexes, la gestion de la perspective de facon simplifiee.
Dans le Makefile, les directives -lGL et -lGLU doivent etre ajoutees a la ligne de compilation. Les lignes ajoutees pour permettre l'utilisation de GLX, openGL et GLU sont:
#ifdef openGL #include <GL/glx.h> #include <GL/gl.h> #include <GL/glu.h> #endif
glXChooseVisual(Display* display, int screen, int* attributeList)renvoie le visual qui correpond le mieux aux specifications de la liste d'attributs attributeList. Cette fonction est le pendant GLX a la fonction X XMatchVisualInfo.
glXCreateContext(Display* display,XVisualInfo *vis,GLXContext shareList,Bool direct);
glXCreateGLXPixmap(Display* display,XVisualInfo *vis,Pixmap pixmap)pixmap est le pixmap X qui existe deja dans les structures de View et de Frame
glXMakeCurrent(Display* display, GLXDrawable draw, GLXContext ctx)
glBegin(GL_TRIANGLE); glVertex3f(0.0,0.0,0.0); /* 3 signifie 3 dimensions, f pour float */ glVertex3f(1.0,0.0,0.0); glVertex3f(0.0,1.0,1.0); glEnd(); glBegin(GL_LINES); glVertex2i(1,1); /* 2 signifie 2 dimensions, i pour int */ glVertex2i(0,0); glEnd(); glFlush(); /* affiche le resultat */
Une liste possede un nom (sous forme d'entier), afin de pouvoir etre reutilisee. OpenGl propose un jeu complet de primitives de reservation/creation/affichage/destruction de Display List. Celles ci sont la pour en faciliter la gestion, mais leur utilisation n'est pas obligatoire. L'exemple suivant illustre l'utilisation de telles listes.
GLUint nomListe1; nomListe = glGenList(2); /* reservation de 2 listes */ glNewList(nomListe,GL_COMPILE) /* debut de definition de la premiere liste*/ glBegin(GL_TRIANGLE); ... glEnd(); glBegin(GL_LINES); ... glEnd(); glFlush(); glEndList(); glNewList(nomListe+1,GL_COMPILE_AND_EXECUTE) /* la liste est executee directement */ glDoAnUnknownOperationOnTheGLContext(); ... glDoAnotherOperation(); glEndList(); glCallList(nomListe); /* execution des listes */ glCallList(nomListe+1);
Nous avons vu plus haut que les zones d'affichage ne peuvent pas etre directement les drawables X, mais des GLXPixmaps. Chaque View est suceptible de recevoir un affichage en openGL. C'est pourquoi nous avons ajoute a cette strucure un pixmap GLX. De meme, pour des raisons de rapidite et d'homogeneite avec les traces en X (il est plus commode de stocker le contexte GLX dans cette meme structure et de l'appeler lorsque l'on en a besoin que de le changer les attributs du contexte courant avant chaque affichage). La strucure view devient donc:
typedef struct _View { ... Pixmap pixmap; /* Xwindow pixmap */ GC gc; /* Xwindow Graphic Context to copy view in frame */ Pixmap clipMask; /* Xwindow clipMask, added to gc */ #ifdef openGL GLXPixmap glxPixmap; /* (modif 03/08/98) pixmap used by openGL */ GLXContext glxContext; /* (modif 14/08/98) glx context used by openGL */ #endif ... }Meme si, en pratique, l'affichage doit se faire, dans XSpect, dans les pixmaps des View, X ou GLX, et etre copies par la suite dans les pixmaps des Frames avant d'etre affiches, en prevision d'une extension de l'utilisation de openGL a tous les traces, il a ete bon de creer l'equivalent GLX du pixmap X des frames. On obtient donc la strucure suivante.
typedef struct _Frame { ... Pixmap pixmap; /* global Xwindow pixmap */ #ifdef openGL GLXPixmap glxPixmap; /* pixmap for openGL (modif 03/08/98) */ GLXContext glxContext; /* (modif 14/08/98) glx context used by openGL */ #endif ... }Enfin, l'utilisation des display Lists dans une optique de rapidite a impose l'ajout de la reference de la display List dans la structure View.
typedef struct _View { ... #ifdef openGL GLuint glListName; /* name of the view's openGl display list */ #endif ... }
Ceci est visible sur les fonctions de choix de la couleur appliquee au contexte courant, qui sont, pour le mode RGB et le mode indexe respectivement
glColor4x(red,green,blue,alpha) et glIndex(index)
Pour obtenir la couleur finale dans le cas d'une specification RGBA dans un pixmap en mode indexe, openGL calcule les composantes RGB de chaque pixel, puis recherche dans la Colormap (palette de couleur associee a l'application ou a l'ecran) la couleur ayant les composantes RGB les plus proches. Le resultat est donc assez aleatoire, et dans les cas ou peu de couleurs sont alouees, ce qui est le cas de Xspect, franchement mauvais.
De plus, ce choix ne permet pas d'utiliser l'overlay (technique de bas niveau, qui consite a ne modifier qu'un plan de couleur de l'ecran) utilisee dans XSpect pour les surlignements dans les selections.
On est donc contraint, si l'on ne veut pas remettre en cause la globalite de la partie graphique d'XSpect, de choisir le mode de couleur indexe, ce qui empeche l'utilisation de la transparence (les resultats etant trop mauvais), er une utilisation intuitive des couleurs.
glNewList(nomListe,GL_COMPILE); Pour tous les points du fichier obtenir son amplitude(z) fixer la couleur obtenir le temps(x) et la frequence(y) correspondants tracer un polygone avec les points environnants Fin pour glEndList();
En effet, le nombre de points contenus dans un fichier, meme s'il est tres variable, atteint courament plusieurs centaines de milliers de donnees. L'examen attentif de l'execution a revele que dans l'algorithme, le temps d'execution de toutes les commandes non openGL reunnies etait negligeable devant celui des primitives openGL utilisees a savoir
Entrer dans openGL toutes les donnees etant impossible, il est donc logique de chercher a ne rentrer que les donnees indispensables pour reduire le temps de calcul, c'est a dire les donnees qui vont etre affichees.
A partir de la, il devient inutile de rentrer les coordonnees en 3 dimensions, puisque l'on ne sait pas a l'avance quelles donnees sont necessaires ou non en fonction de l'affichage desire (puisque c'est justement le role meme de openGL). La seule part de openGL se reduit donc a l'affichage de points de couleur dans un pixmap. Cette couche supplementaire est donc inutile.
L'utilisation de openGL s'est donc progressivement restreinte au trace de points ou de rectangles dans un pixmap GL en utilisant une palette de couleurs par indices, pour des raisons de rapidite et de qualite de rendu, openGL/X n'apportant aucune garantie quand a l'utilisation des couleurs en mode RGBA pour une application utilisant le mode indexe.
Meme avec ces restrictions, l'affichage est reste tres lent: l'utilisation faite d'openGL n'a manifestement pas ete la bonne. La solution openGL ne presentait donc plus aucun avantage, c'est pourquoi le sonagramme a finalement ete realise en X pur.