/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Janvier 2001 */
/* Deux spheres en flat et en Gouraud */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "ModuleMatriceVecteur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
#include "ModuleManipulateur.h"
#include "ModuleCouleurs.h"
static int aff = 0;
static int niv = 2;
static int disc1 = 18;
static int disc2 = 36;
static vecteur ldir = { 1.0F,1.0F,1.0F,1.0F };
void myinit(void) {
glClearColor(0.5F,0.5F,0.8F,1.0F) ;
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
normalise(ldir);
}
vecteur **coordonnees(int n,int m) {
vecteur **p =(vecteur **) calloc(n,sizeof(vecteur *));
int i;
for ( i = 0 ; i < n ; i++ )
p[i] =(vecteur *) calloc(m,sizeof(vecteur));
for ( i = 1 ; i <= n ;i++ ) {
float a = -3.14159F/2.0F + i*3.14159/(n+1);
float csa = cos(a);
float sna = sin(a);
for ( int j = 0 ; j < m ;j++ ) {
float b = j*3.14159F*2.0F/m;
float csb = cos(b);
float snb = sin(b);
p[i-1][j][0] = csb*csa;
p[i-1][j][1] = snb*csa;
p[i-1][j][2] = sna; } }
return(p);
}
void colorise(vecteur n,vecteur ldir) {
float v = produitScalaire(n,ldir);
if ( v < 0.0F )
v = 0.0F;
glColor3f(v,v,v);
}
void flatFacette3(vecteur p1,vecteur p2,vecteur p3,float r) {
vecteur n;
n[0] = p1[0]+p2[0]+p3[0];
n[1] = p1[1]+p2[1]+p3[1];
n[2] = p1[2]+p2[2]+p3[2];
normalise(n);
colorise(n,ldir);
glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
}
void flatFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,float r) {
vecteur n;
n[0] = p1[0]+p2[0]+p3[0]+p4[0];
n[1] = p1[1]+p2[1]+p3[1]+p4[1];
n[2] = p1[2]+p2[2]+p3[2]+p4[2];
normalise(n);
colorise(n,ldir);
glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r);
}
void flatSphere(float r,int n,int m) {
vecteur sup = { 0.0F,0.0F,1.0F };
vecteur inf = { 0.0F,0.0F,-1.0F };
vecteur **p =coordonnees(n,m);
int i;
glBegin(GL_TRIANGLES);
for ( i = 0 ; i < m ; i++ ) {
flatFacette3(p[0][i],p[0][(i+1)%m],inf,r); }
for ( i = 0 ; i < m ; i++ ) {
flatFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,r); }
glEnd();
glBegin(GL_QUADS);
for ( int j = 0 ; j < n-1 ; j++ ) {
for ( i = 0 ; i < m ; i++ ) {
flatFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r); } }
glEnd();
for ( i = 0 ; i < n ; i++ )
free(p[i]);
free(p);
}
void gouraudFacette3(vecteur p1,vecteur p2,vecteur p3,float r) {
colorise(p1,ldir);
glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
colorise(p2,ldir);
glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
colorise(p3,ldir);
glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
}
void gouraudFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,float r) {
colorise(p1,ldir);
glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
colorise(p2,ldir);
glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
colorise(p3,ldir);
glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
colorise(p4,ldir);
glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r);
}
void gouraudSphere(float r,int n,int m) {
vecteur sup = { 0.0F,0.0F,1.0F };
vecteur inf = { 0.0F,0.0F,-1.0F };
vecteur **p =coordonnees(n,m);
int i;
glBegin(GL_TRIANGLES);
for ( i = 0 ; i < m ; i++ ) {
gouraudFacette3(p[0][i],p[0][(i+1)%m],inf,r); }
for ( i = 0 ; i < m ; i++ ) {
gouraudFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,r); }
glEnd();
glBegin(GL_QUADS);
for ( int j = 0 ; j < n-1 ; j++ ) {
for ( i = 0 ; i < m ; i++ ) {
gouraudFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r); } }
glEnd();
for ( i = 0 ; i < n ; i++ )
free(p[i]);
free(p);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
manipulateurSouris();
manipulateurClavier();
glPushMatrix();
glTranslatef(1.4F,0.0F,0.0F);
glRotatef(50.0F,1.0F,1.0F,0.0F);
flatSphere(1.2F,disc1,disc2);
glPopMatrix();
glPushMatrix();
glTranslatef(-1.4F,0.0F,0.0F);
glRotatef(50.0F,1.0F,1.0F,0.0F);
gouraudSphere(1.2F,disc1,disc2);
glPopMatrix();
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void key(unsigned char key,int x,int y) {
if ( keyManipulateur(key,x,y) )
glutPostRedisplay();
else
switch ( key ) {
case 'a' : disc1++ ;
glutPostRedisplay() ;
break ;
case 'A' : disc1-- ;
if ( disc1 < 3 )
disc1 = 3;
glutPostRedisplay() ;
break ;
case 'b' : disc2++ ;
glutPostRedisplay() ;
break ;
case 'B' : disc2-- ;
if ( disc2 < 2 )
disc2 = 2;
glutPostRedisplay() ;
break ;
case 43 : niv++ ;
glutPostRedisplay() ;
break ;
case 45 : niv-- ;
if ( niv < 0 )
niv = 0;
glutPostRedisplay() ;
break ; }
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(400,200);
glutInitWindowPosition(50,50);
glutCreateWindow("Deux spheres");
myinit();
creationMenuBasique();
setParametresOrthoBasique(-1.5,1.5,-1.5,1.5,-500.0,500.0);
setManipulateurDistance(1.0F);
glutReshapeFunc(reshapeOrthoBasique);
glutKeyboardFunc(key);
glutSpecialFunc(specialBasique);
glutMotionFunc(motionBasique);
glutMouseFunc(sourisBasique);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}