Scène initiale sans et avec animation
Scène avec composantes de lumière diffuse, spéculaire, ambiante et émise
Composantes individuelles diffuse et spéculaire
Composantes individuelles ambiante et émise
Fichier source : LightsAndMaterial.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Octobre 2007 */
/* Materiel et lumieres sur des spheres */
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
/* Variables globales */
static int mode = 0;
static int disc = 120;
static float py = 0.0F;
static float angle = 0.0F;
static const float blanc[] = { 1.0F,1.0F,1.0F,1.0F };
static const float rouge[] = { 1.0F,0.0F,0.0F,1.0F };
static const float vert[] = { 0.0F,1.0F,0.0F,1.0F };
static const float bleu[] = { 0.0F,0.0F,1.0F,1.0F };
static const float gris[] = { 0.25F,0.25F,0.25F,1.0F };
static const float noir[] = { 0.0F,0.0F,0.0F,1.0F };
/* Variables globales de gestion */
/* de l'interactivite clavier et souris */
static int clic = 0;
static int mx;
static int my;
static float rx = 0.0F;
static float ry = 0.0F;
static float zoom = 1.0F;
/* Fonction d'affichage d'une eventuelle */
/* erreur OpenGL */
static void checkError(int line) {
GLenum err = glGetError();
if (err) {
printf("GL Error %s (0x%x) at line %d\n",
gluErrorString(err), (int) err, line); }
}
/* Fonction d'initialisation de certains */
/* parametres de l'environnement OpenGL */
/* et allocation des tableaux de stockage */
/* des informations relatives aux particules */
void init(void) {
glClearColor(0.0F,0.0F,0.0F,1.0F);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glMaterialf(GL_FRONT,GL_SHININESS,32.0F);
}
void configurationLumieres() {
{ GLfloat l_pos[] = { 1.0F,0.0F,0.0F,0.0F };
glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
glLightfv(GL_LIGHT0,GL_AMBIENT,(mode == 0) ? noir : gris); }
{ GLfloat l_pos[] = { 0.0F,py,0.0F,1.0F };
glLightfv(GL_LIGHT1,GL_POSITION,l_pos);
glLightfv(GL_LIGHT1,GL_DIFFUSE,blanc);
glLightfv(GL_LIGHT1,GL_SPECULAR,blanc);
glLightfv(GL_LIGHT1,GL_AMBIENT,(mode == 0) ? noir : gris); }
{ GLfloat l_pos[] = { 0.0F,0.0F,10.0F,1.0F };
GLfloat l_dir[] = { 0.0F,0.0F,-1.0F,0.0F };
glLightfv(GL_LIGHT2,GL_POSITION,l_pos);
glLightfv(GL_LIGHT2,GL_DIFFUSE,blanc);
glLightfv(GL_LIGHT2,GL_SPECULAR,blanc);
glLightfv(GL_LIGHT2,GL_AMBIENT,(mode == 0) ? noir : gris);
{ glPushMatrix();
glRotatef(angle,0.0F,1.0F,0.0F);
glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,l_dir);
glPopMatrix(); }
glLightf(GL_LIGHT2,GL_SPOT_CUTOFF,25); }
}
void configurationMateriel() {
switch (mode) {
case 0 : glMaterialfv(GL_FRONT,GL_DIFFUSE,rouge);
glMaterialfv(GL_FRONT,GL_SPECULAR,vert);
glMaterialfv(GL_FRONT,GL_AMBIENT,noir);
glMaterialfv(GL_FRONT,GL_EMISSION,noir);
break;
case 1 : glMaterialfv(GL_FRONT,GL_DIFFUSE,vert);
glMaterialfv(GL_FRONT,GL_SPECULAR,bleu);
glMaterialfv(GL_FRONT,GL_AMBIENT,gris);
glMaterialfv(GL_FRONT,GL_EMISSION,gris);
break;
case 2 : glMaterialfv(GL_FRONT,GL_DIFFUSE,vert);
glMaterialfv(GL_FRONT,GL_SPECULAR,noir);
glMaterialfv(GL_FRONT,GL_AMBIENT,noir);
glMaterialfv(GL_FRONT,GL_EMISSION,noir);
break;
case 3 : glMaterialfv(GL_FRONT,GL_DIFFUSE,noir);
glMaterialfv(GL_FRONT,GL_SPECULAR,bleu);
glMaterialfv(GL_FRONT,GL_AMBIENT,noir);
glMaterialfv(GL_FRONT,GL_EMISSION,noir);
break;
case 4 : glMaterialfv(GL_FRONT,GL_DIFFUSE,noir);
glMaterialfv(GL_FRONT,GL_SPECULAR,noir);
glMaterialfv(GL_FRONT,GL_AMBIENT,gris);
glMaterialfv(GL_FRONT,GL_EMISSION,noir);
break;
case 5 : glMaterialfv(GL_FRONT,GL_DIFFUSE,noir);
glMaterialfv(GL_FRONT,GL_SPECULAR,noir);
glMaterialfv(GL_FRONT,GL_AMBIENT,noir);
glMaterialfv(GL_FRONT,GL_EMISSION,gris);
break; }
}
void scene(void) {
glPushMatrix();
glutSolidSphere(5.0,disc,disc);
glTranslatef(10.0F,0.0F,0.0F);
glutSolidSphere(2.0,disc,disc);
glPopMatrix();
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin */
void display(void) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(rx,1.0F,0.0F,0.0F);
glRotatef(ry,0.0F,1.0F,0.0F);
glScalef(zoom,zoom,zoom);
configurationLumieres();
configurationMateriel();
scene();
glPopMatrix();
glFlush();
glutSwapBuffers();
checkError(__LINE__);
}
/* Fonction executee lors d'un changement */
/* de la taille de la fenetre OpenGL */
/* Configuration d'une camera de visualisation */
/* en projection en perspective */
void reshape(int tx,int ty) {
glViewport(0,0,tx,ty);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40,(double) tx/ty,0.1,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(3.5F,0.0F,20.0F,3.5F,0.0F,0.0F,0.0F,1.0F,0.0F);
}
/* Fonction executee lorsqu'aucun evenement */
/* n'est en attente de gestion */
static void idle1(void) {
static float dy = 0.1F;
py += dy;
if ( ( py <= -10.0F ) || ( py >= 10.0F ) )
dy = -dy;
glutPostRedisplay();
}
/* Fonction executee lorsqu'aucun evenement */
/* n'est en attente de gestion */
static void idle2(void) {
idle1();
angle += 1.0F;
glutPostRedisplay();
}
/* Fonction executee lors de la frappe */
/* d'une touche alphanumerique du clavier */
void key(unsigned char key,int x,int y) {
switch ( key ) {
case 43 : disc++;
glutPostRedisplay();
break;
case 45 : disc--;
if ( disc < 3 )
disc = 3;
glutPostRedisplay();
break;
case 'r' :
case 'R' : angle = 0.0F;
py = 0.0F;
glutPostRedisplay();
break;
case 0x20 : { static int anim = 0;
anim = (anim+1)%3;
switch (anim) {
case 0 : glutIdleFunc(NULL);
break;
case 1 : glutIdleFunc(idle1);
break;
case 2 : glutIdleFunc(idle2);
break; } }
break;
case 0x0D : mode = (mode+1)%6;
glutPostRedisplay();
break;
case 0x1B : exit(0);
break; }
}
/* Fonction executee lors de la frappe */
/* d'une touche non alphanumerique du clavier */
void special(int key,int x,int y) {
switch ( key ) {
case GLUT_KEY_UP : zoom *= 0.99F;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN : zoom /= 0.99F;
glutPostRedisplay();
break; }
}
/* Fonction executee lors d'un clic de souris */
/* dans la fenetre */
void mouse(int bouton,int etat,int x,int y) {
if ( bouton == GLUT_LEFT_BUTTON ) {
if ( etat == GLUT_DOWN ) {
clic = 1;
mx = x;
my = y; }
if ( etat == GLUT_UP ) {
clic = 0; } }
}
/* Fonction executee lors d'un deplacement */
/* de la souris sur la fenetre */
/* avec un bouton appuye */
void motion(int x,int y) {
if ( clic ) {
ry += (x-mx);
rx += (y-my);
mx = x;
my = y;
glutPostRedisplay(); }
}
/* Fonction principale */
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(260,180);
glutInitWindowPosition(50,50);
glutCreateWindow("Materiel et lumieres");
init();
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}