Le source : GestionObjetsTextures.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2006 */
/* Dessin de divers objets avec texture */
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159
#endif
#include "ModuleCouleurs.h"
#include "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
static float anglex = 0.0F;
static float angley = 0.0F;
static float anglez = 0.0F;
static int anim = 1;
static int obj = 0;
static int n1 = 36;
static int n2 = 36;
GLubyte *textureDamier(void) {
GLubyte *tab =(GLubyte *) malloc(8*8*3*sizeof(GLubyte));
GLubyte *t = tab;
for ( int i = 0 ; i < 8 ; i++ )
for ( int j = 0 ; j < 8 ; j++ ) {
t[0] = t[1] = t[2] = ( (i+j)%2 ) ? 0x00 : 0xFF;
t += 3; }
return(tab);
}
void cube(float c){
c /= 2.0F;
glPushMatrix();
glBegin(GL_QUADS);
glNormal3f(0.0F,0.0F,-1.0F);
glTexCoord2f(0.0F,0.0F);
glVertex3f(c,c,-c);
glTexCoord2f(0.0F,1.0F);
glVertex3f(c,-c,-c);
glTexCoord2f(1.0F,1.0F);
glVertex3f(-c,-c,-c);
glTexCoord2f(1.0F,0.0F);
glVertex3f(-c,c,-c);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0F,0.0F,1.0F);
glTexCoord2f(0.0F,0.0F);
glVertex3f(c,c,c);
glTexCoord2f(0.0F,1.0F);
glVertex3f(-c,c,c);
glTexCoord2f(1.0F,1.0F);
glVertex3f(-c,-c,c);
glTexCoord2f(1.0F,0.0F);
glVertex3f(c,-c,c);
glEnd();
glBegin(GL_QUADS);
glNormal3f(-1.0F,0.0F,0.0F);
glTexCoord2f(0.0F,0.0F);
glVertex3f(-c,c,-c);
glTexCoord2f(0.0F,1.0F);
glVertex3f(-c,-c,-c);
glTexCoord2f(1.0F,1.0F);
glVertex3f(-c,-c,c);
glTexCoord2f(1.0F,0.0F);
glVertex3f(-c,c,c);
glEnd();
glBegin(GL_QUADS);
glNormal3f(1.0F,0.0F,0.0F);
glTexCoord2f(0.0F,0.0F);
glVertex3f(c,c,c);
glTexCoord2f(0.0F,1.0F);
glVertex3f(c,-c,c);
glTexCoord2f(1.0F,1.0F);
glVertex3f(c,-c,-c);
glTexCoord2f(1.0F,0.0F);
glVertex3f(c,c,-c);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0F,-1.0F,0.0F);
glTexCoord2f(0.0F,0.0F);
glVertex3f(-c,-c,c);
glTexCoord2f(0.0F,1.0F);
glVertex3f(-c,-c,-c);
glTexCoord2f(1.0F,1.0F);
glVertex3f(c,-c,-c);
glTexCoord2f(1.0F,0.0F);
glVertex3f(c,-c,c);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0F,1.0F,0.0F);
glTexCoord2f(0.0F,0.0F);
glVertex3f(c,c,c);
glTexCoord2f(0.0F,1.0F);
glVertex3f(c,c,-c);
glTexCoord2f(1.0F,1.0F);
glVertex3f(-c,c,-c);
glTexCoord2f(1.0F,0.0F);
glVertex3f(-c,c,c);
glEnd();
glPopMatrix();
}
void cylindre1(float r,float h,int n){
float *cs =(float *) calloc(n,sizeof(float));
float *sn =(float *) calloc(n,sizeof(float));
int i;
for( i = 0 ; i < n ; i++ ){
float a = (2*M_PI*i)/n;
sn[i] = sin(a);
cs[i] = cos(a); }
glPushMatrix();
glBegin(GL_QUAD_STRIP);
for( i = 0 ; i <= n ; i++ ){
float x = r*cs[i%n];
float z = -r*sn[i%n];
glNormal3f(cs[i%n],0.0F,-sn[i%n]);
float s =(float) i/n;
glTexCoord2f(s,0.0F);
glVertex3f(x,h/2,z);
glTexCoord2f(s,1.0F);
glVertex3f(x,-h/2,z); }
glEnd();
glBegin(GL_POLYGON);
glNormal3f(0.0F,1.0F,0.0F);
for( i = 0 ; i < n ; i++ ){
float si = -r*sn[i];
float ci = r*cs[i];
glTexCoord2f(cs[i]/r,sn[i]/r);
glVertex3f(ci,h/2,si); }
glEnd();
glBegin(GL_POLYGON);
glNormal3f(0.0F,-1.0F,0.0F);
for( i = 0 ; i < n ; i++ ){
float si = r*sn[i];
float ci = r*cs[i];
glTexCoord2f(cs[i]/r,sn[i]/r);
glVertex3f(ci,-h/2,si); }
glEnd();
free(cs);
free(sn);
glPopMatrix();
}
void cylindre2(float r,float h,int n){
float *cs =(float *) calloc(n,sizeof(float));
float *sn =(float *) calloc(n,sizeof(float));
int i;
for( i = 0 ; i < n ; i++ ){
float a = (2*M_PI*i)/n;
sn[i] = sin(a);
cs[i] = cos(a); }
glPushMatrix();
glBegin(GL_QUAD_STRIP);
for( i = 0 ; i <= n ; i++ ){
float x = r*cs[i%n];
float z = -r*sn[i%n];
glNormal3f(cs[i%n],0.0F,-sn[i%n]);
float s =(float) i/n;
glTexCoord2f(s,0.0F);
glVertex3f(x,h/2,z);
glTexCoord2f(s,1.0F);
glVertex3f(x,-h/2,z); }
glEnd();
glBegin(GL_QUAD_STRIP);
glNormal3f(0.0F,1.0F,0.0F);
for( i = 0 ; i <= n ; i++ ){
float x = r*cs[i%n];
float z = -r*sn[i%n];
float s =(float) i/n;
glTexCoord2f(s,1.0F);
glVertex3f(0.0,h/2,0.0);
glTexCoord2f(s,0.0F);
glVertex3f(x,h/2,z); }
glEnd();
glBegin(GL_QUAD_STRIP);
glNormal3f(0.0F,-1.0F,0.0F);
for( i = 0 ; i <= n ; i++ ){
float x = r*cs[i%n];
float z = -r*sn[i%n];
float s =(float) i/n;
glTexCoord2f(s,0.0F);
glVertex3f(0.0,-h/2,0.0);
glTexCoord2f(s,1.0F);
glVertex3f(x,-h/2,z); }
glEnd();
free(cs);
free(sn);
glPopMatrix();
}
struct coord3D {
float x;
float y;
float z; };
struct coord2D {
float s;
float t; };
void sphere1(double r,int lat,int lon) {
int npt = 2 + (lat-1)*lon;
int ntx = (lat+1)*(lon+1);
coord3D *pts =(coord3D *) calloc(npt,sizeof(coord3D));
coord3D *nms =(coord3D *) calloc(npt,sizeof(coord3D));
coord2D *tex =(coord2D *) calloc(ntx,sizeof(coord2D));
pts[0].x = 0.0f;
pts[0].y = 0.0f;
pts[0].z = r;
pts[1].x = 0.0f;
pts[1].y = 0.0f;
pts[1].z = -r;
nms[0].x = 0.0f;
nms[0].y = 0.0f;
nms[0].z = 1.0F;
nms[1].x = 0.0f;
nms[1].y = 0.0f;
nms[1].z = -1.0F;
int n = 0 ;
int i,j ;
for ( j = 0 ; j < lat+1 ; j++ ) {
for ( i = 0 ; i < lon+1 ; i++ ) {
tex[n].s =(float) i/lon;
tex[n].t =(float) j/lat;
n++; } }
n = 2 ;
for ( j = 0 ; j < (lat-1) ; j++ ) {
double aa = M_PI/2.0-(j+1)*M_PI/lat;
double c = cos(aa);
double s = sin(aa);
double rc = r*c;
double rs = r*s;
for ( i = 0 ; i < lon ; i++ ) {
double a = i*M_PI*2.0/lon;
double ca = cos(a);
double sa = sin(a);
pts[n].x = rc*ca;
pts[n].y = rc*sa;
pts[n].z = rs;
nms[n].x = c*ca;
nms[n].y = c*sa;
nms[n].z = s;
n++; } }
glBegin(GL_QUAD_STRIP);
for ( i = 0 ; i <= lon ; i++ ) {
glTexCoord2fv((float *) &tex[i]);
glNormal3fv((float *) &nms[0]);
glVertex3fv((float *) &pts[0]);
glTexCoord2fv((float *) &tex[i+lon+1]);
glNormal3fv((float *) &nms[2+i%lon]);
glVertex3fv((float *) &pts[2+i%lon]); }
glEnd();
for ( j = 0 ; j < lat-2 ; j++ ) {
glBegin(GL_QUAD_STRIP);
for ( i = 0 ; i <= lon ; i++ ) {
glTexCoord2fv((float *) &tex[i+(j+1)*(lon+1)]);
glNormal3fv((float *) &nms[2+i%lon+j*lon]);
glVertex3fv((float *) &pts[2+i%lon+j*lon]);
glTexCoord2fv((float *) &tex[i+(j+2)*(lon+1)]);
glNormal3fv((float *) &nms[2+i%lon+j*lon+lon]);
glVertex3fv((float *) &pts[2+i%lon+j*lon+lon]); }
glEnd(); }
glBegin(GL_QUAD_STRIP);
for ( i = 0 ; i <= lon ; i++ ) {
glTexCoord2fv((float *) &tex[i+lat*(lon+1)]);
glNormal3fv((float *) &nms[1]);
glVertex3fv((float *) &pts[1]);
glTexCoord2fv((float *) &tex[i+(lat-1)*(lon+1)]);
glNormal3fv((float *) &nms[2+(lat-2)*lon+i%lon]);
glVertex3fv((float *) &pts[2+(lat-2)*lon+i%lon]); }
glEnd();
free(tex);
free(nms);
free(pts);
}
void calculPositionNormaleCoordTexture(int lt,int lg,int lat,int lon,float r,struct coord3D *p,struct coord3D *n,struct coord2D *t) {
t->s =(float) lg/lon;
t->t =(float) lt/lat;
double aa = M_PI/2.0-t->t*M_PI;
double c = cos(aa);
double s = sin(aa);
double rc = r*c;
double rs = r*s;
double a = t->s*M_PI*2.0;
double ca = cos(a);
double sa = sin(a);
p->x = rc*ca;
p->y = rc*sa;
p->z = rs;
n->x = c*ca;
n->y = c*sa;
n->z = s;
}
void sphere2(double r,int lat,int lon) {
struct coord3D p;
struct coord3D n;
struct coord2D t;
for ( int j = 0 ; j < lat ; j++ ) {
glBegin(GL_QUAD_STRIP);
for ( int i = 0 ; i <= lon ; i++ ) {
calculPositionNormaleCoordTexture(j,i,lat,lon,r,&p,&n,&t);
glTexCoord2fv((float *) &t);
glNormal3fv((float *) &n);
glVertex3fv((float *) &p);
calculPositionNormaleCoordTexture(j+1,i,lat,lon,r,&p,&n,&t);
glTexCoord2fv((float *) &t);
glNormal3fv((float *) &n);
glVertex3fv((float *) &p); }
glEnd(); }
}
void tore(double ri,double re,int nbi,int nbe) {
for ( int i = 0 ; i < nbi ; i++ ) {
float alphai = 2*M_PI*i/nbi;
float alphaj = alphai+2*M_PI/nbi;
float cosalphai = cos(alphai);
float sinalphai = sin(alphai);
float cosalphaj = cos(alphaj);
float sinalphaj = sin(alphaj);
glBegin(GL_QUAD_STRIP);
for ( int j = 0 ; j <= nbe ; j++ ) {
float beta = 2*M_PI*j/nbe;
float cosbeta = cos(beta);
float sinbeta = sin(beta);
float x1 = (ri+re*cosbeta)*cosalphai;
float y1 = (ri+re*cosbeta)*sinalphai;
float z1 = re*sinbeta;
glTexCoord2f((double) i/nbi,(double) j/nbe);
glNormal3f(cosbeta*cosalphai,cosbeta*sinalphai,sinbeta);
glVertex3f(x1,y1,z1);
float x2 = (ri+re*cosbeta)*cosalphaj;
float y2 = (ri+re*cosbeta)*sinalphaj;
float z2 = re*sinbeta;
glTexCoord2f((double) (i+1)/nbi,(double) j/nbe);
glNormal3f(cosbeta*cosalphaj,cosbeta*sinalphaj,sinbeta);
glVertex3f(x2,y2,z2); }
glEnd(); }
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
manipulateurSouris();
manipulateurClavier();
glRotatef(anglex,1.0F,0.0F,0.0F);
glRotatef(angley,0.0F,1.0F,0.0F);
glRotatef(anglez,0.0F,0.0F,1.0F);
switch (obj) {
case 0 : cube(3.8F) ;
break;
case 1 : cylindre1(1.9F,3.8F,n1);
break;
case 2 : cylindre2(1.9F,3.8F,n1);
break;
case 3 : sphere1(3.0F,n1,n2);
break;
case 4 : sphere2(3.0F,n1,n2);
break;
case 5 : tore(2.3F,1.1F,n1,n2);
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void myinit (void) {
glClearColor(0.5F,0.5F,0.5F,0.0F);
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
float dir0[4] = { 1.0F,1.0F,1.0F,0.0F };
glLightfv(GL_LIGHT0,GL_POSITION,dir0) ;
glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurVert()) ;
float dir1[4] = { -1.0F,1.0F,1.0F,0.0F };
glLightfv(GL_LIGHT1,GL_POSITION,dir1) ;
glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurBleu()) ;
float dir2[4] = { 0.0F,-1.0F,1.0F,0.0F };
glLightfv(GL_LIGHT2,GL_POSITION,dir2) ;
glLightfv(GL_LIGHT2,GL_DIFFUSE,couleurRouge()) ;
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,3,8,8,0,GL_RGB,GL_UNSIGNED_BYTE,textureDamier());
glEnable(GL_TEXTURE_2D);
}
void idle(void) {
anglex += 0.31F;
angley += 0.37F;
anglez += 0.41F;
glutPostRedisplay();
}
void key(unsigned char key,int x,int y) {
static int aff = 1;
if ( keyManipulateur(key,x,y) )
glutPostRedisplay();
else
switch ( key ) {
case 43 : n1++;
glutPostRedisplay();
break;
case 45 : n1--;
if ( n1 < 3 )
n1 = 3;
glutPostRedisplay();
break;
case 'N' : n2++;
glutPostRedisplay();
break;
case 'n' : n2--;
if ( n2 < 3 )
n2 = 3;
glutPostRedisplay();
break;
case ' ' : anim = !anim;
glutIdleFunc((anim) ? idle : NULL);
break;
case 0x0D : obj = (obj+1)%6;
glutPostRedisplay();
break;
case 'a' :
case 'A' : aff = !aff;
glPolygonMode(GL_FRONT_AND_BACK,(aff) ? GL_FILL : GL_LINE);
glutPostRedisplay(); }
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(250,250);
glutInitWindowPosition(50,50);
glutCreateWindow("Objets avec texture");
myinit();
creationMenuBasique();
setParametresOrthoBasique(-3.5F,3.5F,-3.5F,3.5F,-50.0,50.0);
setManipulateurDistance(1.0F);
glutReshapeFunc(reshapeOrthoBasique);
glutKeyboardFunc(key);
glutSpecialFunc(specialBasique);
glutMotionFunc(motionBasique);
glutMouseFunc(sourisBasique);
glutIdleFunc(idle);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}