955 lines
35 KiB
C++
955 lines
35 KiB
C++
|
// Prénoms, noms et matricule des membres de l'équipe:
|
||
|
// - Prénom1 NOM1 (matricule1)
|
||
|
// - Prénom2 NOM2 (matricule2)
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <iostream>
|
||
|
#include "inf2705.h"
|
||
|
|
||
|
#define SOL 1
|
||
|
|
||
|
// variables pour l'utilisation des nuanceurs
|
||
|
GLuint prog; // votre programme de nuanceurs
|
||
|
GLint locVertex = -1;
|
||
|
GLint locNormal = -1;
|
||
|
GLint locTexCoord = -1;
|
||
|
GLint locmatrModel = -1;
|
||
|
GLint locmatrVisu = -1;
|
||
|
GLint locmatrProj = -1;
|
||
|
GLint locmatrNormale = -1;
|
||
|
GLint loclaTexture = -1;
|
||
|
GLuint indLightSource;
|
||
|
GLuint indFrontMaterial;
|
||
|
GLuint indLightModel;
|
||
|
GLuint indvarsUnif;
|
||
|
GLuint progBase; // le programme de nuanceurs de base
|
||
|
GLint locVertexBase = -1;
|
||
|
GLint locColorBase = -1;
|
||
|
GLint locmatrModelBase = -1;
|
||
|
GLint locmatrVisuBase = -1;
|
||
|
GLint locmatrProjBase = -1;
|
||
|
|
||
|
GLuint vao[2];
|
||
|
GLuint vbo[5];
|
||
|
GLuint ubo[4];
|
||
|
|
||
|
// matrices de du pipeline graphique
|
||
|
MatricePipeline matrModel;
|
||
|
MatricePipeline matrVisu;
|
||
|
MatricePipeline matrProj;
|
||
|
|
||
|
// les formes
|
||
|
FormeSphere *sphere = NULL, *sphereLumi = NULL;
|
||
|
FormeTheiere *theiere = NULL;
|
||
|
FormeTore *tore = NULL;
|
||
|
FormeCylindre *cylindre = NULL;
|
||
|
FormeCylindre *cone = NULL;
|
||
|
|
||
|
// variables pour définir le point de vue
|
||
|
double thetaCam = 0.0; // angle de rotation de la caméra (coord. sphériques)
|
||
|
double phiCam = 0.0; // angle de rotation de la caméra (coord. sphériques)
|
||
|
double distCam = 0.0; // distance (coord. sphériques)
|
||
|
|
||
|
// variables d'état
|
||
|
bool enPerspective = false; // indique si on est en mode Perspective (true) ou Ortho (false)
|
||
|
bool enmouvement = false; // le modèle est en mouvement/rotation automatique ou non
|
||
|
bool afficheAxes = true; // indique si on affiche les axes
|
||
|
GLenum modePolygone = GL_FILL; // comment afficher les polygones
|
||
|
|
||
|
////////////////////////////////////////
|
||
|
// déclaration des variables globales //
|
||
|
////////////////////////////////////////
|
||
|
|
||
|
// partie 1: illumination
|
||
|
int modele = 1; // le modèle à afficher
|
||
|
|
||
|
// partie 3: texture
|
||
|
GLuint textureDE = 0;
|
||
|
GLuint textureECHIQUIER = 0;
|
||
|
|
||
|
// définition des lumières
|
||
|
struct LightSourceParameters
|
||
|
{
|
||
|
glm::vec4 ambient;
|
||
|
glm::vec4 diffuse;
|
||
|
glm::vec4 specular;
|
||
|
glm::vec4 position;
|
||
|
glm::vec3 spotDirection;
|
||
|
float spotExposant;
|
||
|
float spotAngle; // ([0.0,90.0] ou 180.0)
|
||
|
float constantAttenuation;
|
||
|
float linearAttenuation;
|
||
|
float quadraticAttenuation;
|
||
|
} LightSource[1] = { { glm::vec4( 1.0, 1.0, 1.0, 1.0 ),
|
||
|
glm::vec4( 1.0, 1.0, 1.0, 1.0 ),
|
||
|
glm::vec4( 1.0, 1.0, 1.0, 1.0 ),
|
||
|
glm::vec4( 4, 1, 15, 1.0 ),
|
||
|
glm::vec3( -5.0, -2.0, -10.0 ),
|
||
|
1.0, // l'exposant du cône
|
||
|
15.0, // l'angle du cône du spot
|
||
|
1., 0., 0. } };
|
||
|
|
||
|
// définition du matériau
|
||
|
struct MaterialParameters
|
||
|
{
|
||
|
glm::vec4 emission;
|
||
|
glm::vec4 ambient;
|
||
|
glm::vec4 diffuse;
|
||
|
glm::vec4 specular;
|
||
|
float shininess;
|
||
|
} FrontMaterial = { glm::vec4( 0.0, 0.0, 0.0, 1.0 ),
|
||
|
glm::vec4( 0.1, 0.1, 0.1, 1.0 ),
|
||
|
glm::vec4( 1.0, 0.1, 1.0, 1.0 ),
|
||
|
glm::vec4( 1.0, 1.0, 1.0, 1.0 ),
|
||
|
100.0 };
|
||
|
|
||
|
struct LightModelParameters
|
||
|
{
|
||
|
glm::vec4 ambient; // couleur ambiante
|
||
|
int localViewer; // doit-on prendre en compte la position de l'observateur? (local ou à l'infini)
|
||
|
int twoSide; // éclairage sur les deux côtés ou un seul?
|
||
|
} LightModel = { glm::vec4(0,0,0,1), false, false };
|
||
|
|
||
|
struct
|
||
|
{
|
||
|
// partie 1: illumination
|
||
|
int typeIllumination; // 0:Lambert, 1:Gouraud, 2:Phong
|
||
|
int utiliseBlinn; // indique si on veut utiliser modèle spéculaire de Blinn ou Phong
|
||
|
int utiliseDirect; // indique si on utilise un spot style Direct3D ou OpenGL
|
||
|
int afficheNormales; // indique si on utilise les normales comme couleurs (utile pour le débogage)
|
||
|
// partie 3: texture
|
||
|
int texnumero; // numéro de la texture appliquée
|
||
|
int utiliseCouleur; // doit-on utiliser la couleur de base de l'objet en plus de celle de la texture?
|
||
|
int afficheTexelNoir; // un texel noir doit-il être affiché 0:noir, 1:mi-coloré, 2:transparent?
|
||
|
} varsUnif = { 2, false, false, false,
|
||
|
0, true, 0 };
|
||
|
// ( En glsl, les types 'bool' et 'int' sont de la même taille, ce qui n'est pas le cas en C++.
|
||
|
// Ci-dessus, on triche donc un peu en déclarant les 'bool' comme des 'int', mais ça facilite la
|
||
|
// copie directe vers le nuanceur où les variables seront bien de type 'bool'. )
|
||
|
|
||
|
|
||
|
void verifierAngles()
|
||
|
{
|
||
|
if ( thetaCam > 360.0 )
|
||
|
thetaCam -= 360.0;
|
||
|
else if ( thetaCam < 0.0 )
|
||
|
thetaCam += 360.0;
|
||
|
|
||
|
const GLdouble MINPHI = -90.0, MAXPHI = 90.0;
|
||
|
if ( phiCam > MAXPHI )
|
||
|
phiCam = MAXPHI;
|
||
|
else if ( phiCam < MINPHI )
|
||
|
phiCam = MINPHI;
|
||
|
}
|
||
|
|
||
|
void calculerPhysique( )
|
||
|
{
|
||
|
if ( enmouvement )
|
||
|
{
|
||
|
static int sensTheta = 1;
|
||
|
static int sensPhi = 1;
|
||
|
thetaCam += 0.3 * sensTheta;
|
||
|
phiCam += 0.5 * sensPhi;
|
||
|
//if ( thetaCam <= 0. || thetaCam >= 360.0 ) sensTheta = -sensTheta;
|
||
|
if ( phiCam < -90.0 || phiCam > 90.0 ) sensPhi = -sensPhi;
|
||
|
|
||
|
static int sensAngle = 1;
|
||
|
LightSource[0].spotAngle += sensAngle * 0.3;
|
||
|
if ( LightSource[0].spotAngle < 5.0 ) sensAngle = -sensAngle;
|
||
|
if ( LightSource[0].spotAngle > 60.0 ) sensAngle = -sensAngle;
|
||
|
|
||
|
#if 0
|
||
|
static int sensExposant = 1;
|
||
|
LightSource[0].spotExposant += sensExposant * 0.3;
|
||
|
if ( LightSource[0].spotExposant < 1.0 ) sensExposant = -sensExposant;
|
||
|
if ( LightSource[0].spotExposant > 10.0 ) sensExposant = -sensExposant;
|
||
|
#endif
|
||
|
|
||
|
// De temps à autre, alterner entre le modèle d'illumination: Lambert, Gouraud, Phong
|
||
|
static float type = 0;
|
||
|
type += 0.005;
|
||
|
varsUnif.typeIllumination = fmod(type,3);
|
||
|
}
|
||
|
|
||
|
verifierAngles();
|
||
|
}
|
||
|
|
||
|
void chargerTextures()
|
||
|
{
|
||
|
unsigned char *pixels;
|
||
|
GLsizei largeur, hauteur;
|
||
|
if ( ( pixels = ChargerImage( "textures/de.bmp", largeur, hauteur ) ) != NULL )
|
||
|
{
|
||
|
glGenTextures( 1, &textureDE );
|
||
|
glBindTexture( GL_TEXTURE_2D, textureDE );
|
||
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, largeur, hauteur, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
|
||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||
|
glBindTexture( GL_TEXTURE_2D, 0 );
|
||
|
delete[] pixels;
|
||
|
}
|
||
|
if ( ( pixels = ChargerImage( "textures/echiquier.bmp", largeur, hauteur ) ) != NULL )
|
||
|
{
|
||
|
glGenTextures( 1, &textureECHIQUIER );
|
||
|
glBindTexture( GL_TEXTURE_2D, textureECHIQUIER );
|
||
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, largeur, hauteur, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
|
||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||
|
glBindTexture( GL_TEXTURE_2D, 0 );
|
||
|
delete[] pixels;
|
||
|
}
|
||
|
|
||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||
|
}
|
||
|
|
||
|
void chargerNuanceurs()
|
||
|
{
|
||
|
// charger le nuanceur de base
|
||
|
{
|
||
|
// créer le programme
|
||
|
progBase = glCreateProgram();
|
||
|
|
||
|
// attacher le nuanceur de sommets
|
||
|
{
|
||
|
GLuint nuanceurObj = glCreateShader( GL_VERTEX_SHADER );
|
||
|
glShaderSource( nuanceurObj, 1, &ProgNuanceur::chainesSommetsMinimal, NULL );
|
||
|
glCompileShader( nuanceurObj );
|
||
|
glAttachShader( progBase, nuanceurObj );
|
||
|
ProgNuanceur::afficherLogCompile( nuanceurObj );
|
||
|
}
|
||
|
// attacher le nuanceur de fragments
|
||
|
{
|
||
|
GLuint nuanceurObj = glCreateShader( GL_FRAGMENT_SHADER );
|
||
|
glShaderSource( nuanceurObj, 1, &ProgNuanceur::chainesFragmentsMinimal, NULL );
|
||
|
glCompileShader( nuanceurObj );
|
||
|
glAttachShader( progBase, nuanceurObj );
|
||
|
ProgNuanceur::afficherLogCompile( nuanceurObj );
|
||
|
}
|
||
|
|
||
|
// faire l'édition des liens du programme
|
||
|
glLinkProgram( progBase );
|
||
|
|
||
|
ProgNuanceur::afficherLogLink( progBase );
|
||
|
// demander la "Location" des variables
|
||
|
if ( ( locVertexBase = glGetAttribLocation( progBase, "Vertex" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Vertex" << std::endl;
|
||
|
if ( ( locColorBase = glGetAttribLocation( progBase, "Color" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Color" << std::endl;
|
||
|
if ( ( locmatrModelBase = glGetUniformLocation( progBase, "matrModel" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrModel" << std::endl;
|
||
|
if ( ( locmatrVisuBase = glGetUniformLocation( progBase, "matrVisu" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrVisu" << std::endl;
|
||
|
if ( ( locmatrProjBase = glGetUniformLocation( progBase, "matrProj" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrProj" << std::endl;
|
||
|
}
|
||
|
|
||
|
// charger le nuanceur de ce TP
|
||
|
{
|
||
|
// créer le programme
|
||
|
prog = glCreateProgram();
|
||
|
|
||
|
// attacher le nuanceur de sommets
|
||
|
#if !defined(SOL)
|
||
|
const GLchar *chainesSommets = ProgNuanceur::lireNuanceur( "nuanceurSommets.glsl" );
|
||
|
#else
|
||
|
const GLchar *chainesSommets = ProgNuanceur::lireNuanceur( "nuanceurSommetsSolution.glsl" );
|
||
|
#endif
|
||
|
if ( chainesSommets != NULL )
|
||
|
{
|
||
|
GLuint nuanceurObj = glCreateShader( GL_VERTEX_SHADER );
|
||
|
glShaderSource( nuanceurObj, 1, &chainesSommets, NULL );
|
||
|
glCompileShader( nuanceurObj );
|
||
|
glAttachShader( prog, nuanceurObj );
|
||
|
ProgNuanceur::afficherLogCompile( nuanceurObj );
|
||
|
delete [] chainesSommets;
|
||
|
}
|
||
|
#if !defined(SOL)
|
||
|
const GLchar *chainesGeometrie = ProgNuanceur::lireNuanceur( "nuanceurGeometrie.glsl" );
|
||
|
#else
|
||
|
const GLchar *chainesGeometrie = ProgNuanceur::lireNuanceur( "nuanceurGeometrieSolution.glsl" );
|
||
|
#endif
|
||
|
if ( chainesGeometrie != NULL )
|
||
|
{
|
||
|
GLuint nuanceurObj = glCreateShader( GL_GEOMETRY_SHADER );
|
||
|
glShaderSource( nuanceurObj, 1, &chainesGeometrie, NULL );
|
||
|
glCompileShader( nuanceurObj );
|
||
|
glAttachShader( prog, nuanceurObj );
|
||
|
ProgNuanceur::afficherLogCompile( nuanceurObj );
|
||
|
delete [] chainesGeometrie;
|
||
|
}
|
||
|
// attacher le nuanceur de fragments
|
||
|
#if !defined(SOL)
|
||
|
const GLchar *chainesFragments = ProgNuanceur::lireNuanceur( "nuanceurFragments.glsl" );
|
||
|
#else
|
||
|
const GLchar *chainesFragments = ProgNuanceur::lireNuanceur( "nuanceurFragmentsSolution.glsl" );
|
||
|
#endif
|
||
|
if ( chainesFragments != NULL )
|
||
|
{
|
||
|
GLuint nuanceurObj = glCreateShader( GL_FRAGMENT_SHADER );
|
||
|
glShaderSource( nuanceurObj, 1, &chainesFragments, NULL );
|
||
|
glCompileShader( nuanceurObj );
|
||
|
glAttachShader( prog, nuanceurObj );
|
||
|
ProgNuanceur::afficherLogCompile( nuanceurObj );
|
||
|
delete [] chainesFragments;
|
||
|
}
|
||
|
|
||
|
// faire l'édition des liens du programme
|
||
|
glLinkProgram( prog );
|
||
|
|
||
|
ProgNuanceur::afficherLogLink( prog );
|
||
|
// demander la "Location" des variables
|
||
|
if ( ( locVertex = glGetAttribLocation( prog, "Vertex" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Vertex" << std::endl;
|
||
|
if ( ( locNormal = glGetAttribLocation( prog, "Normal" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de Normal (partie 1)" << std::endl;
|
||
|
if ( ( locTexCoord = glGetAttribLocation( prog, "TexCoord" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de TexCoord (partie 3)" << std::endl;
|
||
|
if ( ( locmatrModel = glGetUniformLocation( prog, "matrModel" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrModel" << std::endl;
|
||
|
if ( ( locmatrVisu = glGetUniformLocation( prog, "matrVisu" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrVisu" << std::endl;
|
||
|
if ( ( locmatrProj = glGetUniformLocation( prog, "matrProj" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrProj" << std::endl;
|
||
|
if ( ( locmatrNormale = glGetUniformLocation( prog, "matrNormale" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de matrNormale (partie 1)" << std::endl;
|
||
|
if ( ( loclaTexture = glGetUniformLocation( prog, "laTexture" ) ) == -1 ) std::cerr << "!!! pas trouvé la \"Location\" de laTexture (partie 3)" << std::endl;
|
||
|
if ( ( indLightSource = glGetUniformBlockIndex( prog, "LightSourceParameters" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de LightSource" << std::endl;
|
||
|
if ( ( indFrontMaterial = glGetUniformBlockIndex( prog, "MaterialParameters" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de FrontMaterial" << std::endl;
|
||
|
if ( ( indLightModel = glGetUniformBlockIndex( prog, "LightModelParameters" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de LightModel" << std::endl;
|
||
|
if ( ( indvarsUnif = glGetUniformBlockIndex( prog, "varsUnif" ) ) == GL_INVALID_INDEX ) std::cerr << "!!! pas trouvé l'\"index\" de varsUnif" << std::endl;
|
||
|
|
||
|
// charger les ubo
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[0] );
|
||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(LightSource), &LightSource, GL_DYNAMIC_COPY );
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
|
||
|
const GLuint bindingIndex = 0;
|
||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[0] );
|
||
|
glUniformBlockBinding( prog, indLightSource, bindingIndex );
|
||
|
}
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[1] );
|
||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(FrontMaterial), &FrontMaterial, GL_DYNAMIC_COPY );
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
|
||
|
const GLuint bindingIndex = 1;
|
||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[1] );
|
||
|
glUniformBlockBinding( prog, indFrontMaterial, bindingIndex );
|
||
|
}
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[2] );
|
||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(LightModel), &LightModel, GL_DYNAMIC_COPY );
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
|
||
|
const GLuint bindingIndex = 2;
|
||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[2] );
|
||
|
glUniformBlockBinding( prog, indLightModel, bindingIndex );
|
||
|
}
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[3] );
|
||
|
glBufferData( GL_UNIFORM_BUFFER, sizeof(varsUnif), &varsUnif, GL_DYNAMIC_COPY );
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
|
||
|
const GLuint bindingIndex = 3;
|
||
|
glBindBufferBase( GL_UNIFORM_BUFFER, bindingIndex, ubo[3] );
|
||
|
glUniformBlockBinding( prog, indvarsUnif, bindingIndex );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// initialisation d'openGL
|
||
|
void initialiser()
|
||
|
{
|
||
|
// donner l'orientation du modèle
|
||
|
thetaCam = 0.0;
|
||
|
phiCam = 0.0;
|
||
|
distCam = 30.0;
|
||
|
|
||
|
// couleur de l'arrière-plan
|
||
|
glClearColor( 0.4, 0.2, 0.0, 1.0 );
|
||
|
|
||
|
// activer les etats openGL
|
||
|
glEnable( GL_DEPTH_TEST );
|
||
|
|
||
|
// charger les textures
|
||
|
chargerTextures();
|
||
|
|
||
|
// allouer les UBO pour les variables uniformes
|
||
|
glGenBuffers( 4, ubo );
|
||
|
|
||
|
// charger les nuanceurs
|
||
|
chargerNuanceurs();
|
||
|
glUseProgram( prog );
|
||
|
|
||
|
// (partie 1) créer le cube
|
||
|
/* +Y */
|
||
|
/* 3+-----------+2 */
|
||
|
/* |\ |\ */
|
||
|
/* | \ | \ */
|
||
|
/* | \ | \ */
|
||
|
/* | 7+-----------+6 */
|
||
|
/* | | | | */
|
||
|
/* | | | | */
|
||
|
/* 0+---|-------+1 | */
|
||
|
/* \ | \ | +X */
|
||
|
/* \ | \ | */
|
||
|
/* \| \| */
|
||
|
/* 4+-----------+5 */
|
||
|
/* +Z */
|
||
|
|
||
|
GLfloat sommets[3*4*6] =
|
||
|
{
|
||
|
-1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, // P3,P2,P0,P1
|
||
|
1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, // P5,P4,P1,P0
|
||
|
1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // P6,P5,P2,P1
|
||
|
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, // P7,P6,P3,P2
|
||
|
-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, // P4,P7,P0,P3
|
||
|
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0 // P4,P5,P7,P6
|
||
|
};
|
||
|
GLfloat normales[3*4*6] =
|
||
|
{
|
||
|
0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0,
|
||
|
0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0,
|
||
|
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||
|
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
|
||
|
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
|
||
|
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
|
||
|
};
|
||
|
GLfloat texcoordsDe[2*4*6] =
|
||
|
{
|
||
|
1.000000,0.000000, 0.666666,0.000000, 1.000000,0.333333, 0.666666,0.333333,
|
||
|
0.000000,0.666666, 0.333333,0.666666, 0.000000,0.333333, 0.333333,0.333333,
|
||
|
0.666666,1.000000, 0.666666,0.666666, 0.333333,1.000000, 0.333333,0.666666,
|
||
|
1.000000,0.333333, 0.666666,0.333333, 1.000000,0.666666, 0.666666,0.666666,
|
||
|
0.333333,0.000000, 0.333333,0.333333, 0.666666,0.000000, 0.666666,0.333333,
|
||
|
0.666666,0.333333, 0.333333,0.333333, 0.666666,0.666666, 0.333333,0.666666
|
||
|
};
|
||
|
GLfloat texcoordsEchiquier[2*4*6] =
|
||
|
{
|
||
|
-1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, 2.0,
|
||
|
2.0, -1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0,
|
||
|
-1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, 2.0,
|
||
|
-1.0, 2.0, 2.0, 2.0, -1.0, -1.0, 2.0, -1.0,
|
||
|
2.0, 2.0, 2.0, -1.0, -1.0, 2.0, -1.0, -1.0,
|
||
|
-1.0, -1.0, -1.0, 2.0, 2.0, -1.0, 2.0, 2.0
|
||
|
};
|
||
|
|
||
|
// allouer les objets OpenGL
|
||
|
glGenVertexArrays( 2, vao );
|
||
|
glGenBuffers( 5, vbo );
|
||
|
// initialiser le VAO
|
||
|
glBindVertexArray( vao[0] );
|
||
|
|
||
|
// charger le VBO pour les sommets
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[0] );
|
||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(sommets), sommets, GL_STATIC_DRAW );
|
||
|
glVertexAttribPointer( locVertex, 3, GL_FLOAT, GL_FALSE, 0, 0 );
|
||
|
glEnableVertexAttribArray(locVertex);
|
||
|
// (partie 1) charger le VBO pour les normales
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[1] );
|
||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(normales), normales, GL_STATIC_DRAW );
|
||
|
glVertexAttribPointer( locNormal, 3, GL_FLOAT, GL_FALSE, 0, 0 );
|
||
|
glEnableVertexAttribArray(locNormal);
|
||
|
// (partie 3) charger le VBO pour les coordonnées de texture du dé
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[2] );
|
||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(texcoordsDe), texcoordsDe, GL_STATIC_DRAW );
|
||
|
glVertexAttribPointer( locTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0 );
|
||
|
glEnableVertexAttribArray(locTexCoord);
|
||
|
// (partie 3) charger le VBO pour les coordonnées de texture de l'échiquier
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[3] );
|
||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(texcoordsEchiquier), texcoordsEchiquier, GL_STATIC_DRAW );
|
||
|
glVertexAttribPointer( locTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0 );
|
||
|
glEnableVertexAttribArray(locTexCoord);
|
||
|
|
||
|
glBindVertexArray(0);
|
||
|
|
||
|
// initialiser le VAO pour une ligne (montrant la direction du spot)
|
||
|
glBindVertexArray( vao[1] );
|
||
|
GLfloat coords[] = { 0., 0., 0., 0., 0., 1. };
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[4] );
|
||
|
glBufferData( GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW );
|
||
|
glVertexAttribPointer( locVertexBase, 3, GL_FLOAT, GL_FALSE, 0, 0 );
|
||
|
glEnableVertexAttribArray(locVertexBase);
|
||
|
glBindVertexArray(0);
|
||
|
|
||
|
// créer quelques autres formes
|
||
|
sphere = new FormeSphere( 1.0, 32, 32 );
|
||
|
sphereLumi = new FormeSphere( 0.5, 10, 10 );
|
||
|
theiere = new FormeTheiere( );
|
||
|
tore = new FormeTore( 0.4, 0.8, 32, 32 );
|
||
|
cylindre = new FormeCylindre( 0.3, 0.3, 3.0, 32, 32 );
|
||
|
cone = new FormeCylindre( 0.0, 0.5, 3.0, 32, 32 );
|
||
|
}
|
||
|
|
||
|
void conclure()
|
||
|
{
|
||
|
glUseProgram( 0 );
|
||
|
glDeleteVertexArrays( 2, vao );
|
||
|
glDeleteBuffers( 4, vbo );
|
||
|
glDeleteBuffers( 4, ubo );
|
||
|
delete sphere;
|
||
|
delete sphereLumi;
|
||
|
delete theiere;
|
||
|
delete tore;
|
||
|
delete cylindre;
|
||
|
delete cone;
|
||
|
}
|
||
|
|
||
|
void afficherModele()
|
||
|
{
|
||
|
// partie 3: paramètres de texture
|
||
|
switch ( varsUnif.texnumero )
|
||
|
{
|
||
|
default:
|
||
|
//std::cout << "Sans texture" << std::endl;
|
||
|
glBindTexture( GL_TEXTURE_2D, 0 );
|
||
|
break;
|
||
|
case 1:
|
||
|
//std::cout << "Texture DE" << std::endl;
|
||
|
glBindTexture( GL_TEXTURE_2D, textureDE );
|
||
|
break;
|
||
|
case 2:
|
||
|
//std::cout << "Texture ECHIQUIER" << std::endl;
|
||
|
glBindTexture( GL_TEXTURE_2D, textureECHIQUIER );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Dessiner le modèle
|
||
|
matrModel.PushMatrix(); {
|
||
|
|
||
|
// appliquer les rotations
|
||
|
matrModel.Rotate( phiCam, -1.0, 0.0, 0.0 );
|
||
|
matrModel.Rotate( thetaCam, 0.0, -1.0, 0.0 );
|
||
|
|
||
|
// mise à l'échelle
|
||
|
matrModel.Scale( 5.0, 5.0, 5.0 );
|
||
|
|
||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
|
||
|
// (partie 1: ne pas oublier de calculer et donner une matrice pour les transformations des normales)
|
||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) );
|
||
|
|
||
|
switch ( modele )
|
||
|
{
|
||
|
default:
|
||
|
case 1:
|
||
|
// afficher le cube
|
||
|
glBindVertexArray( vao[0] );
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, varsUnif.texnumero == 1 ? vbo[2] : vbo[3] );
|
||
|
glVertexAttribPointer( locTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0 );
|
||
|
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
||
|
glDrawArrays( GL_TRIANGLE_STRIP, 4, 4 );
|
||
|
glDrawArrays( GL_TRIANGLE_STRIP, 8, 4 );
|
||
|
glDrawArrays( GL_TRIANGLE_STRIP, 12, 4 );
|
||
|
glDrawArrays( GL_TRIANGLE_STRIP, 16, 4 );
|
||
|
glDrawArrays( GL_TRIANGLE_STRIP, 20, 4 );
|
||
|
glBindVertexArray( 0 );
|
||
|
break;
|
||
|
case 2:
|
||
|
tore->afficher();
|
||
|
break;
|
||
|
case 3:
|
||
|
sphere->afficher();
|
||
|
break;
|
||
|
case 4:
|
||
|
matrModel.Rotate( -90.0, 1.0, 0.0, 0.0 );
|
||
|
matrModel.Translate( 0.0, 0.0, -0.5 );
|
||
|
matrModel.Scale( 0.5, 0.5, 0.5 );
|
||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
|
||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) );
|
||
|
theiere->afficher( );
|
||
|
break;
|
||
|
case 5:
|
||
|
matrModel.PushMatrix(); {
|
||
|
matrModel.Translate( 0.0, 0.0, -1.5 );
|
||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
|
||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) );
|
||
|
cylindre->afficher();
|
||
|
} matrModel.PopMatrix();
|
||
|
break;
|
||
|
case 6:
|
||
|
matrModel.PushMatrix(); {
|
||
|
matrModel.Translate( 0.0, 0.0, -1.5 );
|
||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
|
||
|
glUniformMatrix3fv( locmatrNormale, 1, GL_TRUE, glm::value_ptr( glm::inverse( glm::mat3( matrVisu.getMatr() * matrModel.getMatr() ) ) ) );
|
||
|
cone->afficher();
|
||
|
} matrModel.PopMatrix();
|
||
|
break;
|
||
|
}
|
||
|
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
|
||
|
}
|
||
|
|
||
|
void afficherLumiere()
|
||
|
{
|
||
|
// Dessiner la lumiere
|
||
|
|
||
|
// tracer une ligne vers la source lumineuse
|
||
|
const GLfloat fact = 5.;
|
||
|
GLfloat coords[] =
|
||
|
{
|
||
|
LightSource[0].position.x , LightSource[0].position.y , LightSource[0].position.z,
|
||
|
LightSource[0].position.x+LightSource[0].spotDirection.x/fact, LightSource[0].position.y+LightSource[0].spotDirection.y/fact, LightSource[0].position.z+LightSource[0].spotDirection.z/fact
|
||
|
};
|
||
|
glLineWidth( 3.0 );
|
||
|
glVertexAttrib3f( locColorBase, 1.0, 1.0, 0.5 ); // jaune
|
||
|
glBindVertexArray( vao[1] );
|
||
|
matrModel.PushMatrix(); {
|
||
|
glBindBuffer( GL_ARRAY_BUFFER, vbo[4] );
|
||
|
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(coords), coords );
|
||
|
glDrawArrays( GL_LINES, 0, 2 );
|
||
|
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
|
||
|
glBindVertexArray( 0 );
|
||
|
glLineWidth( 1.0 );
|
||
|
|
||
|
// tracer la source lumineuse
|
||
|
matrModel.PushMatrix(); {
|
||
|
matrModel.Translate( LightSource[0].position.x, LightSource[0].position.y, LightSource[0].position.z );
|
||
|
glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
|
||
|
sphereLumi->afficher();
|
||
|
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
|
||
|
}
|
||
|
|
||
|
// fonction d'affichage
|
||
|
void FenetreTP::afficherScene()
|
||
|
{
|
||
|
// effacer l'ecran et le tampon de profondeur
|
||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||
|
|
||
|
glUseProgram( progBase );
|
||
|
|
||
|
// définir le pipeline graphique
|
||
|
if ( enPerspective )
|
||
|
{
|
||
|
matrProj.Perspective( 35.0, (GLdouble)largeur_ / (GLdouble)hauteur_,
|
||
|
0.1, 60.0 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
const GLfloat d = 8.0;
|
||
|
if ( largeur_ <= hauteur_ )
|
||
|
{
|
||
|
matrProj.Ortho( -d, d,
|
||
|
-d*(GLdouble)hauteur_ / (GLdouble)largeur_,
|
||
|
d*(GLdouble)hauteur_ / (GLdouble)largeur_,
|
||
|
0.1, 60.0 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
matrProj.Ortho( -d*(GLdouble)largeur_ / (GLdouble)hauteur_,
|
||
|
d*(GLdouble)largeur_ / (GLdouble)hauteur_,
|
||
|
-d, d,
|
||
|
0.1, 60.0 );
|
||
|
}
|
||
|
}
|
||
|
glUniformMatrix4fv( locmatrProjBase, 1, GL_FALSE, matrProj );
|
||
|
|
||
|
matrVisu.LookAt( 0.0, 0.0, distCam, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
|
||
|
glUniformMatrix4fv( locmatrVisuBase, 1, GL_FALSE, matrVisu );
|
||
|
|
||
|
matrModel.LoadIdentity();
|
||
|
glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
|
||
|
|
||
|
// afficher les axes
|
||
|
if ( afficheAxes ) FenetreTP::afficherAxes( 8.0 );
|
||
|
|
||
|
// dessiner la scène
|
||
|
afficherLumiere();
|
||
|
|
||
|
glUseProgram( prog );
|
||
|
|
||
|
// mettre à jour les blocs de variables uniformes
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[0] );
|
||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY );
|
||
|
memcpy( p, &LightSource, sizeof(LightSource) );
|
||
|
glUnmapBuffer( GL_UNIFORM_BUFFER );
|
||
|
}
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[1] );
|
||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY );
|
||
|
memcpy( p, &FrontMaterial, sizeof(FrontMaterial) );
|
||
|
glUnmapBuffer( GL_UNIFORM_BUFFER );
|
||
|
}
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[2] );
|
||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY );
|
||
|
memcpy( p, &LightModel, sizeof(LightModel) );
|
||
|
glUnmapBuffer( GL_UNIFORM_BUFFER );
|
||
|
}
|
||
|
{
|
||
|
glBindBuffer( GL_UNIFORM_BUFFER, ubo[3] );
|
||
|
GLvoid *p = glMapBuffer( GL_UNIFORM_BUFFER, GL_WRITE_ONLY );
|
||
|
memcpy( p, &varsUnif, sizeof(varsUnif) );
|
||
|
glUnmapBuffer( GL_UNIFORM_BUFFER );
|
||
|
}
|
||
|
|
||
|
// mettre à jour les matrices et autres uniformes
|
||
|
glUniformMatrix4fv( locmatrProj, 1, GL_FALSE, matrProj );
|
||
|
glUniformMatrix4fv( locmatrVisu, 1, GL_FALSE, matrVisu );
|
||
|
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
|
||
|
//glActiveTexture( GL_TEXTURE0 ); // activer la texture '0' (valeur de défaut)
|
||
|
glUniform1i( loclaTexture, 0 ); // '0' => utilisation de GL_TEXTURE0
|
||
|
|
||
|
afficherModele();
|
||
|
}
|
||
|
|
||
|
// fonction de redimensionnement de la fenêtre graphique
|
||
|
void FenetreTP::redimensionner( GLsizei w, GLsizei h )
|
||
|
{
|
||
|
glViewport( 0, 0, w, h );
|
||
|
}
|
||
|
|
||
|
static void echoEtats( )
|
||
|
{
|
||
|
static std::string illuminationStr[] = { "0:Lambert", "1:Gouraud", "2:Phong" };
|
||
|
static std::string reflexionStr[] = { "0:Phong", "1:Blinn" };
|
||
|
static std::string spotStr[] = { "0:OpenGL", "1:Direct3D" };
|
||
|
std::cout << " modèle d'illumination= " << illuminationStr[varsUnif.typeIllumination]
|
||
|
<< ", refléxion spéculaire= " << reflexionStr[varsUnif.utiliseBlinn]
|
||
|
<< ", spot= " << spotStr[varsUnif.utiliseDirect]
|
||
|
<< std::endl;
|
||
|
}
|
||
|
|
||
|
// fonction de gestion du clavier
|
||
|
void FenetreTP::clavier( TP_touche touche )
|
||
|
{
|
||
|
// traitement des touches q et echap
|
||
|
switch ( touche )
|
||
|
{
|
||
|
case TP_ECHAP:
|
||
|
case TP_q: // Quitter l'application
|
||
|
quit();
|
||
|
break;
|
||
|
|
||
|
case TP_x: // Activer/désactiver l'affichage des axes
|
||
|
afficheAxes = !afficheAxes;
|
||
|
std::cout << "// Affichage des axes ? " << ( afficheAxes ? "OUI" : "NON" ) << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_v: // Recharger les fichiers des nuanceurs et recréer le programme
|
||
|
chargerNuanceurs();
|
||
|
std::cout << "// Recharger nuanceurs" << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_p: // Permuter la projection: perspective ou orthogonale
|
||
|
enPerspective = !enPerspective;
|
||
|
break;
|
||
|
|
||
|
case TP_i: // Alterner entre le modèle d'illumination: Lambert, Gouraud, Phong
|
||
|
if ( ++varsUnif.typeIllumination > 2 ) varsUnif.typeIllumination = 0;
|
||
|
echoEtats( );
|
||
|
break;
|
||
|
|
||
|
case TP_r: // Alterner entre le modèle de réflexion spéculaire: Phong, Blinn
|
||
|
varsUnif.utiliseBlinn = !varsUnif.utiliseBlinn;
|
||
|
echoEtats( );
|
||
|
break;
|
||
|
|
||
|
case TP_s: // Alterner entre le modèle de spot: OpenGL, Direct3D
|
||
|
varsUnif.utiliseDirect = !varsUnif.utiliseDirect;
|
||
|
echoEtats( );
|
||
|
break;
|
||
|
|
||
|
//case TP_l: // Alterner entre une caméra locale à la scène ou distante (localViewer)
|
||
|
// LightModel.localViewer = !LightModel.localViewer;
|
||
|
// std::cout << " localViewer=" << LightModel.localViewer << std::endl;
|
||
|
// break;
|
||
|
|
||
|
case TP_a: // Incrémenter l'angle du cône du spot
|
||
|
case TP_EGAL:
|
||
|
case TP_PLUS:
|
||
|
LightSource[0].spotAngle += 2.0;
|
||
|
if ( LightSource[0].spotAngle > 90.0 ) LightSource[0].spotAngle = 90.0;
|
||
|
std::cout << " spotAngle=" << LightSource[0].spotAngle << std::endl;
|
||
|
break;
|
||
|
case TP_z: // Décrémenter l'angle du cône du spot
|
||
|
case TP_MOINS:
|
||
|
case TP_SOULIGNE:
|
||
|
LightSource[0].spotAngle -= 2.0;
|
||
|
if ( LightSource[0].spotAngle < 0.0 ) LightSource[0].spotAngle = 0.0;
|
||
|
std::cout << " spotAngle=" << LightSource[0].spotAngle << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_d: // Incrémenter l'exposant du spot
|
||
|
case TP_BARREOBLIQUE:
|
||
|
LightSource[0].spotExposant += 0.3;
|
||
|
if ( LightSource[0].spotExposant > 89.0 ) LightSource[0].spotExposant = 89.0;
|
||
|
std::cout << " spotExposant=" << LightSource[0].spotExposant << std::endl;
|
||
|
break;
|
||
|
case TP_e: // Décrémenter l'exposant du spot
|
||
|
case TP_POINT:
|
||
|
LightSource[0].spotExposant -= 0.3;
|
||
|
if ( LightSource[0].spotExposant < 0.0 ) LightSource[0].spotExposant = 0.0;
|
||
|
std::cout << " spotExposant=" << LightSource[0].spotExposant << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_j: // Incrémenter le coefficient de brillance
|
||
|
case TP_CROCHETDROIT:
|
||
|
FrontMaterial.shininess *= 1.1;
|
||
|
std::cout << " FrontMaterial.shininess=" << FrontMaterial.shininess << std::endl;
|
||
|
break;
|
||
|
case TP_u: // Décrémenter le coefficient de brillance
|
||
|
case TP_CROCHETGAUCHE:
|
||
|
FrontMaterial.shininess /= 1.1; if ( FrontMaterial.shininess < 0.0 ) FrontMaterial.shininess = 0.0;
|
||
|
std::cout << " FrontMaterial.shininess=" << FrontMaterial.shininess << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_DROITE:
|
||
|
LightSource[0].position.x += 0.3;
|
||
|
break;
|
||
|
case TP_GAUCHE:
|
||
|
LightSource[0].position.x -= 0.3;
|
||
|
break;
|
||
|
case TP_BAS:
|
||
|
LightSource[0].position.y += 0.3;
|
||
|
break;
|
||
|
case TP_HAUT:
|
||
|
LightSource[0].position.y -= 0.3;
|
||
|
break;
|
||
|
|
||
|
case TP_FIN:
|
||
|
LightSource[0].spotDirection.x += 0.6;
|
||
|
break;
|
||
|
case TP_DEBUT:
|
||
|
LightSource[0].spotDirection.x -= 0.6;
|
||
|
break;
|
||
|
case TP_PAGEPREC:
|
||
|
LightSource[0].spotDirection.y += 0.6;
|
||
|
break;
|
||
|
case TP_PAGESUIV:
|
||
|
LightSource[0].spotDirection.y -= 0.6;
|
||
|
break;
|
||
|
|
||
|
case TP_m: // Choisir le modèle affiché: cube, tore, sphère, théière, cylindre, cône
|
||
|
if ( ++modele > 6 ) modele = 1;
|
||
|
std::cout << " modele=" << modele << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_0:
|
||
|
thetaCam = 0.0; phiCam = 0.0; distCam = 30.0; // placer les choses afin d'avoir une belle vue
|
||
|
break;
|
||
|
|
||
|
case TP_t: // Choisir la texture utilisée: aucune, dé, échiquier
|
||
|
varsUnif.texnumero++;
|
||
|
if ( varsUnif.texnumero > 2 ) varsUnif.texnumero = 0;
|
||
|
std::cout << " varsUnif.texnumero=" << varsUnif.texnumero << std::endl;
|
||
|
break;
|
||
|
|
||
|
// case TP_c: // Changer l'affichage de l'objet texturé avec couleurs ou sans couleur
|
||
|
// varsUnif.utiliseCouleur = !varsUnif.utiliseCouleur;
|
||
|
// std::cout << " utiliseCouleur=" << varsUnif.utiliseCouleur << std::endl;
|
||
|
// break;
|
||
|
|
||
|
case TP_o: // Changer l'affichage des texels noirs (noir, mi-coloré, transparent)
|
||
|
varsUnif.afficheTexelNoir++;
|
||
|
if ( varsUnif.afficheTexelNoir > 2 ) varsUnif.afficheTexelNoir = 0;
|
||
|
std::cout << " afficheTexelNoir=" << varsUnif.afficheTexelNoir << std::endl;
|
||
|
break;
|
||
|
|
||
|
case TP_g: // Permuter l'affichage en fil de fer ou plein
|
||
|
modePolygone = ( modePolygone == GL_FILL ) ? GL_LINE : GL_FILL;
|
||
|
glPolygonMode( GL_FRONT_AND_BACK, modePolygone );
|
||
|
break;
|
||
|
|
||
|
case TP_n: // Utiliser ou non les normales calculées comme couleur (pour le débogage)
|
||
|
varsUnif.afficheNormales = !varsUnif.afficheNormales;
|
||
|
break;
|
||
|
|
||
|
case TP_ESPACE: // Permuter la rotation automatique du modèle
|
||
|
enmouvement = !enmouvement;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
std::cout << " touche inconnue : " << (char) touche << std::endl;
|
||
|
imprimerTouches();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// fonction callback pour un clic de souris
|
||
|
int dernierX = 0; // la dernière valeur en X de position de la souris
|
||
|
int dernierY = 0; // la derniere valeur en Y de position de la souris
|
||
|
static enum { deplaceCam, deplaceSpotDirection, deplaceSpotPosition } deplace = deplaceCam;
|
||
|
static bool pressed = false;
|
||
|
void FenetreTP::sourisClic( int button, int state, int x, int y )
|
||
|
{
|
||
|
pressed = ( state == TP_PRESSE );
|
||
|
if ( pressed )
|
||
|
{
|
||
|
// on vient de presser la souris
|
||
|
dernierX = x;
|
||
|
dernierY = y;
|
||
|
switch ( button )
|
||
|
{
|
||
|
case TP_BOUTON_GAUCHE: // Tourner l'objet
|
||
|
deplace = deplaceCam;
|
||
|
break;
|
||
|
case TP_BOUTON_MILIEU: // Modifier l'orientation du spot
|
||
|
deplace = deplaceSpotDirection;
|
||
|
break;
|
||
|
case TP_BOUTON_DROIT: // Déplacer la lumière
|
||
|
deplace = deplaceSpotPosition;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// on vient de relâcher la souris
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void FenetreTP::sourisWheel( int x, int y ) // Changer la taille du spot
|
||
|
{
|
||
|
const int sens = +1;
|
||
|
LightSource[0].spotAngle += sens*y;
|
||
|
if ( LightSource[0].spotAngle > 90.0 ) LightSource[0].spotAngle = 90.0;
|
||
|
if ( LightSource[0].spotAngle < 0.0 ) LightSource[0].spotAngle = 0.0;
|
||
|
std::cout << " spotAngle=" << LightSource[0].spotAngle << std::endl;
|
||
|
}
|
||
|
|
||
|
// fonction de mouvement de la souris
|
||
|
void FenetreTP::sourisMouvement( int x, int y )
|
||
|
{
|
||
|
if ( pressed )
|
||
|
{
|
||
|
int dx = x - dernierX;
|
||
|
int dy = y - dernierY;
|
||
|
switch ( deplace )
|
||
|
{
|
||
|
case deplaceCam:
|
||
|
thetaCam -= dx / 3.0;
|
||
|
phiCam -= dy / 3.0;
|
||
|
break;
|
||
|
case deplaceSpotDirection:
|
||
|
LightSource[0].spotDirection.x += 0.06 * dx;
|
||
|
LightSource[0].spotDirection.y -= 0.06 * dy;
|
||
|
// std::cout << " LightSource[0].spotDirection=" << glm::to_string(LightSource[0].spotDirection) << std::endl;
|
||
|
break;
|
||
|
case deplaceSpotPosition:
|
||
|
LightSource[0].position.x += 0.03 * dx;
|
||
|
LightSource[0].position.y -= 0.03 * dy;
|
||
|
// std::cout << " LightSource[0].position=" << glm::to_string(LightSource[0].position) << std::endl;
|
||
|
//glm::vec3 ecranPos( x, hauteur_-y, ecranLumi[2] );
|
||
|
//LightSource[0].position = glm::vec4(glm::unProject( ecranPos, VM, P, cloture ), 1.0);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
dernierX = x;
|
||
|
dernierY = y;
|
||
|
|
||
|
verifierAngles();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main( int argc, char *argv[] )
|
||
|
{
|
||
|
// créer une fenêtre
|
||
|
FenetreTP fenetre( "INF2705 TP" );
|
||
|
|
||
|
// allouer des ressources et définir le contexte OpenGL
|
||
|
initialiser();
|
||
|
|
||
|
bool boucler = true;
|
||
|
while ( boucler )
|
||
|
{
|
||
|
// mettre à jour la physique
|
||
|
calculerPhysique( );
|
||
|
|
||
|
// affichage
|
||
|
fenetre.afficherScene();
|
||
|
fenetre.swap();
|
||
|
|
||
|
// récupérer les événements et appeler la fonction de rappel
|
||
|
boucler = fenetre.gererEvenement();
|
||
|
}
|
||
|
|
||
|
// détruire les ressources OpenGL allouées
|
||
|
conclure();
|
||
|
|
||
|
return 0;
|
||
|
}
|