|
Un simple Cube Mapping
Le Cube Mapping permet de simuler la réflexion d'un environnement sur un objet de manière plus efficace que le sphere mapping. Mais il est aussi utilisé pour d'autres applications comme le Bump Mapping.
Ici, nous allons voir concrètement le code minimum pour utiliser un simple Cube Mapping afin de simuler la réflexion d'un environnement dans une application OpenGL. A la fin de cette page, vous trouverez des liens vers des documents plus complets sur le principe du Cube Mapping ainsi que des codes sources.
|
|
Le Sphère Mapping consiste à projeter une texture en 2D sur des objets 3d d'une scène pour simuler la réflexion de l'environnement sur ces objets. Avec cette méthode, les différents objets ne peuvent pas se réfléchir les un sur les autres. De plus la qualité du rendu n'est pas parfaite, puisque l'image projetée ne représente pas exactement l'environnement 3d de la scène.
Le Cube Mapping améliore les choses car l'environnement projeté sur les objets n'est plus en 2D, donc plus proche de la réalité. La technique consiste à projeter les 6 textures d'un cube représentant l'environnement (à la manière d'un SkyBox) sur un objet (pour l'envelopper). Les 6 textures peuvent avoir été créés à l'avance, de la même manière que pour un SkyBox, ou de manière dynamique (en plaçant la caméra au centre de l'objet, et en faisant 6 photos de la scène dans 6 directions). L'avantage de la méthode dynamique est bien sûr que la réflexion devient dynamique (les objets de la scène font alors partie de l'environnement).
Passons maintenant au code.
|
|
Nous avons besoin de vérifier la compatibilité du matériel avec le Cube Mapping lors de l'initialisation.
|
|
// glExt_CheckGLExtension vérifie le support d'une extension par le système
bool glExt_CheckGLExtension( char* extensionName )
{
// On récupère la liste des extensions supportées
char* extensionList = (char*) glGetString(GL_EXTENSIONS);
if(strstr(extensionList, extensionName) == NULL) // Notre extension en fait-elle partie ?
return false;
return true;
} |
|
Si tout s'est bien passé, la fonction ci-dessus a retrouvé la chaine "GL_ARB_texture_cube_map" passée en argument dans la liste des extensions disponibles sur la machine.
Nous n'avons pas besoin de nouvelles fonctions, mais de nouveaux identifiants:
|
|
// A ajouter quelque part dans un header
# define GL_NORMAL_MAP_ARB 0x8511
# define GL_REFLECTION_MAP_ARB 0x8512
# define GL_TEXTURE_CUBE_MAP_ARB 0x8513
# define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
# define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
# define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
# define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
# define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
# define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
# define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
# define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
# define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
|
|
Nous n'allons pas utiliser tous ces identifiants dans notre exemple.
|
|
Lors de l'initialisation du programme, on commence par charger les 6 textures du CubeMap en utilisant le target correspondant à leur orientation dans l'espace. Ces textures peuvent être les textures d'un SkyBox.
|
|
GLenum CubeMapTarget[6] = { // Liste des targets pour la création des textures de CubeMap
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
};
char CubeMapFileName[6][20]={ // Liste des noms de fichiers des textures
"Data/right.jpg",
"Data/left.jpg",
"Data/bottom.jpg",
"Data/top.jpg",
"Data/front.jpg",
"Data/back.jpg"
};
void LoadCubeMapTexture(void) // Fonction de chargement des textures en mémoires
{
int i=0;
// On génère un ID de texture unique pour les 6 textures du CubeMap
glGenTextures(1, &CubMapTextureID);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, CubMapTextureID);
for (i = 0; i < 6; i++)
{
// La fonction ci-dessous est utilisée pour charger les 6 textures du CubeMap
// Elle utilise glTexImage2D avec le contenu de CubeMapTarget[i] comme target et le nom du fichier.
CreateGLTexture(CubeMapTarget[i],CubeMapFileName[i]);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
}
|
|
Pour afficher un objet en lui appliquant le CubeMap, il suffit de sélectionner l'ID du CubeMap et d'autoriser la génération des coordonnées de texture avec GL_REFLECTION_MAP_ARB. On n'oublie pas d'activer l'utilisation du Cube Mapping avec glEnable.
|
|
void DrawGLScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(...); // On positionne la caméra.
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB,CubMapTextureID);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glEnable(GL_NORMALIZE);
// Affichage de l'objet...
}
|
|
On désactive tout ce dont on a plus besoin ensuite et c'est finit!
|
|
Les textures du CubeMap seront inversées. Il faut donc les retourner avant (dans les .bmp,.jpg,...) ou pendant avec la matrice de texture:
|
|
Exemple simple:
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glRotatef(180, 0.0f, 0.0f, 1.0f);
|
|
La génération automatique de texture ne prendra pas en compte les transformations de l'espace. Si vous tournez autour de l'objet, vous verrez tout le temps la même réflexion sur celui-ci. Il faut encore manipuler les matrices.
|
|
Nvidia,"OpenGL Cube Map Texturing" (Document HTML,www.nvidia.com)
Chris Wynn & Sim Dietrich,"Cube Maps" (PDF,www.nvidia.com)
http://www.ultimategameprogramming.com (code source)
|
|
Version originale: Mai 2006
|
Dernière mise à jour: Mai 2006
|
Par Grégory Smialek
|
Site hébergé par free
|
|