Utilisation des extensions OpenGL sur une NVidia GeForce (256,2 ou 3)
Rappels sur l'OpenGL
NB: je consid�re que vous connaissez bien OpenGL
1.1. Pour r�viser, ce site permet de se rafraichir la
m�moire.
Le pipeline OpenGL se divise en deux moteurs
principaux:
- Le geometric engine, qui va effectuer tous les calculs 3D comme les transformations g�ometriques, le clipping, et le calcul de la couleur d'�clairage en chaque sommets, et qui finalement � partir de donn�es 3D (des coordonn�es de polygones dans l'espace), produit des polygones dans l'espace ecran pr�ts a �tre remplis par le raster engine
- le raster engine, qui va effectuer toutes les op�rations 2D de remplissage des polygones � l'aide de la texture courante, les informations de couleurs...
- le fait de ne pas pouvoir utiliser simult�nement plus d'une texture par polygone
- le fait de ne pas pouvoir effectuer soi-meme le calcul de la couleur du pixel � partir des donn�es du raster engine
- les calculs d'éclairage sont effectués uniquement aux sommets, alors que l'on souhaiterait le faire par point
Utilisations des extensions
Sous linux (c�st le seul unix sous lequel la GeForce tourne), pour utiliser une extension (i.e soit une fonction, soit un flag), il suffit que cette fonction soit d�finie dans le gl.h et que ca compile. Sous Windows, l'acc�s est un peu different. Soit vous trouvez un fichier glext.h qui vous permet d'avoir toutes les definitions, sinon il vous faut chercher le profil de la fonction et creer votre glext.h a la main. La d�marche consiste � r�cup�rer l' adresse de chaque fonction que l' on veut utiliser. Ceci permet de savoir si la carte dispose de cette extension lors du lancement du programme. Pour ceci, il s'agit de d�clarer un pointeur sur ce type de fonction. Pour initialiser votre programme, vous devez avant d'entrer dans votre boucle d'evenements r�cuperer l'adresse dans le driver de cette fonction par l'appel a la fonction windows wglGetProcAdress("TokenDeLaFonction"). Si le pointeur renvoye n'est pas nul, alors la fonction est utilisable.
Utilisation du multitexture
Puisqu'OpenGL est une
machine d'�tats finis, il faut toujours sp�cifier � OpenGL quelle
est la texture sur laquelle les op�rations vont s'appliquer. Pour le
multitexture, le principe consiste � sp�cifier l'unit� de texture
sur laquelle les op�rations de texture s'appliquent. On utilise pour
cel� la fonction glActiveTextureARB. Avant toute operation
li�e � la texture, on appelle un glActiveTextureARB(GL_TEXTURE0_ARB) ou
GL_TEXTURE1_ARB ou GL_TEXTUREk_ARB (0<k<n) où n est le nombre d'unites de
textures disponibles simultanement pour le hard. Dans le cas des
GeForce 256 et GeForce 2, ce nombre est 2. Dans le cas de la GeForce
3, ce nombre est 4. (Attention cependant l'utilisation des 4 textures
divise le frame rate par 2) Ensuite, pour utiliser plusieurs
textures simultanement, il faut pour chaque unit� de texture
activer l'utilisation de la texture a l'aide de
glEnable(GL_TEXTURE_2D) ou glEnable(GL_TEXTURE_CUBE_MAP_EXT) ou glEnable(GL_TEXTURE_1D).
Dans
le cas de 2 textures simultanees:
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(montexid[0]);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(montexid[1]);
Ensuite
pour definir les coordonnees de textures pour un sommet, (par
exemple pour des textures 2D)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.,1.);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.5,1.);
glVertex3fv(MonVertex.pos);
Remarque: on n'est pas oblig� d'utiliser des
textures 2D pour chaque unit� de texture. On peut tr�s bien
utiliser une cube map et une texture 1D, ou n'importe quelle autre
configuration de textures.
Utilisation des cube maps
Un cube map peut se voir comme une table d'indirection permettant d'associer � une direction donn�e une valeur RGB(A). Comment les utiliser? En fait, les texture target sont d�j� allou�s:
- GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT
Pour le mode reflection (Env Map), il faut dire:
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_EXT);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_EXT);
glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_EXT);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
Il faudra ensuite penser que le cube est situe autour de l'objet et que les faces du cube correspondent � l'image de l'environement ext�rieur vu du centre de l'objet.
Pour le mode Normales (renormalisation), il faut taper:
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_NORMAL_MAP_EXT);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_NORMAL_MAP_EXT);
glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_NORMAL_MAP_EXT);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
Ce mode est appel� renormalisation car le but principal de son impl�mentation est de pouvoir renormaliser n'importe quel vecteur. Comme coordonn�es de texture, il suffit de donner les coordonn�es du vecteur. La couleur renvoy�e est la couleur situ�e dans le cube map � l'intersection du vecteur et du cube. Il suffit que les textures soient construites de facon � ce que chaque vecteur issu de l'origine et touchant le cube ait comme couleur lui-meme renorme en RGB. Attention tout de meme, il ne faut pas oublier le glEnable(GL_TEXTURE_CUBE_MAP_EXT) pour que la cube map soit utilisee par gl.
Utilisation des registers combiners
Le m�canisme des registers combiners intervient dans le raster engine. En OpenGL standard, la fonction de m�lange des attributs divers (couleur du materiau, couleur de la lumi�re, couleur de la texture) pour le pixel courant n'est pas reprogrammable (juste une poign�e de m�thodes entre lesquelles choisir). Le calcul de m�lange des attributs est fixe. L'id�e de ce genre de "Pixel Shaders" est de permettre au programmeur de red�finir la fonction de m�lange des attributs. Lorsque le raster engine a fini de calculer les donn�es associ�es au fragment, il execute le pixel shader. Ce pixel shader est en fait un micro-programme execut� par le hardware pour chaque pixel a tracer � l'�cran, qui prend en entr�e toutes les donn�es calcul�es par le raster pour le pixel. Ce pixel shader est implement� sur NVidia GeForce par les Register combiners. Dans ces Register combiners, on peut effectuer:
- comme operations vectorielles:
- Produit scalaire
- Somme de vecteurs
- comme operations de couleurs:
- multiplication composante a composante
- somme de couleurs
Pour de plus amples informations: le document de MJKilgard: A practical and robust approach for bump-mapping with Today'hardware
En fait, les register combiners se pr�sentent comme un micro-programme d�coup� en plusieurs �tages. Ceux-ci sont soit des �tages generaux, soit l'�tage final. Au sein de chaque �tage g�n�ral, on dispose pour le pixel des valeurs:
NOM DE REGISTRE | Valeur initiale | Droits d'acces | Description |
GL_ZERO | 0 | Lecture seule | Une constante |
GL_CONSTANT_COLOR0_NV | definie par l'application | Lecture seule | Une valeur constante pour un meme shader |
GL_CONSTANT_COLOR1_NV | definie par l'application | Lecture seule | id |
GL_FOG | selon les parametres de glFogi et du fragment | Lecture seule | En RGB la couleur du fog, et en alpha son opacite |
GL_PRIMARY_COLOR_NV | couleur interpolee | Lecture/ecriture | La couleur du fragment definie par glColor ou glColorMaterial |
GL_SECONDARY_COLOR_NV | couleur interpolee | Lecture/ecriture | Une extension OpenGL permet de definir une seconde couleur de materiau |
GL_SPARE0_NV | indefinie | Lecture ecriture | Un registre de travail |
GL_SPARE1_NV | indefinie | Lecture ecriture | Un registre de travail |
GL_TEXTURE0_ARB | couleur filtree de l'unite de texture 0 pour le fragment courant | Lecture ecriture (attention, on ne modifie pas la valeur de la texture) | Une information de texture |
GL_TEXTURE1_ARB | couleur filtree de l'unite de texture 1 pour le fragment courant | Lecture ecriture | Une information de texture |
GL_TEXTUREi_ARB | couleur filtree de l'unite de texture i pour le fragment courant, dans le cas de la GeForce 3, i vaut (0,1,2,3) | Lecture ecriture | Une information de texture |
Ensuite on dispose de 8 registres, 4 en RGB, 4 en alpha qui vont permettre de d�composer les op�rations. L'id�e est de dire que les op�rations en RGB vont �tre ind�pendantes de celles en alpha. On nomme alors ces registres A,B,C,D. On peut donner � chaque registre une des valeurs des registres pr�c�demment d�crits auxquels on a �ventuellement appliqu� une fonction de conversion. La diff�rence entre les GeForce 256 et 2 par rapport � la GeForce 3 est qu'elles disposent de moins de textures en m�me temps (2 au lieu de 4). Ces fonctions de conversions sont:
Mapping d'entr�e | Fonction appliqu�e | Intervalles | Explications |
GL_UNSIGNED_IDENTITY_NV | max(0,x) | [0..1]=>[0..1] | Presque l'identit� (ne pas oublier que les valeurs negatives sont clamp�es avec ce mecanisme) |
GL_SIGNED_INVERT_IDENTITY_NV | 1.-min(max(0,x),1) | [0..1]=>[1..0] | Presque l'inversion sauf qu'on clampe ce qui depasse 1 |
GL_EXPAND_NORMAL_NV | 2*max(0,x)-1 | [0..1]=>[-1..1] | La fonction de conversion d'une couleur en un vecteur (attention le vecteur 0,0,0 est repr�sent� par 0.5,0.5,0.5) |
GL_EXPAND_NEGATE_NV | -2*max(0,x)+1 | [0..1]=>[1..-1] | La conversion d'une couleur en le vecteur oppos� |
GL_HALF_BIAS_NORMAL_NV | max(0,x)-0.5 | [0..1]=>[-0.5..0.5] | sans commentaire |
GL_HALF_BIAS_NEGATE_NV | -max(0,x)+0.5 | [0..1]=>[0.5..-0.5] | sans commentaire |
GL_SIGNED_IDENTITY_NV | x | [-1..1]=>[-1..1] | l'identite signee |
GL_SIGNED_NEGATE_NV | -x | [-1..1]=>[1..-1] | L'inverse signee |
Cette figure montre un exemple d'utilisation d'un �tage. Pour se
repr�senter le m�canisme des register combiners, il faut imaginer un
processeur. Une partie des registres sont accessibles par le
programmeur (voir tableau precedent), une partie des registres sont
r�serv�s par le processeur pour r�aliser les op�rations de calculs
interm�diaires (registres A B C D). Pour executer une partie de
micro-programme de pixel shader, il faut imaginer l'execution d'une
operation dans un processeur. Le processeur va charger dans ses
registres de travail les valeurs contenus dans ceux du programmeur, en
utilisant un mode d'interpr�tation particulier de chaque valeur dans
le registre de travail. Ensuite, il ex�cute forc�ment une op�ration de
multiplication (produit scalaire ou composante a composante) entre A
et B, et entre C et D, en parall�le. Ensuite, le programmeur choisit la destination
de chaque produit (ou il peut choisir de ne pas les stocker). De plus,
une op�ration d'addition ou de s�lection peut s'effectuer sur le
r�sultat des deux produits pr�c�dents. La s�lection correspond � : si
SPARE0.alpha>0.5 alors CD sinon AB. Ensuite on peut stocker le
resultat ou ne pas en tenir compte. L'op�ration finale de scale et bias
s'applique � tous les resultats (produits + addition). Tous les
r�sultats ne peuvent stocker que dans les resultats accessibles au
programmeur.
G�n�rateurs de code
Le g�n�rateur de code d'un �tage normalLe g�n�rateur de code de l'�tage final
NB:Pour utiliser ces morceaux de code, il ne faut pas oublier de dire a la carte:
- la taille du shader, en appelant glCombinerParameteriNV(GL_NUM_COMBINERS_NV,3) dans le cas ou on veut utiliser 3 etages normaux + le final
- definir les couleurs constantes (1 et 2) en appelant glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV,couleur)
- d'activer les register combiners par glEnable(GL_REGISTER_COMBINERS_NV)
Utilisation des registers combiners
Un exemple d'application des combinersINFORMATIONS
Auteur:Franck SenegasDerni�re Mise A Jour:22-8-2001