Texture OpenGL

Download Report

Transcript Texture OpenGL

Application de texture
en OpenGL
1
Introduction
Jusqu’à maintenant, les objets ont été affichés en utilisant une couleur ou
un dégradé entre les couleurs des sommets.
En appliquant une texture, vous collez une image sur un polygone que vous avez
pu obtenir en scannant une photographie.
L’application de texture est un sujet très vaste et complexe :
les textures peuvent être exprimées en une, deux ou trois dimensions;
on peut appliquer des textures à des surfaces composées de plusieurs
polygones ou à des surfaces courbes;
on peut prendre en compte le contour des objets;
on peut prendre en compte l’environnement dans lequel se trouve un objet
pour donner l’impression que les objets brillants réfléchissent cet
environnement sur leurs surfaces;
on peut appliquer une texture à une surface de plusieurs manières :
« peindre » directement la surface,
utiliser la texture pour moduler la couleur de la surface,
2
fusionner une couleur de texture et une couleur de surface.
Les textures sont simplement des tableaux rectangulaires de couleurs (R, V, B, A).
Ces valeurs d’un tableau de texture sont souvent appelées « texels ».
Exemple d’application de texture :
contour
de l’objet
texture
Déformation de l’objet après affichage
ce qui entraîne une distorsion de la texture.
Selon la taille de la texture, celle de l’image à l’écran et la déformation de l’objet,
plusieurs texels peuvent correspondre à un emplacement sur l’objet ce qui nous
amène à en établir la moyenne, ou encore, les texels peuvent chevaucher plusieurs
emplacements sur l’objet, ce qui revient à en calculer une moyenne pondérée.
3
Étapes nécessaires à l’application d’une texture
0. Construire une texture dans un tableau en mémoire.
const int Largeur = 64;
const int Hauteur = 64;
const int RVBA = 4;
static GLubyte echiquier[Largeur][Hauteur][RVBA];
void Construction_de_la_texture()
{
int i, j, k;
for (i = 0; i < Hauteur; i++)
for (j = 0; j < Largeur; j++)
{
k = (((i&0x8) == 0) ^ ((j&0x8) == 0)) * 255;
echiquier[i][j][0] = (GLubyte) k;
echiquier[i][j][1] = (GLubyte) k;
echiquier[i][j][2] = (GLubyte) k;
echiquier[i][j][3] = (GLubyte) 255;
}
}
1. Appel à « Construction_de_la_texture() » dans la fonction « Initialisation ».
2. Nommer un objet de texture.
Tout entier non signé peut être utilisé comme nom de texture.
Pour éviter les réutilisations accidentelles, demandez à glGenTextures()
de fournir des noms de texture non encore utilisées.
void glGenTextures(GLsizei n, GLuint * Noms_de_texture);
Retourne n noms non utilisés pour les objets de texture dans le
tableau Noms_de_texture. Les noms retournés dans ce tableau
ne sont pas nécessairement des entiers contigus.
Exemple :
Déclaration au début de l’application :
static GLuint Nom_de_texture;
Dans la fonction « Initialisation »,
//
//
Retourne un numéro de texture non utilisé à l’adresse désignée
par le 2ième paramètre.
glGenTextures(1, &Nom_de_texture);
5
Note :
Ces noms de texture sont marqués comme utilisés mais ils n’acquièrent un état
de texture et une dimension (1D, 2D ou 3D) uniquement à l’occasion du
1er chargement.
Zéro est un nom de texture réservé et n’est jamais retourné par glGenTextures()
comme nom de texture.
On peut déterminer si un nom de texture est déjà utilisé :
GLboolean glIsTexture(GLuint Nom_de_texture);
Retourne GL_TRUE si Nom_de_texture est le nom d’une texture qui
a été chargée et qui n’a pas été ultérieurement supprimée.
Retourne GL_FALSE si Nom_de_texture est 0 ou si Nom_de_texture
est différent d’un nom de texture existant.
La primitive retourne GL_FALSE si Nom_de_texture a été
retourné par glGenTextures() mais n’est pas encore chargé
(par au moins un appel de glBindTexture() avec ce nom).
6
3. Créer et utiliser les objets de texture.
Pour créer et utiliser les objets de texture, on emploie la routine :
glBindTexture(GLenum cible, GLuint Nom_de_texture);
Lorsque vous utilisez un entier non signé (Nom_de_texture) pour la
1ière fois, un nouvel objet de texture est créé selon la dimension spécifiée
par cible (GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D)
et se voit assigner ce nom.
Cet objet est généré à partir des valeurs par défaut de l’image et des
propriétés de la texture. Les prochains appels à glTexImage2D(),
glTexSubImage2D(), glCopyTexImage2D(), glCopyTexSubImage2D()
et glTexParameter*() stockent les données dans l’objet de texture.
En réutilisant un entier, vous chargez un objet de texture existant, il devient
actif et ses données représentent l’état de la texture active. Autrement dit,
l’état de la texture précédemment chargée est remplacé par le nouveau.
Exemple :
// Permet de créer un nouvel objet de texture 2D et de lui assigner
// un numéro de texture déjà alloué ou bien de charger un objet de
// texture existant.
7
glBindTexture(GL_TEXTURE_2D, Nom_de_texture);
4. Choix de filtres en l’absence de correspondance exacte entre les texels et les pixels.
Indique comment la texture doit être répétée et comment les couleurs doivent être
filtrées dans le cas où il n'existe pas de correspondance exacte entre les texels de
la texture et les pixels à l'écran.
void glTexParameter{if}( GLenum cible,
GLenum nom_du_parametre,
TYPE valeur_du_parametre);
void glTexParameter{if}v(GLenum cible,
GLenum nom_du_parametre,
TYPE * valeur_du_parametre);
Le 1er paramètre est GL_TEXTURE_1D, GL_TEXTURE_2D ou
GL_TEXTURE_3D pour indiquer une texture 1D, 2D ou 3D.
Les valeurs des 2 autres paramètres apparaissent dans le tableau de la diapositive
suivante.
8
9
Exemple :
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);
10
5. Spécifier la texture associée à un objet.
Permet de spécifier les propriétés de l'image de texture comme, par exemple,
la taille, le type et l'emplacement.
void glTexImage2D
( GLenum cible, // 2 valeurs constantes possibles :
//
GL_TEXTURE_2D
ou
//
GL_PROXY_TEXTURE_2D
//
détermine si les ressources sont suffisantes pour
//
supporter une texture donnée.
GLint niveau, // 0 en présence d’une seule résolution. On peut aussi considérer
// plusieurs niveaux de résolution de la texture pour éviter les effets
// visuels désagréables lorsque les objets texturés sont visionnés à
// des distances différentes du point de vue.
GLint f_interne, // Format interne à sélectionner pour chaque texel. Ce format
// combiné à une fonction de texture détermine le mode
// d’application des textures. 38 constantes symboliques et les
// entiers entre 1 et 4 décrivent la variété de possibilités.
GLsizei Largeur, // Fournit les dimensions de l’image de texture sous la forme
GLsizei Hauteur, // (2m+2b)x(2m+2b) où m est un entier non négatif et b la bordure.
11
// Dimension minimale : 64 x 64 ou 66 x 66 avec les bordures.
GLint Bordure,
// Largeur de la bordure :
//
0 sans bordure,
//
1 avec bordure
//
(voir plus loin).
GLenum format,
// Décrit le format et
// le type des données
// de l’image de texture.
GLenum type,
const GLvoid * texels);
// Décrit la texture et
// sa bordure i.e.
// héberge les données
// de l’image de texture.
ou à un type de données compacté.
12
Exemple :
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, Largeur, Hauteur,
0, GL_RGBA, GL_UNSIGNED_BYTE, echiquier);
6. Activez le mode d’application de la texture.
Il vous faut activer la texture avant d’afficher la scène, en utilisant la primitive
glEnable() à laquelle vous associez la constante symbolique
GL_TEXTURE_1D,
GL_TEXTURE_2D,
GL_TEXTURE_3D ou GL_TEXTURE_CUBE_MAP.
Exemple :
//
//
Permet d'activer le mode d'application de texture 2D dans la fonction
« Affichage ».
glEnable(GL_TEXTURE_2D);
13
7. Indiquez le mode d’application de la texture à chaque pixel.
Jusqu’à maintenant, les valeurs de texture ont été utilisées directement en tant que
couleurs à appliquer à la surface à restituer.
Il est également possible de faire appel aux valeurs associées aux textures
pour moduler la couleur dans laquelle la surface serait restituée en l’absence
de texture.
Il existe un choix très vaste de fonctions de texture définies à l’aide de glTexEnv :
void glTexEnv{if}(GLenum cible, GLenum nom, TYPE parametre);
void glTexEnv{if}v(GLenum cible, GLenum nom, TYPE * parametre);
Intégration d’un modèle de texture à un modèle de rendu
Exemple I :
Pour déterminer de quelle façon les couleurs de la texture sont intégrées dans le
modèle de rendu, l'approche la plus simple est considérée qui consiste à initialiser
l’intensité lumineuse à la valeur de la texture. Aucun autre calcul n'est nécessaire.
glTexEnvf(
GL_TEXTURE_ENV,
GL_TEXTURE_ENV_MODE,
GL_REPLACE);
14
Exemple II :
Sachant que la couleur d’un objet correspond à la couleur de la composante de
lumière diffuse lorsque la surface est éclairée par de la lumière blanche, l’objet
apparaît peint à partir de la texture choisie.
I = element_de_texture(s, t) [ka La + kd cos  Ld] + ks Ls cos,
pour des valeurs appropriées de s et t.
Puisque la couleur de la composante spéculaire correspond à la couleur de la source
lumineuse, la texture est indépendante de la composante spéculaire.
Opengl permet aussi d’opter pour ce type de modèle de texture :
glTexEnvf(
GL_TEXTURE_ENV,
GL_TEXTURE_ENV_MODE,
GL_MODULATE);
15
8. Affichez la scène en spécifiant les coordonnées géométriques des objets et
les coordonnées de texture correspondantes.
Les coordonnées de texture déterminent le texel de la texture qui sera assigné à
un sommet.
Comme pour l’interpolation de couleurs entre 2 sommets de polygones, les
coordonnées de texture sont interpolées entre les sommets.
Les coordonnées de texture peuvent disposer de 1, 2, 3 ou 4 coordonnées (s, t, r, q)
comme suit :
textures 1D :
textures 2D :
textures 3D :
s
s, t
s, t, r.
La coordonnée q permet de créer des coordonnées homogènes.
Les valeurs des coordonnées de texture s’étendent généralement de 0 à 1.
La commande de déclaration des coordonnées de texture, glTexCoord*(), est
comparable à glVertex*(), glColor*() et glNormal*(). Elle est utilisée à l’intérieur
16
d’une paire glBegin() et glEnd().
void glTexCoord{1 2 3 4}{sifd}(TYPE coordonnees);
void glTexCoord{1 2 3 4}{sifd}v(TYPE * coordonnees);
Positionne les coordonnées de texture actives (s, t, r, q). Lors des prochaines
invocations de glVertex*(), ces sommets récupéreront ces coordonnées actives.
Avec glTexCoord1*(), la coordonnée s est positionnée à la valeur spécifiée,
t et r sont positionnées à 0 et q à 1. Quant à glTexCoord2*(), elle permet de
spécifier s et t; r et q sont positionnées resp. à 0 et 1. Avec glTexCoord3*(), q
est positionnée à 1 et les autres coordonnées sont définies comme spécifié.
La commande glTexCoord4*(), permet de spécifier toutes les coordonnées.
Employez le suffixe approprié (s, i, f ou d) et la valeur correspondante pour
TYPE (GLshort, GLint, GLfloat ou GLdouble) pour déclarer le type de données
des coordonnées.
Les coordonnées de texture sont multipliées par la matrice de texturage 4 x 4
avant toute application.
17
Exemple :
Application d’une texture à des surfaces planes.
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glTexCoord2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(-2.0, -1.0, 0.0);
glVertex3f(-2.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(2.41421, 1.0, -1.41421);
glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
Note I : Si la surface et la texture ont des formes différentes, des distorsions peuvent
survenir.
Note II : Si les surfaces ne sont pas planes, on peut définir la normale associée à
chaque sommet avant sa définition.
18
Exemple I de programme élémentaire au complet
Construction d’une texture sous forme d’échiquier et application de la texture à
2 carrés.
//
//
//
Tiré de Mason Woo, Jackie Neider, Tom Davis et Dave Shreiner,
OpenGL 2.0 Le guide officiel pour l'apprentissage et
la maîtrise d'OpenGL 2.0.CAMPUSPRESS, 2006.
#include <windows.h>
#include <GL/glut.h>
#include <GL/glaux.h>
const int Largeur = 64;
const int Hauteur = 64;
const int RVBA = 4;
static GLubyte echiquier[Largeur][Hauteur][RVBA];
static GLuint Nom_de_texture;
19
void Construction_de_la_texture()
{
// Construction d'un échiquier.
int i,j, k;
for (i = 0; i < Hauteur; i++)
for (j = 0; j < Largeur; j++)
{
k = (((i&0x8) == 0) ^ ((j&0x8) == 0)) * 255;
echiquier[i][j][0] = (GLubyte) k;
echiquier[i][j][1] = (GLubyte) k;
echiquier[i][j][2] = (GLubyte) k;
echiquier[i][j][3] = (GLubyte) 255;
}
}
20
void Initialisation(void)
{
//
Permet d'initialiser la couleur de fond RVB.
glClearColor(0.0, 0.0, 0.0, 0.0);
//
Permet d'obtenir un modèle de rendu constant.
glShadeModel(GL_FLAT);
//
Donne accès à un tableau de distances
//
lors de l'élimination des parties cachées.
glEnable(GL_DEPTH_TEST);
Construction_de_la_texture();
//
Retourne un numéro de texture non utilisé
//
à l'adresse désignée par le 2ième paramètre.
glGenTextures(1, &Nom_de_texture);
//
Permet de créer un nouvel objet de texture 2D et
//
de lui assigner ce numéro.
glBindTexture(GL_TEXTURE_2D, Nom_de_texture);
21
//
//
//
//
//
Indique comment la texture doit être répétée et comment
les couleurs doivent être filtrées dans le cas où il
n'existe pas de correspondance exacte entre les texels
de la texture et les pixels à l'écran.
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);
//
//
Permet de spécifier les propriétés de l'image de texture
comme, par exemple, la taille, le type et l'emplacement.
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, Largeur, Hauteur,
0, GL_RGBA, GL_UNSIGNED_BYTE, echiquier);
}
22
void affichage( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
Permet d'activer le mode d'application de texture 2D.
glEnable(GL_TEXTURE_2D);
//
//
//
//
//
Pour déterminer de quelle façon les couleurs de la texture
sont intégrées dans le modèle de rendu, l'approche la plus
simple est considérée; elle consiste à initialiser l’intensité
lumineuse à la valeur de la texture.
Aucun autre calcul n'est nécessaire.
glTexEnvf(
//
GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);
Permet de rendre actif un objet de texture.
glBindTexture(GL_TEXTURE_2D, Nom_de_texture);
23
//
//
2 polygones sont dessinés. Les coordonnées de texture sont
positionnées aux coordonnées des sommets.
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glTexCoord2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(-2.0, -1.0, 0.0);
glVertex3f(-2.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(2.41421, 1.0, -1.41421);
glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
24
Utilisation de la mémoire tampon comme source
des données de texture.
À la place de glTexImage2D, glCopyTexImage2D() lit un rectangle de pixels
dans la mémoire tampon et utilise ce rectangle comme un ensemble de texels
pour composer une nouvelle texture.
void glCopyTexImage2D
( GLenum cible, // Le 1er paramètre doit être positionné à GL_TEXTURE_2D.
GLint niveau, // Idem à glTexImage2D.
GLint f_interne, // Idem à glTexImage2D.
GLint x,
// Coordonnées du sommet inférieur gauche du rectangle de pixels
GLint y,
// aligné sur l’écran.
GLsizei Largeur, // Indique la taille de ce rectangle de pixels dont la forme coïncide
GLsizei Hauteur, // avec celle de glTexImage2D.
GLint Bordure // Largeur de la bordure.
);
25
Proxy de texture
La taille des textures est à prendre en compte. OpenGL offre des outils permettant
d’évaluer si votre implémentation OpenGL est capable de supporter un format de
texture donné à une taille de texture donnée.
GLint *
glGetIntegerv(GL_MAX_TEXTURE_SIZE, parametre);
Retourne la taille de la plus grande texture carrée supportée. Cela ne tient pas
compte du format interne de chaque texel.
Pour les textures 3D, on utilise plutôt GL_MAX_3D_TEXTURE_SIZE.
glTexImage2D( GL_PROXY_TEXTURE_2D, niveau, f_interne, Largeur, Hauteur,
Bordure, format, type, NULL);
Permet de savoir si les ressources sont suffisantes pour une texture 2D standard.
26
void glGetTexLevelParameter{if}v( GLenum cible, GLint niveau,
GLenum nom_variable_d_etat,
TYPE * parametre);
Permet de savoir si les ressources suffisent pour héberger votre texture. Si elles
sont insuffisantes p/r à une variable d’état (largeur, hauteur de la texture,
largeur de bordure, …), la valeur 0 est retournée.
Exemple :
GLint Largeur;
glTexImage2D(
GL_PROXY_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &Largeur);
27
Remplacer en tout ou en partie une texture
Il est souvent préférable de remplacer en tout ou en partie une image de texture
par de nouvelles données, plutôt que d’en créer une nouvelle.
void glTexSubImage2D( GLenum cible, // GL_TEXTURE_2D est utilisé.
GLint niveau,
// voir glTexImage2D().
GLint decalage_x,// Position relative des texels p/r à (0, 0)
GLint decalage_y,// représentant le coin inférieur gauche
// de la texture.
GLsizei Largeur, // Dimensions de la région destinée à
GLsizei Hauteur, // remplacer en tout ou en partie la
// texture active.
GLenum format, // voir glTexImage2D().
GLenum type, // voir glTexImage2D().
const GLvoid * texels); // Accueille les données de la
// sous-image de texture.
Définit une texture 2D qui remplace en tout ou en partie une région à l’intérieur
de la texture active 2D.
Note : La mémoire tampon peut faire office de source de données; glTexSubImage2D
peut être remplacée par glCopyTexSubImage2D() qui lit un rectangle de pixels
dans la mémoire tampon et modifie une portion de la texture existante. 28
Exemple : Modification de la texture précédente.
//
//
//
Tiré de Mason Woo, Jackie Neider, Tom Davis et Dave Shreiner,
OpenGL 2.0 Le guide officiel pour l'apprentissage et
la maîtrise d'OpenGL 2.0.CAMPUSPRESS, 2006.
#include <windows.h>
#include <GL/glut.h>
#include <GL/glaux.h>
const int Largeur_Image = 64;
const int Hauteur_Image = 64;
const int Largeur_Sous_Image = 16;
const int Hauteur_Sous_Image = 16;
const int RVBA = 4;
static GLubyte echiquier[Largeur_Image][Hauteur_Image][RVBA];
static GLubyte Sous_image[Largeur_Sous_Image][Hauteur_Sous_Image][RVBA];
static GLuint Nom_de_texture;
29
void Construction_des_textures()
{
// Construction d'un échiquier.
int i, j, k;
for (i = 0; i < Hauteur_Image; i++)
for (j = 0; j < Largeur_Image; j++)
{
k = (((i&0x8)==0) ^ ((j&0x8)==0)) * 255;
echiquier[i][j][0] = (GLubyte) k;
echiquier[i][j][1] = (GLubyte) k;
echiquier[i][j][2] = (GLubyte) k;
echiquier[i][j][3] = (GLubyte) 255;
}
// Construction d'un échiquier réduit.
for (i = 0; i < Hauteur_Sous_Image; i++)
for (j = 0; j < Largeur_Sous_Image; j++)
{
k = (((i&0x4)==0) ^ ((j&0x4)==0)) * 255;
Sous_image[i][j][0] = (GLubyte) k;
Sous_image[i][j][1] = (GLubyte) 0;
Sous_image[i][j][2] = (GLubyte) 0;
Sous_image[i][j][3] = (GLubyte) 255;
}
}
30
void clavier(unsigned char cle, int x, int y)
{
switch(cle)
{
case 's': case 'S':
glBindTexture(GL_TEXTURE_2D, Nom_de_texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 20, 32,
Largeur_Sous_Image, Hauteur_Sous_Image, GL_RGBA,
GL_UNSIGNED_BYTE, Sous_image);
glutPostRedisplay();
break;
case 'r': case 'R':
glBindTexture(GL_TEXTURE_2D, Nom_de_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
Largeur_Image, Hauteur_Image, 0, GL_RGBA,
GL_UNSIGNED_BYTE, echiquier);
glutPostRedisplay();
break;
default: break;
}
31
}
Note :
Les autres fonctions demeurent inchangées ou presque.
Exemple :
//
//
//
Chargement de plusieurs textures.
Tiré de Mason Woo, Jackie Neider, Tom Davis et Dave Shreiner,
OpenGL 2.0 Le guide officiel pour l'apprentissage et
la maîtrise d'OpenGL 2.0.CAMPUSPRESS, 2006.
#include <windows.h>
#include <GL/glut.h>
#include <GL/glaux.h>
const int Largeur = 64;
const int Hauteur = 64;
const int RVBA = 4;
static GLubyte Premiere_image[Largeur][Hauteur][RVBA];
static GLubyte Deuxieme_image[Largeur][Hauteur][RVBA];
static GLuint Nom_de_texture[2];
32
void Construction_de_textures()
{
int i, j, k;
for (i = 0; i < Hauteur; i++)
for (j = 0; j < Largeur; j++)
{
k = (((i&0x8)==0) ^ ((j&0x8)==0)) * 255;
Premiere_image[i][j][0] = (GLubyte) k;
Premiere_image[i][j][1] = (GLubyte) k;
Premiere_image[i][j][2] = (GLubyte) k;
Premiere_image[i][j][3] = (GLubyte) 255;
k = (((i&0x10)==0) ^ ((j&0x10)==0)) * 255;
Deuxieme_image[i][j][0] = (GLubyte) k;
Deuxieme_image[i][j][1] = (GLubyte) 0;
Deuxieme_image[i][j][2] = (GLubyte) 0;
Deuxieme_image[i][j][3] = (GLubyte) 255;
}
}
33
void Initialisation(void)
{
//
Permet d'initialiser la couleur de fond RVB.
glClearColor(0.0, 0.0, 0.0, 0.0);
//
Permet d'obtenir un modèle de rendu constant.
glShadeModel(GL_FLAT);
//
Donne accès à un tableau de distances
//
lors de l'élimination des parties cachées.
glEnable(GL_DEPTH_TEST);
Construction_de_textures();
//
Retourne un numéro de texture non utilisé
//
à l'adresse désignée par le 2ième paramètre.
glGenTextures(2, Nom_de_texture);
//
Permet de créer un nouvel objet de texture 2D et
//
de lui assigner ce numéro.
glBindTexture(GL_TEXTURE_2D, Nom_de_texture[0]);
34
//
//
//
Indique comment la texture doit être répétée et les couleurs filtrées
dans le cas où il n'existe pas de correspondance exacte entre les
texels de la texture et les pixels à l'écran.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//
Permet de spécifier les propriétés de l'image de texture comme,
//
par exemple, la taille, le type et l'emplacement.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Largeur, Hauteur,
0, GL_RGBA, GL_UNSIGNED_BYTE, Premiere_image);
glBindTexture(GL_TEXTURE_2D, Nom_de_texture[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
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, Largeur, Hauteur,
0, GL_RGBA, GL_UNSIGNED_BYTE, Deuxieme_image);
}
35
void affichage( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
Permet d'activer le mode d'application de texture 2D.
glEnable(GL_TEXTURE_2D);
//
//
//
//
Pour déterminer de quelle façon les couleurs de la texture sont
intégrées dans le modèle de rendu, l'approche la plus simple est
considérée; elle consiste à initialiser l’intensité lumineuse à la
valeur de la texture. Aucun autre calcul est nécessaire.
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);
//
Permet de rendre actif un objet de texture.
glBindTexture(GL_TEXTURE_2D, Nom_de_texture[0]);
36
//
//
2 polygones sont dessinés. Les coordonnées de texture sont
positionnées aux coordonnées des sommets.
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glEnd();
glVertex3f(-2.0, -1.0, 0.0);
glVertex3f(-2.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glBindTexture(GL_TEXTURE_2D, Nom_de_texture[1]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
37
Textures à une dimension
Dans certaines situations, les textures 1D sont suffisantes.
Ex. : Dessin de bandes texturées dont toutes les variations s’effectuent
dans une seule direction.
Les textures 1D se comportent comme une texture 2D avec une hauteur égale à 1
et une absence de bordures en haut et en bas.
void glTexImage1D
(
GLenum cible,
GLint niveau,
GLint f_interne,
GLsizei Largeur, // 2m ou (2m+2 en présence d’une bordure) où m est un
// entier non négatif.
GLint Bordure,
GLenum format,
GLenum type,
const GLvoid * texels
// texels est un tableau 1D.
);
Tous les autres paramètres ont la même signification que glTexImage2D.
38
Note :
Toutes les routines de définition de texture 2D et de sous-texture 2D possèdent
leurs « homologues » 1D :
glCopyTexSubImage1D()
Exemple de texture 1D :
#include <windows.h>
#include <GL/glut.h>
#include <GL/glaux.h>
const int Largeur = 64;
const int Hauteur = 64;
const int RVBA = 4;
static GLubyte Premiere_image[Largeur][Hauteur][RVBA];
static GLubyte Deuxieme_image[Largeur][RVBA];
static GLuint Nom_de_texture[2];
39
void Construction_de_textures()
{
int i, j, k;
for (i = 0; i < Hauteur; i++)
{
for (j = 0; j < Largeur; j++)
{
k = (((i&0x8)==0) ^ ((j&0x8)==0)) * 255;
Premiere_image[i][j][0] = (GLubyte) k;
Premiere_image[i][j][1] = (GLubyte) k;
Premiere_image[i][j][2] = (GLubyte) k;
Premiere_image[i][j][3] = (GLubyte) 255;
}
k = ((i&0x8)==0) * 255;
Deuxieme_image[i][0] = (GLubyte) k;
Deuxieme_image[i][1] = (GLubyte) 0;
Deuxieme_image[i][2] = (GLubyte) 0;
Deuxieme_image[i][3] = (GLubyte) 255;
}
}
40
void Initialisation(void)
{
//
Permet d'initialiser la couleur de fond RVB.
glClearColor(0.0, 0.0, 0.0, 0.0);
//
Permet d'obtenir un modèle de rendu constant.
glShadeModel(GL_FLAT);
//
//
Donne accès à un tableau de distances
lors de l'élimination des parties cachées.
glEnable(GL_DEPTH_TEST);
Construction_de_textures();
//
//
Retourne un numéro de texture non utilisé
à l'adresse désignée par le 2 ième paramètre.
glGenTextures(2, Nom_de_texture);
41
//
//
Permet de créer un nouvel objet de texture 2D et
de lui assigner ce numéro.
glBindTexture(GL_TEXTURE_2D, Nom_de_texture[0]);
//
//
//
Indique comment la texture doit être répétée et les couleurs doivent
être filtrées dans le cas où il n’existe pas de correspondance
exacte entre les texels de la texture et les pixels à l'écran.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//
//
Permet de spécifier les propriétés de l'image de texture
comme, par exemple, la taille, le type et l'emplacement.
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, Largeur, Hauteur, 0,
GL_RGBA, GL_UNSIGNED_BYTE, Premiere_image);
42
//
//
Permet de créer un nouvel objet de texture 1D et de lui assigner ce
numéro.
glBindTexture(GL_TEXTURE_1D, Nom_de_texture[1]);
//
//
//
//
Indique comment la texture doit être répétée et les couleurs doivent
être filtrées dans le cas où il n’existe pas de correspondance exacte
entre les texels de la texture et les pixels à l'écran.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//
//
Permet de spécifier les propriétés de l'image de texture comme,
par exemple, la taille, le type et l'emplacement.
glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, Largeur, 0,
GL_RGBA, GL_UNSIGNED_BYTE, Deuxieme_image);
}
43
void affichage( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
Permet d'activer le mode d'application de texture 2D.
glEnable(GL_TEXTURE_2D);
//
//
//
//
Pour déterminer de quelle façon les couleurs de la texture sont
intégrées dans le modèle de rendu, l'approche la plus simple est
considérée; elle consiste à initialiser l'intensité lumineuse à la
valeur de la texture. Aucun autre calcul est nécessaire.
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//
Permet de rendre actif un objet de texture.
glBindTexture(GL_TEXTURE_2D, Nom_de_texture[0]);
//
//
2 polygones sont dessinés. Les coordonnées de texture sont
positionnées aux coordonnées des sommets.
44
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glTexCoord2f(1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glEnd();
glVertex3f(-2.0, -1.0, 0.0);
glVertex3f(-2.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_1D);
glBindTexture(GL_TEXTURE_1D, Nom_de_texture[1]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glFlush();
glDisable(GL_TEXTURE_1D);
}
45
Textures tridimensionnelles
Images de textures compressées
Bordures de textures
Niveaux de détail multiples
Filtrage
Textures résidentes et suppression de textures
Etc.
46