Le source : VolumeRevolution.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Janvier 2004 */
/* Un volume cree par revolution */
/* d'un polygone autour de l'axe Oy */
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include "ModuleManipulateur.h"
#include "ModuleCouleurs.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
#include "ModuleMatriceVecteur.h"
struct Coord2D {
float x;
float y; };
struct Polygone2D {
struct Coord2D *p;
int nbp; };
static int f1;
static int f2;
static int aff = 1;
static struct Coord2D pts1[5] = {{1.0F,1.0F},
{0.5F,2.5F},
{1.5F,4.5F},
{3.5F,3.5F},
{4.0F,0.5F}};
static struct Polygone2D p1 = { pts1,5 };
static struct Coord2D pts2[8] = {{0.5F,2.5F},
{1.0F,4.0F},
{2.5F,4.5F},
{4.0F,4.0F},
{4.5F,2.5F},
{4.0F,1.0F},
{2.5F,0.5F},
{1.0F,1.0F}};
static struct Polygone2D p2 = { pts2,8 };
static int n = 36;
static int nn = 25;
static int np = 0;
static int m = 0;
void myinit(void) {
GLfloat shinines[] = { 50.0 };
GLfloat l_pos[] = { 1.0,1.0,1.0,0.0 };
glClearColor(0.75F,0.75F,1.0F,1.0F) ;
glMaterialfv(GL_FRONT,GL_SPECULAR,couleurBlanc());
glMaterialfv(GL_FRONT,GL_SHININESS,shinines);
glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
void polygone(Polygone2D *p) {
glBegin(GL_LINE_LOOP);
for ( int i = 0 ; i < p->nbp ; i++ )
glVertex2fv((float *) &p->p[i]);
glEnd();
}
void display1() {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glPushMatrix();
switch ( np ) {
case 0 : polygone(&p1);
break;
case 1 : polygone(&p2);
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
vecteur **sommetsVolumeRevolution(Polygone2D *p,int n) {
vecteur **pts =(vecteur **) calloc(n,sizeof(vecteur *));
int i,j;
for ( j = 0 ; j < n ; j++ ) {
float a =(float) j/n*360;
matrice m;
toRotationY(m,a);
pts[j] =(vecteur *) calloc(p->nbp,sizeof(vecteur));
for ( i = 0 ; i < p->nbp ; i++ ) {
pts[j][i][0] = p->p[i].x;
pts[j][i][1] = p->p[i].y;
pts[j][i][2] = 0.0F;
pts[j][i][3] = 1.0F;
produitMatriceVecteur(m,pts[j][i],pts[j][i]); } }
return(pts);
}
void volumeRevolutionFilDeFer(Polygone2D *p,int n) {
vecteur **pts = sommetsVolumeRevolution(p,n);
glLineWidth(1);
int i;
int j;
glColor4fv(couleurBleu());
for ( i = 0 ; i < p->nbp ; i++ ) {
glBegin(GL_LINE_LOOP);
for ( j = 0 ; j < n ; j++ ) {
glVertex3fv((float *) &pts[j][i]); }
glEnd(); }
for ( j = 0 ; j < n ; j++ ) {
glLineWidth(( j != nn) ? 1 : 3);
glColor4fv(( j != nn) ? couleurRouge() : couleurVertFonce());
glBegin(GL_LINE_LOOP);
for ( i = 0 ; i < p->nbp ; i++ ) {
glVertex3fv((float *) &pts[j][i]); }
glEnd(); }
for ( j = 0 ; j < n ; j++ )
free(pts[j]);
free(pts);
}
void calculNormale(vecteur p,vecteur p1,vecteur p2,vecteur n) {
vecteur v1;
vecteur v2;
v1[0] = p1[0] - p[0];
v1[1] = p1[1] - p[1];
v1[2] = p1[2] - p[2];
v2[0] = p2[0] - p[0];
v2[1] = p2[1] - p[1];
v2[2] = p2[2] - p[2];
produitVectoriel(v2,v1,n);
}
void volumeRevolutionSolid(Polygone2D *p,int n) {
vecteur **pts = sommetsVolumeRevolution(p,n);
int i;
int j;
if ( m )
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
else
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
for ( i = 0 ; i < p->nbp ; i++ ) {
glBegin(GL_QUAD_STRIP);
for ( j = 0 ; j <= n ; j++ ) {
vecteur nm;
calculNormale(pts[j%n][i%p->nbp],pts[(j+1)%n][i%p->nbp],pts[j%n][(i+1)%p->nbp],nm);
glNormal3fv((float *) nm);
glVertex3fv((float *) &pts[j%n][i%p->nbp]);
glVertex3fv((float *) &pts[j%n][(i+1)%p->nbp]); }
glEnd(); }
for ( j = 0 ; j < n ; j++ )
free(pts[j]);
free(pts);
}
void display2() {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0F,1.0F,0.0F);
manipulateurSouris();
manipulateurClavier();
glTranslatef(0.0F,-2.5F,0.0F);
switch ( np ) {
case 0 : if ( aff )
volumeRevolutionFilDeFer(&p1,n);
else {
glEnable(GL_LIGHTING);
volumeRevolutionSolid(&p1,n);
glDisable(GL_LIGHTING); }
break;
case 1 : if ( aff )
volumeRevolutionFilDeFer(&p2,n);
else{
glEnable(GL_LIGHTING);
volumeRevolutionSolid(&p2,n);
glDisable(GL_LIGHTING); }
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void key(unsigned char key,int x,int y) {
if ( keyManipulateur(key,x,y) )
glutPostWindowRedisplay(f2);
else
switch ( key ) {
case ' ' : aff = !aff;
glutPostWindowRedisplay(f2);
break;
case 'm' :
case 'M' : m = !m;
glutPostWindowRedisplay(f2);
break;
case 'n' : nn = (nn+1)%n;
glutPostWindowRedisplay(f2);
break;
case 'N' : nn = (nn+n-1)%n;
glutPostWindowRedisplay(f2);
break;
case 45 : n--;
if ( n < 3 )
n = 3;
nn = nn%n;
glutPostWindowRedisplay(f2);
break;
case 43 : n++;
glutPostWindowRedisplay(f2);
break;
case 0x0D : np = (np+1)%2;
glutPostWindowRedisplay(f1);
glutPostWindowRedisplay(f2);
break; }
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitWindowSize(170,170);
glutInitWindowPosition(50,50);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
f1 = glutCreateWindow("Polygone");
creationMenuBasique();
glutDisplayFunc(display1);
setParametresOrthoBasique(0.0,5.0,0.0,5.0,-50.0,50.0);
glutReshapeFunc(reshapeOrthoBasique);
glutKeyboardFunc(key);
glutSpecialFunc(specialBasique);
glutInitWindowSize(250,250);
glutInitWindowPosition(70,250);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
f2 = glutCreateWindow("Volume de révolution");
myinit();
creationMenuBasique();
glutDisplayFunc(display2);
setParametresPerspectiveBasique(65.0F,1.0F,1.0F,20.0F,0.0F,0.0F,-8.5F);
setManipulateurClavierAngle(30.0F,0.0F,10.0F);
setManipulateurDistance(5.0F);
glutReshapeFunc(reshapePerspectiveBasique);
glutKeyboardFunc(key);
glutSpecialFunc(specialBasique);
glutMotionFunc(motionBasique);
glutMouseFunc(sourisBasique);
glutMainLoop();
return(0);
}