/**************/
/* Texture2.c */
/**************/
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <tiffio.h>
#include <string.h>
#include <math.h>
#define PI 3.14159265
/* declaration des variables */
float distance=2.5; /* distance de l'observateur a l'origine */
int anglex=30,angley=20,xprec,yprec; /* stockage des déplacements de souris */
GLbitfield masqueClear; /* masque pour l'utilisation de glClear() */
GLfloat couleurAP[]={0.8,0.8,0.8,1.0}; /* couleur de fond */
int IdTex[2]; /* tableau d'Id pour les 2 textures */
float decalage=0; /* décalage de la texture procedurale pour l'animation */
/* Parametres de lumière */
GLfloat L0pos[]={ 0.0,2.0,-1.0};
GLfloat L0dif[]={ 1.0,0.6,0.6};
GLfloat L1pos[]={ 2.0,2.0,2.0};
GLfloat L1dif[]={ 0.0,0.5,1.0};
GLfloat Mspec[]={0.5,0.5,0.5};
GLfloat Mshiny=50;
/* déclaration des indicateurs booleens */
unsigned char b_gauche=0; /* le bouton gauche de la souris est il presse ? */
unsigned char b_droit=0; /* le bouton gauche de la souris est il presse ? */
unsigned char prof=1; /* Tampon de profondeur */
unsigned char brouillard=0; /* brouillard */
unsigned char eclairage=1; /* eclairage */
unsigned char separe=1; /* séparation de la composante spéculaire pour
l'éclairage des textures */
/* prototypes des fonctions */
void init();
void affichage();
void clavier(unsigned char key,int x,int y);
void souris(int button, int state,int x,int y);
void mouvSouris(int x,int y);
void redim(int w,int h);
void inactif();
void chargeTextureTiff(char *fichier,int numtex);
void chargeTextureProc(int numtex);
int fonctionTexture(int x,int y);
/**********************************/
/* int main(int argc,char **argv) */
/**********************************/
/* fonction principale */
/**********************************/
int main(int argc,char **argv)
{
/* initialisation de glut */
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(400,400);
glutCreateWindow(argv[0]);
/* Chargement des textures */
glGenTextures(2,IdTex);
chargeTextureTiff("texture.tif",IdTex[0]);
chargeTextureProc(IdTex[1]);
/* initialisation d'OpenGL */
init();
/* mise en place des fonctions de rappel glut */
glutDisplayFunc(affichage);
glutKeyboardFunc(clavier);
glutMouseFunc(souris);
glutMotionFunc(mouvSouris);
glutReshapeFunc(redim);
glutIdleFunc(inactif);
/* Boucle principale */
glutMainLoop();
return 0;
}
/***************************/
/* void init() */
/***************************/
/* Initialisation d'OpenGL */
/***************************/
void init()
{
/* Parametres de base */
glClearColor(couleurAP[0],couleurAP[1],couleurAP[2],couleurAP[3]);
glColor3f(1.0,1.0,1.0);
glShadeModel(GL_SMOOTH);
/* Parametres de perspective */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,1,0.1,16.0);
glMatrixMode(GL_MODELVIEW);
/* Paramètres d'eclaraiage */
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT0,GL_DIFFUSE,L0dif);
glLightfv(GL_LIGHT0,GL_SPECULAR,L0dif);
glLightfv(GL_LIGHT1,GL_DIFFUSE,L1dif);
glLightfv(GL_LIGHT1,GL_SPECULAR,L1dif);
if (eclairage)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
if (separe)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
else
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
/* Paramétres du matériau */
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Mspec);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,Mshiny);
/* Mise en place des textures */
glEnable(GL_TEXTURE_2D);
/* mise en place du tampon de profondeur */
if (prof) {
masqueClear=GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
glEnable(GL_DEPTH_TEST);
}
else {
masqueClear=GL_COLOR_BUFFER_BIT;
glDisable(GL_DEPTH_TEST);
}
/* Mise en place du brouillard */
glFogi(GL_FOG_MODE,GL_EXP);
glFogfv(GL_FOG_COLOR,couleurAP);
glFogf(GL_FOG_START,0);
glFogf(GL_FOG_END,15);
glFogf(GL_FOG_DENSITY,0.35);
if (brouillard)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
}
/***************************************/
/* void affichage() */
/***************************************/
/* fonction de rappel pour l'affichage */
/***************************************/
void affichage()
{
glClear(masqueClear);
/* Positionnement de l'observateur (ou de l'objet) */
glLoadIdentity();
gluLookAt(0.0,0.0,distance,0.0,0.0,0.0,0.0,1.0,0.0);
glRotatef(angley,1.0,0.0,0.0);
glRotatef(anglex,0.0,1.0,0.0);
/* Description de l'obet */
glBindTexture(GL_TEXTURE_2D,IdTex[0]);
glBegin(GL_POLYGON);
glNormal3f(0.0,0.0,1.0);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5, 0.5);
glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5, 0.5);
glTexCoord2f(1.0,1.0); glVertex3f( 0.5, 0.5, 0.5);
glEnd();
glBindTexture(GL_TEXTURE_2D,IdTex[1]);
glBegin(GL_POLYGON);
glNormal3f(1.0,0.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f( 0.5, 0.5, 0.5);
glTexCoord2f(0.0,0.0); glVertex3f( 0.5,-0.5, 0.5);
glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5,-0.5);
glTexCoord2f(1.0,1.0); glVertex3f( 0.5, 0.5,-0.5);
glEnd();
glBindTexture(GL_TEXTURE_2D,IdTex[0]);
glBegin(GL_POLYGON);
glNormal3f(0.0,0.0,-1.0);
glTexCoord2f(0.0,1.0); glVertex3f( 0.5, 0.5,-0.5);
glTexCoord2f(0.0,0.0); glVertex3f( 0.5,-0.5,-0.5);
glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5,-0.5);
glTexCoord2f(1.0,1.0); glVertex3f(-0.5, 0.5,-0.5);
glEnd();
glBindTexture(GL_TEXTURE_2D,IdTex[1]);
glBegin(GL_POLYGON);
glNormal3f(-1.0,0.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5, 0.5,-0.5);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5,-0.5);
glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5, 0.5);
glTexCoord2f(1.0,1.0); glVertex3f(-0.5, 0.5, 0.5);
glEnd();
glBindTexture(GL_TEXTURE_2D,IdTex[0]);
glBegin(GL_POLYGON);
glNormal3f(0.0,1.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5, 0.5,-0.5);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(1.0,0.0); glVertex3f( 0.5, 0.5, 0.5);
glTexCoord2f(1.0,1.0); glVertex3f( 0.5, 0.5,-0.5);
glEnd();
glBindTexture(GL_TEXTURE_2D,IdTex[1]);
glBegin(GL_POLYGON);
glNormal3f(0.0,-1.0,0.0);
glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5,-0.5);
glTexCoord2f(0.0,1.0); glVertex3f(-0.5,-0.5, 0.5);
glTexCoord2f(1.0,1.0); glVertex3f( 0.5,-0.5, 0.5);
glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5,-0.5);
glEnd();
/* echange de tampon (double buffering)*/
glutSwapBuffers();
}
/**************************************************/
/* void clavier(unsigned char touche,int x,int y) */
/**************************************************/
/* fonction de rappel clavier */
/**************************************************/
void clavier(unsigned char touche,int x,int y)
{
switch (touche) {
case 'p': /* bascule tampon de profondeur */
prof=1-prof;
if (prof) {
masqueClear=GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
glEnable(GL_DEPTH_TEST);
}
else {
masqueClear=GL_COLOR_BUFFER_BIT;
glDisable(GL_DEPTH_TEST);
}
glutPostRedisplay();
break;
case 'b': /* bascule brouillard */
brouillard=1-brouillard;
if (brouillard)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
glutPostRedisplay();
break;
case 'e' : /* bascule eclairage */
eclairage=1-eclairage;
if (eclairage)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
glutPostRedisplay();
break;
case 's' : /* bascule séparation eclairage speculaire */
separe=1-separe;
if (separe)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
else
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
glutPostRedisplay();
break;
case 27: /* touche escape pour quitter */
exit(0);
default :
}
}
/***********************************************************/
/* void souris(int bouton, int etat,int x,int y) */
/***********************************************************/
/* fonction de rappel pour l'appui sur un bouton de souris */
/***********************************************************/
void souris(int bouton, int etat,int x,int y)
{
if (bouton == GLUT_LEFT_BUTTON && etat == GLUT_DOWN) {
b_gauche = 1;
xprec = x;
yprec=y;
}
if (bouton == GLUT_LEFT_BUTTON && etat == GLUT_UP)
b_gauche=0;
if (bouton == GLUT_RIGHT_BUTTON && etat == GLUT_DOWN) {
b_droit = 1;
yprec=y;
}
if (bouton == GLUT_RIGHT_BUTTON && etat == GLUT_UP)
b_droit=0;
}
/***************************************************/
/* void mouvSouris(int x,int y) */
/***************************************************/
/* fonction de rappel pour les mouvement de souris */
/***************************************************/
void mouvSouris(int x,int y)
{
/* si le bouton gauche est presse */
if (b_gauche) {
anglex=anglex+(x-xprec);
angley=angley+(y-yprec);
glutPostRedisplay();
xprec=x;
yprec=y;
}
/* si le bouton gauche est presse */
if (b_droit) {
distance+=((float)(y-yprec))/10.0;
if (distance<1.0)
distance=1.0;
if (distance>15.0)
distance=15.0;
glutPostRedisplay();
yprec=y;
}
}
/****************************************************************/
/* void redim(int l,int h) */
/****************************************************************/
/* fonction de rappel pour les redimensionnements de la fenetre */
/****************************************************************/
void redim(int l,int h)
{
if (l<h)
glViewport(0,(h-l)/2,l,l);
else
glViewport((l-h)/2,0,h,h);
}
/****************************************************/
/* void inactif */
/****************************************************/
/* fonction de rappel pour pour l'inactivité (idle) */
/****************************************************/
void inactif()
{
/* increment du décalage */
decalage+=0.1;
if (decalage>2*PI)
decalage-=2*PI;
/* rechargement de la texture */
chargeTextureProc(IdTex[1]);
glutPostRedisplay();
}
/****************************************************/
/* void chargeTextureTiff(char *fichier,int numtex) */
/****************************************************/
/* chargement de l'image tif 'fichier' et placement */
/* dans la texture de numero 'numtex' */
/****************************************************/
void chargeTextureTiff(char *fichier,int numtex)
{
unsigned char image[256][256][3];
uint32 l, h;
int i,j;
size_t npixels;
uint32* raster;
/* chargement de l'image TIF */
TIFF* tif = TIFFOpen(fichier, "r");
if (tif) {
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &l);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
npixels = l * h;
raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
if (raster != NULL) {
/* lecture de l'image */
if (TIFFReadRGBAImage(tif, l, h, raster, 1)) {
/* transfert de l'image vers le tableau 'image' */
for (i=0;i<256;i++)
for (j=0;j<256;j++) {
image[i][j][0]=((unsigned char *)raster)[i*256*4+j*4+0];
image[i][j][1]=((unsigned char *)raster)[i*256*4+j*4+1];
image[i][j][2]=((unsigned char *)raster)[i*256*4+j*4+2];
}
}
else {
printf("erreur de chargement du fichier %s\n",fichier);
exit(0);
}
_TIFFfree(raster);
}
TIFFClose(tif);
/* paramétrage de la texture */
glBindTexture(GL_TEXTURE_2D,numtex);
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,256,256,0,
GL_RGB,GL_UNSIGNED_BYTE,image);
}
}
/**************************************/
/* void chargeTextureProc(int numtex) */
/**************************************/
/* Création de la texture procedurale */
/* de numero 'numtex' */
/**************************************/
void chargeTextureProc(int numtex)
{
unsigned char image[256][256][3];
int i,j;
int a;
/* calcule de l'image */
for (i=0;i<256;i++)
for (j=0;j<256;j++) {
a=fonctionTexture(i,j);
image[i][j][0]=a;
image[i][j][1]=128;
image[i][j][2]=128;
}
/* Paramètrage de la texture */
glBindTexture(GL_TEXTURE_2D,numtex);
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,256,256,0,
GL_RGB,GL_UNSIGNED_BYTE,image);
}
/*****************************************************/
/* int fonctionTexture(int x,int y) */
/*****************************************************/
/* Calcule et renvoie la valeur de la fonction */
/* utilisee pour la texture procedurale au point x,y */
/*****************************************************/
int fonctionTexture(int x,int y)
{
float dx=(128.0-(float)x)/255.0*40.0;
float dy=(128.0-(float)y)/255.0*40.0;
float a=cos(sqrt(dx*dx+dy*dy)+decalage);
return (int)((a+1.0)/2.0*255);
}