Texel
Liens | OpenGL | Index | Contact





















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 principe:
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.

  Les extensions:
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.

  Chargement des textures:

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);
}


  Affichage:
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!

  Rappel:
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.

  Références et liens:
  • 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




















    www.texel.fr.fm