L'exécutable

GestionObjetsTextures01.gif (7490 octets)

GestionObjetsTextures02.gif (10036 octets) GestionObjetsTextures03.gif (9326 octets)

GestionObjetsTextures04.gif (14628 octets) GestionObjetsTextures05.gif (15678 octets)

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);
}

RETOUR