13.2.2 Le fichier PAppTestSdlGl3.cpp

Écrivons le fichier PAppTestSdlGl3.cpp. Commençons par l'include de base comme d'habitude :

1
2
3
4
#include "PAppTestSdlGl3.h"

const float VITESSE_ROTATION_CUBE(0.3);
const float VITESSE_CAMERA(3.0);

Nous définissons aussi la vitesse de rotation de la caméra, et sa vitesse de translation.

Constructeur et destructeur :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
///Constructeur par défaut de PAppTestSdlGl3
PAppTestSdlGl3::PAppTestSdlGl3(const std::string& titreFenetre, int largeurFenetre, int hauteurFenetre)
	:PAppSdlOpenGl3(titreFenetre, largeurFenetre, hauteurFenetre)
{
	initialisationPAppTestSdlGl3();
}

///Destructeur de PAppTestSdlGl3
PAppTestSdlGl3::~PAppTestSdlGl3(){
	delete[] p_vertices;
	delete[] p_indices;
	delete[] p_couleurs;
	glDeleteProgram(p_programTest);
}

la fonction de mise à jour :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void PAppTestSdlGl3::update(float dt){
	if(keyEventMadeNoRepeat("close")){stop();}
	
	if(keyEventMadeRepeat("forward")) p_cameraGL.moveVisee(VITESSE_CAMERA*dt);
	else if(keyEventMadeRepeat("backward")) p_cameraGL.moveVisee(-VITESSE_CAMERA*dt);
	
	if(keyEventMadeRepeat("right")) p_cameraGL.moveGauche(-VITESSE_CAMERA*dt);
	else if(keyEventMadeRepeat("left")) p_cameraGL.moveGauche(VITESSE_CAMERA*dt);
	
	if(keyEventMadeRepeat("turnRight")) p_cameraGL.turnRight(VITESSE_ROTATION_CUBE*dt);
	else if(keyEventMadeRepeat("turnLeft")) p_cameraGL.turnLeft(VITESSE_ROTATION_CUBE*dt);
	
	if(keyEventMadeRepeat("turnUp")) p_cameraGL.turnUp(VITESSE_ROTATION_CUBE*dt);
	else if(keyEventMadeRepeat("turnDown")) p_cameraGL.turnDown(VITESSE_ROTATION_CUBE*dt);
}

la fonction d'affichage :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void PAppTestSdlGl3::draw3d(){
	glEnableVertexAttribArray(0);  //les coordonnées
	glEnableVertexAttribArray(1);  //les coordonnées de textures
	
	// Activation du shader et des tableaux Vertex Attrib (0 pour les vertices, 1 pour les couleurs, 2 pour les textures)
	glUseProgram(p_programTest);
	glBindTexture(GL_TEXTURE_2D, p_texture);
	//on envoie les matrices de projection et modelview
	sendMatProjectionToShader(p_idMatriceProjection);
	sendMatModelViewToShader(p_idMatriceModelView);
	
	drawTexturedCube3D();
	
	glBindTexture(GL_TEXTURE_2D, 0);
	glUseProgram(0);
	glDisableVertexAttribArray(1);  //on désactive les textures
	glDisableVertexAttribArray(0);  //on désactive les vertices
}

Vous remarquerez les fonctions sendMatProjectionToShader et sendMatModelViewToShader que j'ai rajouté.

La fonction privée qui affiche le cube :

1
2
3
4
5
6
7
8
void PAppTestSdlGl3::drawTexturedCube3D(){
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, p_vertices);
	
	/* ***** Première face ***** */
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, p_couleurs);
	//on a 24 éléments pour définir les 3 composantes des 8 sommets du cube
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, p_indices);
}

Initialisation de la classe et initialisation des touches :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
///Fonction d'initialisation de la classe PAppTestSdlGl3
void PAppTestSdlGl3::initialisationPAppTestSdlGl3(){
	initialisationTouches();
	initilisationCamera();
	initialisationProgrammeShader();
	initialisationVertices();
	initialisationColors();
	initialisationIndex();
}

///fonction qui initialise les touches
void PAppTestSdlGl3::initialisationTouches(){
	addKeyEventRepeat("turnRight", SDLK_RIGHT);
	addKeyEventRepeat("turnLeft", SDLK_LEFT);
	addKeyEventRepeat("turnUp", SDLK_UP);
	addKeyEventRepeat("turnDown", SDLK_DOWN);
	
	addKeyEventNoRepeat("close", SDLK_ESCAPE);
	
	addKeyEventRepeat("forward", SDLK_z);
	addKeyEventRepeat("backward", SDLK_s);
	addKeyEventRepeat("right", SDLK_d);
	addKeyEventRepeat("left", SDLK_q);
}

Initialisation de la caméra :

1
2
3
4
5
void PAppTestSdlGl3::initilisationCamera(){
	p_cameraGL.setPosition(-30.0, 0.0, 50.0);
	p_cameraGL.setPhi(M_PI/2.0 + M_PI/4.0);
	p_cameraGL.setTheta(M_PI/7.0);
}

Initialisation des shaders et du programme shader :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void PAppTestSdlGl3::initialisationProgrammeShader(){
	p_programTest = glCreateProgram();
	GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, GL_FRAGMENT_SHADER_VERTICES_CUBE_COLORED);
	GLuint vertexShader = loadShader(GL_VERTEX_SHADER, GL_VERTEX_SHADER_VERTICES_CUBE_COLORED);
	
	//on attache les shaders au programme
	glAttachShader(p_programTest, fragmentShader);
	glAttachShader(p_programTest, vertexShader);
	//on lie le programme
	int linkingResult = linkGlProgram(p_programTest);
	if(linkingResult == 0){
		glDeleteProgram(p_programTest);
		dontRun();
	}else{
		p_idMatriceModelView = glGetUniformLocation(p_programTest, "modelview");
		p_idMatriceProjection = glGetUniformLocation(p_programTest, "projection");
	}
}

Faites attention de bien être rigoureux sur les éventuelles erreurs d'initialisation.

Initialisation des vertices, des couleurs, et des faces :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
///fonction qui initialise les Vertices
void PAppTestSdlGl3::initialisationVertices(){
	unsigned int tailleTabVertices(8 * 3);
	float arreteCube = 5.0;
	// Vertices
	float vertices[] = {	-arreteCube,	-arreteCube,	-arreteCube,	arreteCube,
				-arreteCube,	-arreteCube,	arreteCube,	arreteCube,
				-arreteCube,	-arreteCube,	arreteCube,	-arreteCube,
				-arreteCube,	-arreteCube,	arreteCube,	arreteCube,
				-arreteCube,	arreteCube,	arreteCube,	arreteCube,
				arreteCube,	-arreteCube,	arreteCube,	arreteCube};
				
	p_vertices = new float[tailleTabVertices];
	for(unsigned int i(0); i < tailleTabVertices; i++) p_vertices[i] = vertices[i];
}

///fonction qui initialise les couleurs
void PAppTestSdlGl3::initialisationColors(){
	unsigned int tailleTabColor(8*3);
	p_couleurs = new float[tailleTabColor];
	
	float tabColor[] = {	1.0, 0.0, 0.0,   1.0, 1.0, 0.0,   1.0, 1.0, 1.0,  0.0, 1.0, 1.0,
				0.0, 0.0, 1.0,   0.0, 0.0, 0.0,   1.0, 0.0, 1.0,  0.0, 1.0, 0.0};
	
	for(unsigned int i(0); i < tailleTabColor; i++){
		p_couleurs[i] = tabColor[i];
	}
}

///fonction qui initialise les index des faces à dessiner
void PAppTestSdlGl3::initialisationIndex(){
	unsigned int tailleTabIndices(6 * 2 * 3);
	p_indices = new unsigned int[tailleTabIndices];
	// Indices
	unsigned int indices [] = {	0, 1, 2,   2, 3, 0,   // Face 1
					5, 1, 2,   2, 6, 5,   // Face 2
					0, 1, 5,   5, 4, 0,   // Face 3
					4, 5, 6,   6, 7, 4,   // Face 4
					0, 4, 7,   7, 3, 0,   // Face 5
					7, 6, 2,   2, 3, 7};  // Face 6
					
	for(unsigned int i(0); i < tailleTabIndices; i++) p_indices[i] = indices[i];
}

Un petit résumé de ce que l'on vient d'écrire :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "PAppTestSdlGl3.h"

const float VITESSE_ROTATION_CUBE(0.3);
const float VITESSE_CAMERA(3.0);

/////////////////////////////////////////////////////////
//                                                     //
//   Fonctions publiques de la classe PAppTestSdlGl3   //
//                                                     //
/////////////////////////////////////////////////////////


///Constructeur par défaut de PAppTestSdlGl3
PAppTestSdlGl3::PAppTestSdlGl3(const std::string& titreFenetre, int largeurFenetre, int hauteurFenetre)
	:PAppSdlOpenGl3(titreFenetre, largeurFenetre, hauteurFenetre)
{
	initialisationPAppTestSdlGl3();
}

///Destructeur de PAppTestSdlGl3
PAppTestSdlGl3::~PAppTestSdlGl3(){
	delete[] p_vertices;
	delete[] p_indices;
	delete[] p_couleurs;
	glDeleteProgram(p_programTest);
}

///fonction qui met à jour l'application
/**	@param dt : intervalle de temps entre deux calcul
*/
void PAppTestSdlGl3::update(float dt){
	if(keyEventMadeNoRepeat("close")){stop();}
	
	if(keyEventMadeRepeat("forward")) p_cameraGL.moveVisee(VITESSE_CAMERA*dt);
	else if(keyEventMadeRepeat("backward")) p_cameraGL.moveVisee(-VITESSE_CAMERA*dt);
	
	if(keyEventMadeRepeat("right")) p_cameraGL.moveGauche(-VITESSE_CAMERA*dt);
	else if(keyEventMadeRepeat("left")) p_cameraGL.moveGauche(VITESSE_CAMERA*dt);
	
	if(keyEventMadeRepeat("turnRight")) p_cameraGL.turnRight(VITESSE_ROTATION_CUBE*dt);
	else if(keyEventMadeRepeat("turnLeft")) p_cameraGL.turnLeft(VITESSE_ROTATION_CUBE*dt);
	
	if(keyEventMadeRepeat("turnUp")) p_cameraGL.turnUp(VITESSE_ROTATION_CUBE*dt);
	else if(keyEventMadeRepeat("turnDown")) p_cameraGL.turnDown(VITESSE_ROTATION_CUBE*dt);
}

///fonction qui affiche toute la scène 3D
void PAppTestSdlGl3::draw3d(){
	glEnableVertexAttribArray(0);  //les coordonnées
	glEnableVertexAttribArray(1);  //les coordonnées de textures
	
	// Activation du shader et des tableaux Vertex Attrib (0 pour les vertices, 1 pour les couleurs, 2 pour les textures)
	glUseProgram(p_programTest);
	glBindTexture(GL_TEXTURE_2D, p_texture);
	//on envoie les matrices de projection et modelview
	sendMatProjectionToShader(p_idMatriceProjection);
	sendMatModelViewToShader(p_idMatriceModelView);
	
	drawTexturedCube3D();
	
	glBindTexture(GL_TEXTURE_2D, 0);
	glUseProgram(0);
	glDisableVertexAttribArray(1);  //on désactive les textures
	glDisableVertexAttribArray(0);  //on désactive les vertices
}

///////////////////////////////////////////////////////
//                                                   //
//   Fonctions private de la classe PAppTestSdlGl3   //
//                                                   //
///////////////////////////////////////////////////////

///fonction qui affiche un cube texturé en 3D
void PAppTestSdlGl3::drawTexturedCube3D(){
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, p_vertices);
	
	/* ***** Première face ***** */
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, p_couleurs);
	//on a 24 éléments pour définir les 3 composantes des 8 sommets du cube
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, p_indices);
}

///Fonction d'initialisation de la classe PAppTestSdlGl3
void PAppTestSdlGl3::initialisationPAppTestSdlGl3(){
	initialisationTouches();
	initilisationCamera();
	initialisationProgrammeShader();
	initialisationVertices();
	initialisationColors();
	initialisationIndex();
}

///fonction qui initialise les touches
void PAppTestSdlGl3::initialisationTouches(){
	addKeyEventRepeat("turnRight", SDLK_RIGHT);
	addKeyEventRepeat("turnLeft", SDLK_LEFT);
	addKeyEventRepeat("turnUp", SDLK_UP);
	addKeyEventRepeat("turnDown", SDLK_DOWN);
	
	addKeyEventNoRepeat("close", SDLK_ESCAPE);
	
	addKeyEventRepeat("forward", SDLK_z);
	addKeyEventRepeat("backward", SDLK_s);
	addKeyEventRepeat("right", SDLK_d);
	addKeyEventRepeat("left", SDLK_q);
}

///fonction qui initialise la caméra
void PAppTestSdlGl3::initilisationCamera(){
	p_cameraGL.setPosition(-30.0, 0.0, 50.0);
	p_cameraGL.setPhi(M_PI/2.0 + M_PI/4.0);
	p_cameraGL.setTheta(M_PI/7.0);
}

///fonction qui initialise le programme qui utilisera les shaders
void PAppTestSdlGl3::initialisationProgrammeShader(){
	p_programTest = glCreateProgram();
	GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, GL_FRAGMENT_SHADER_VERTICES_CUBE_COLORED);
	GLuint vertexShader = loadShader(GL_VERTEX_SHADER, GL_VERTEX_SHADER_VERTICES_CUBE_COLORED);
	
	//on attache les shaders au programme
	glAttachShader(p_programTest, fragmentShader);
	glAttachShader(p_programTest, vertexShader);
	//on lie le programme
	int linkingResult = linkGlProgram(p_programTest);
	if(linkingResult == 0){
		glDeleteProgram(p_programTest);
		dontRun();
	}else{
		p_idMatriceModelView = glGetUniformLocation(p_programTest, "modelview");
		p_idMatriceProjection = glGetUniformLocation(p_programTest, "projection");
	}
}

///fonction qui initialise les Vertices
void PAppTestSdlGl3::initialisationVertices(){
	unsigned int tailleTabVertices(8 * 3);
	float arreteCube = 5.0;
	// Vertices
	float vertices[] = {	-arreteCube,	-arreteCube,	-arreteCube,	arreteCube,
				-arreteCube,	-arreteCube,	arreteCube,	arreteCube,
				-arreteCube,	-arreteCube,	arreteCube,	-arreteCube,
				-arreteCube,	-arreteCube,	arreteCube,	arreteCube,
				-arreteCube,	arreteCube,	arreteCube,	arreteCube,
				arreteCube,	-arreteCube,	arreteCube,	arreteCube};
				
	p_vertices = new float[tailleTabVertices];
	for(unsigned int i(0); i < tailleTabVertices; i++) p_vertices[i] = vertices[i];
}

///fonction qui initialise les couleurs
void PAppTestSdlGl3::initialisationColors(){
	unsigned int tailleTabColor(8*3);
	p_couleurs = new float[tailleTabColor];
	
	float tabColor[] = {	1.0, 0.0, 0.0,   1.0, 1.0, 0.0,   1.0, 1.0, 1.0,  0.0, 1.0, 1.0,
				0.0, 0.0, 1.0,   0.0, 0.0, 0.0,   1.0, 0.0, 1.0,  0.0, 1.0, 0.0};
	
	for(unsigned int i(0); i < tailleTabColor; i++){
		p_couleurs[i] = tabColor[i];
	}
}

///fonction qui initialise les index des faces à dessiner
void PAppTestSdlGl3::initialisationIndex(){
	unsigned int tailleTabIndices(6 * 2 * 3);
	p_indices = new unsigned int[tailleTabIndices];
	// Indices
	unsigned int indices [] = {	0, 1, 2,   2, 3, 0,   // Face 1
					5, 1, 2,   2, 6, 5,   // Face 2
					0, 1, 5,   5, 4, 0,   // Face 3
					4, 5, 6,   6, 7, 4,   // Face 4
					0, 4, 7,   7, 3, 0,   // Face 5
					7, 6, 2,   2, 3, 7};  // Face 6
					
	for(unsigned int i(0); i < tailleTabIndices; i++) p_indices[i] = indices[i];
}

Voilà qui est fait.