OpenGL et SDL : Application de textures
Un article de Games Creators Network.
Attention
Cet article est en attente du choix d'une licence par son auteur. Elle n'est pas soumise à la licence par défaut du GCN.
Cela signifie entre autre chose que si vous n'êtes pas l'auteur de cet article, vous n'avez probablement pas le droit de le modifier.
Sommaire |
[modifier] Présentation
La librairie OpenGL est complètement indépendante du matériel, aussi on l'utilise souvent avec une autre librairie pour gérer les aspects fenêtrage, clavier, souris, etc.
Le plus souvent, on utilise glut (pour GL Utility Toolkit) mais ce n'est pas la seule méthode. Il est possible d'utiliser Gtk mais également la librairieSDL.
Personnellement, j'utilise de plus en plus la librairie SDL en conjonction avecOpenGL, ceci par goût personnel. Aussi, j'ai voulu écrire ce court tutoriel afin de montrer comment on peut appliquer une texture à un objet en gérant le ou les fichiers de texture via l'utilisation de SDL.
[modifier] Utilisation de la SDL
[modifier] Rappel sur SDL_Surface
La structure SDL_Surface est le principal objet manipulé par les fonctions de la librairie SDL. Cette structure permet de décrire une image en deux dimensions et contient toutes les informations nécessaires pour la manipuler.
[modifier] La librairie SDL_Image
La librairie SDL comporte en natif une fonction SDL_LoadBMP qui ne sait manipuler que des fichiers au format BMP. On pourrait utiliser cette fonction mais il faudrait auparavant convertir toutes les textures dans ce format qui, je rappelle, ne permet aucune compression.Il existe cependant une librairie, libSDL_image.so, disponible sur le site officiel de la librairie SDL et qui apporte des fonctions permettant d'ouvrir des fichiers graphiques sans se préoccuper des formats. La fonction générique à utiliser est IMG_Load et prend en paramètre le nom du fichier (éventuellement avec le chemin complet). Cette fonction renvoit un pointeur sur une SDL_Surface.
Les formats reconnus sont les suivants: BMP, PNM, XPM, XCF, PCX, GIF, JPG, TIFF, PNG, LBM.
Quel que soit le mode de compression de l'image dans le fichier, une fois chargée en mémoire, l'image est sous forme brute, pixel par pixel, sans compression. Elle est de ce fait plus facilement exploitable.
[modifier] Chargement d'un fichier
Charger un fichier de type quelconque peut se faire de la manière suivante :
SDL_Surface * texture;
// ...
texture = IMG_Load (" texture_brique.png" );
// ...
Remarquez que dans cet exemple, le fichier contenant la texture est au format PNG. La fonction IMG_Load se débrouille très bien avec les différents formats, donc laissez-la faire.
[modifier] Utilisation avec OpenGL
[modifier] Rappels sur le format RGBA
Ce paragraphe constitue un court rappel sur le format RGBA qui peut être utilisé avec OpenGL
Tout d'abord, RGBA signifie Red Green Blue Alpha. Chaque pixel est codé avec 4 valeurs, chacune d'elle pouvant être codées sur un mot de 8 bits, 5 bits, ou toute autre combinaison possible. Le codage est effectué de la manière suivante :
Pixel 0Pixel 1...rougevertbleualpharougevertbleualpha...Le champ alpha contient l'information de transparence du pixel. Si la valeur est proche de 0, le pixel sera transparent, c'est-à-dire qu'il sera possible de voir à travers lui. A l'inverse, si la valeur est proche du maximal, il sera opaque.
Il est évident que si vous voulez bénéficier de cette information, le fichier doit lui aussi la contenir. C'est le cas des fichiers PNG ou GIF. En revanche, les fichiers JPEG ne contiennent pas d'information de transparence.
Par exemple, si votre texture est contenue dans un fichier JPEG, le pointeur texture->pixels pointera sur les pixels organisés de la manière suivante :
Pixel 0Pixel 1...rougevertbleurougevertbleu...Il n'y aura pas d'information de transparence. Attention cependant à ne pas confondre. Certains formats comme le JPEG n'enregistrent aucune information de transparence alors que d'autres comme le PNG ou le GIF peuvent éventuellement comporter une valeur de transparence pour chaque pixel, mais ça n'est pas une obligation. Vous pouvez très bien trouver des fichiers PNG sans information de transparence.
Petite astuce: si vous souhaitez ajouter une information de transparence à un fichier PNG (par exemple) qui en est dépourvu, ouvrez le fichier avec un logiciel comme Gimp et ajoutez un canal de transparence.
Donc, pour en revenir à ce qui nous intéresse, en fonction du format du fichier et de ce qu'il contient, vous allez dire à OpenGL comment manipuler les pixels de la texture.
[modifier] Jonction OpenGL et SDL
Le pointeur texture contient 3 champs qui vont être utiles pour OpenGL :
texture->w (largeur de la texture)
texture->h (hauteur de la texture)
texture->pixels (pointeur sur les pixels de l'image)
Le morceau de code suivant montre comment lier le pointeur texture à du code OpenGL :
GLuint texture_name; GLuint objet; SDL_Surface * texture; // ---- Création d'un objet de texture. ------------------------------------------------ glGenTextures (1, & texture_name); glBindTexture (GL_TEXTURE_2D, texture_name); // Paramétrage de la texture. 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_MIN_FILTER, GL_LINEAR); // Chargement du fichier. texture = IMG_Load (" texture_brique.png" ); // Jonction entre OpenGL et SDL. glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture-> pixels); // ---- Fin de création de l'objet de texture. ----------------------------------------- // ... // Création d'un objet par l'utilisation d'une liste d'affichage. objet = glGenLists (1); glNewList (objet, GL_COMPILE); // Avant d'appeler les fonction glVertex..., on indique quelle texture va être associée à l'objet. // On active l'application de texture... glEnable (GL_TEXTURE_2D); // ... et on indique quelle texture utiliser (celle qui a été créée précédemment). glBindTexture (GL_TEXTURE_2D, texture_name); // On peut enfin créer un objet (ici un simple carré). glBegin (GL_QUADS); glTexCoord2f (0.0, 0.0); glNormal3f (1.0, 1.0, 0.0); glVertex3f (1.0, 1.0, -2.0); glTexCoord2f (0.0, 5.0); glNormal3f (1.0, 1.0, 0.0); glVertex3f (-1.0, 1.0, -2.0); glTexCoord2f (5.0, 5.0); glNormal3f (1.0, 1.0, 0.0); glVertex3f (-1.0, -1.0, -2.0); glTexCoord2f (5.0, 0.0); glNormal3f (1.0, 1.0, 0.0); glVertex3f (1.0, -1.0, -2.0); glEnd (); // Fin de l'application de la texture. glDisable (GL_TEXTURE_2D); // Fin de la liste d'affichage. glEndList ();
J'utilise ici une liste d'affichage pour créer un plan carré. Cette liste comporte toutes les informations sur la texture, de ce fait, un simple glCallList(1) suffira à afficher le carré avec sa texture.
La fonctions la plus importante est l'appel à glTexImage2D. Dans cet exemple, on informe OpenGL qu'on souhaite que chaque composante RGBA soit codée sur 8 bits (un octet: GL_RGBA8).
Ensuite, on indique que les pixels référencés par le pointeur texture->pixels sont codés en RGBA (GL_RGBA) et sont non signés (GL_UNSIGNED_BYTE). Ils contiennent donc une information de transparence.
Lors de la création de l'objet, il est primordial de spécifier les coordonnées de chaque sommet dans la texture via la fonction glTexCoord2f. On en profite aussi pour spécifier les normales.
La capture d'écran qui suit montre un environnement 3D concernant un jeu que je développe actuellement. J'utilise SDL pour lire les fichiers contenant les textures et je les applique aux objets de la même manière que celle présentée dans l'exemple précédent.
[modifier] Conclusion
Voilà, c'est à peu près tout ce qu'il faut pour texturer un objet. Ne pas oublier néanmoins de positionner les normales ainsi qu'une ou plusieurs sources lumineuses sinon, la texture ne sera pas éclairée et paraîtra sombre. Vous pouvez aussi, si vous le souhaitez faire du blending mais là, je n'ai pas encore regardé à quoi ça correspond. Et puis, il y a aussi le bump mapping qui permet de rendre des objets texturés encore plus réalistes. Tout ceci fera peut-être l'objet d'un autre tutoriel. En attendant, amusez-vous bien.
Ce document a été publié sur la version 3 du G.C.N. par ZeDraken.
- Auteur Original : ZeDraken
- Date de publication : 12 mai 2004
Catégories: OpenGL | SDL


