TP2-OpenGl 2.1 Elimination d`effet d`alias par mip-map

Transcription

TP2-OpenGl 2.1 Elimination d`effet d`alias par mip-map
ENSICAEN
2007
TP2-OpenGl
2.1
Elimination d’effet d’alias par mip-map
Avec cette technique, on prépare, à partir d’une texture T0 , une suite T1 , · · · Tn
de textures de tailles décroissantes. Ainsi, si la texture initiale T0 est de taille
256 × 64, les suivantes seront de tailles respectives 128 × 32, 64 × 16, 32 × 8,
16 × 4, 8 × 2, 4 × 1, 2 × 1 et 1 × 1. En général, un texel t de Ti+1 correspond à 4
texels adjacents de Ti , la couleur de t étant la moyenne des couleurs des texels
correspondants dans Ti+1 .
L’algorithme employé tente de garder constant le nombre de texels intervenant
dans la couleur d’un pixel. Nous appelons ce nombre le ratio de texels/pixel.
Cette opération améliore grandement l’effet de compression de texture (“texture
minification”). Pour cela, OpenGl trouve pour un pixel donné p, les deux plans
de texture T et T ′ qui donnent les meilleurs ratios de texels/pixel par défaut et
par excès. Suivant la méthode spécifiée, la texture finale sera soit celle provenant
du plan de ratio le plus proche, soit une interpolation linéaire entre deux texels,
l’un provenant de T et l’autre de T ′ .
2.1.1
Préparation des textures intermédiaires
Si on a réussi à construire la texture du niveau 0, la fonction glu ci-dessous
permet d’obtenir les autres niveaux de texture.
gluBuild2DMipmaps(GLenum target, GLint components, GLint width,
GLint height, GLenum format, GLenum type,
void *texels)
Exemple :
texdata = loadppm("tuile.ppm", -1, texWidth, texHight, texMaxval);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texWidth, texHight, GL_RGB,
GL_UNSIGNED_BYTE, texdata)
La première ligne charge dans texdata une texture en récupérant ses dimensions
et la seconde construit les textures de niveaux inférieurs. Les paramètres de
gluBuild2DMipmaps ont la même signification que ceux de glTexImage2D. Le
paramètre components indique le nombre de composantes d’un texel (4 pour le
format RGBA, 3 pour RGB etc.).
1
2.1.2
Traitement de compression de texture
Lorsqu’on a chargé une texture mipmap, on a plusieurs possibilités pour traiter
le problème de compression de texels. Rappelons que pour les textures ordinaires, nous pouvons spécifier deux méthodes GL_LINEAR et GL_NEAREST par :
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
et
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
Avec le mipmaping, on peut indiquer quatre autres méthodes :
GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR,
GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR
La qualité de texturage s’améliore dans l’ordre, la meilleure qualité étant produite par GL_LINEAR_MIPMAP_LINEAR.
Exercie 1. Complétez le code du fichier exo1.cpp de la manière suivante :
placez 400 = 20 × 20 carrés de dimension 1 × 1 sur [−10, +10] × [−10, +10] du
plan z = −5 (la caméra se trouvant à l’origine). Texturez chaque carré par la
méthode de mipmap, avec le fichier d’image tuile.ppm. Complétez le code de
la fonction keyboard pour qu’on puisse modifier par les touches du clavier, le
traitement de la compression des textures. Faites subir aux carrés des rotations
et des translations et examiner le résultat.
————————————————————————————————
Après avoir lancé gluBuild2DMipmaps, il est possible de modifier l’image du
niveau i, en exécutant glTexImage2D. Par exemple, pour le niveau 2 :
texdata2 = loadppm("texture2.ppm", -1, width2, hight2, maxval2);
glTexImage2D(GL_TEXTURE_2D, 2, 3, width2, height2, 0,
GL_RGB, GL_UNSIGNED_BYTE, texdata2);
Avec ces deux instructions, nous avons modifié l’image mipmap du niveau 2. Il
faut bien entendu s’assurer que cet image a les bonnes dimensions.
Exercice 2. Reprenez l’exercice précédent. Chargez en mode mipmap le fichier texbase.ppm et remplacez les différents niveaux de texture (de 0 à 5) par
les images se trouvant dans les fichiers tex256.ppm, . . ., tex8.ppm. Ces fichiers
2
contiennent des images monochromes.
Faites mouvoir l’objet et observez (et expliquez) la composition des couleurs
observées en différents modes de texture.
2.2
Texturage multiple
Le but du texturage multiple est d’appliquer plusieurs textures distinctes sur un
même objet. En principe, tout se passe comme pour l’application d’une texture
simple, sauf qu’il faut charger n fichiers textures et définir pour chaque sommets
n coordonnés de textures. Les coordonnées de texture ne sont pas nécessairement identiques.
Pour y parvenir, procédez de la manière suivante (pour deux textures) :
1. Inclure (par #include) le fichier glext.h, en vérifiant que ce fichier figure bien dans un répertoire accessible au compilateur.
2. Déclarer deux nouvelles fonctions, initialisées à NULL, de la manière suivante :
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
3. Déclarez un tableau de noms de texture, contenant autant de cases que
nécessaires. Pour deux textures, on déclarera par exemple :
GLuint
texName[2];
4. Il faut aller chercher l’adresse exacte des deux fonctions déclarées précédemment. Cela se fait par :
glActiveTextureARB =
(PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB =
(PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
5. Réservez de la place mémoire pour les deux structures de données qui
vont recevoir les textures.
glGenTextures(2, texName);
6. Chargez les deux images servant de texture. Avec la fonction loadppm
cela donne :
3
texdata1=loadppm("mur.ppm", -1, texWidth1, texHeight1, texMaxval1);
texdata2=loadppm("light.ppm", 127, texWidth2, texHeight2, texMaxval2);
Dans cet exemple, on remarquera que la première image chargée (mur.ppm)
est une image en RGB alors que le second (light.ppm) est traduit en
RGBA, avec un alpha égal à 127.
7. Il faut maintenant activer chaque texture et définir les modalités de son
application. Avec notre exemple, les instructions relatives à la première
texture sont :
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth1, texHeight1, 0,
GL_RGB, GL_UNSIGNED_BYTE, texdata1);
errCode = glGetError();
if (errCode != GL_NO_ERROR){
errString= gluErrorString(errCode);
cout <<" Texture1: "<<errString<<endl;
exit(1);
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
On examinera soigneusement l’ensemble de ces instructions. La première
ligne est spécifique au multi-texturage. Il est prudent de vérifier que les
instructions ont été correctement exécutées (d’où le message d’erreur). La
dernière ligne n’est nécessaire que si l’objet a déjà reçu une couleur.
8. On exécute les mêmes opérations pour la seconde texture :
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texName[1]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth2, texHeight2, 0,
GL_RGBA, GL_UNSIGNED_BYTE, texdata2);
errCode = glGetError();
4
if (errCode != GL_NO_ERROR){
errString= gluErrorString(errCode);
cout <<" Texture2: "<<errString<<endl;
exit(1);
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
La présence de l’instruction glTexEnvf est nécessaire, car il s’agit d’afficher
la seconde texture pardessus la première.
9. Il faut enfin définir les coordonnées de texture. Cette opération se fait
à l’occasion de chaque déclaration de sommet. Par exemple (les nombres
sont donnés à titre d’exemple) :
glMultiTexCoord2fARB(GL_TEXTURE0,0.5,0.5);
glMultiTexCoord2fARB(GL_TEXTURE1,0.3,0.2);
glVertex3f(0.1,0.2,0.3);
Exercice 3.
Réalisez le multitexturing sur un tore à l’aide des fichiers mur.ppm et light.ppm.
Exercice 4. Réalisez une scène comprenant une tour en brique, illuminée par
la lumière de jour.
Indications : Inspirez vous de l’image de la tour fournie. Trouvez une image
de mur en brique sur le web. Eclaircissez l’image sous gimp comme s’il était
surexposé. Fabriquez une texture (toujours sous gimp) comprenant une partie
blanche et partie plus sombre. Appliquez les deux images en multi-texture sur
une scène de tour simple (cube allongé).
5

Documents pareils