1 // sous mac
2 // g++ -I/usr/local/include/ -lglfw -lGLEW -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs main6.cpp -framework OpenGL -omain6
3 // ./main6
4
5 // sous linux
6 // g++ -I/usr/local/include/ -I/public/ig/glm/ -c main6.cpp -omain6.o
7 // g++ -I/usr/local main6.o -lglfw -lGLEW -lGL -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -omain6
8 // ./main6
9
10 // Inclut les en-têtes standards
11 #include <stdio.h>
12 #include <string>
13 #include <vector>
14 #include <iostream>
15 #include <fstream>
16 #include <algorithm>
17 using namespace std;
18
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <GL/glew.h>
23 #include <GLFW/glfw3.h>
24
25 #ifdef __APPLE__
26 #include <OpenGL/gl.h>
27 #else
28 #include <GL/gl.h>
29 #endif
30
31 #include <opencv2/core/core.hpp>
32 #include <opencv2/highgui/highgui.hpp>
33 using namespace cv;
34
35 #define GLM_FORCE_RADIANS
36 #include <glm/glm.hpp>
37 #include <glm/gtc/matrix_transform.hpp>
38 #include <glm/gtc/type_ptr.hpp>
39
40 using namespace glm;
41
42
43 // Le nombre de donnees
44 const int N = 12;
45
46 // Avec 3 parties dans le VBO ca commence a etre complique. On va stocker la taille
47 // des 3 parties dans des variables pour plus facilement calculer les decallages
48 long vertexSize, colorSize, texCoordSize;
49
50 // Les donnees sous forme de pointeur. Il faudra donc faire un malloc
51 // pour allouer de l'espace avant de mettre des donnees dedans
52 GLfloat *g_vertex_buffer_data = NULL;
53 GLfloat *g_vertex_color_data = NULL;
54 GLfloat *g_vertex_texcoord_data = NULL;
55
56 // l'angle de rotation de la camera autour du modele
57 float angleRot = 0.0f;
58
59 // LA fenetre
60 GLFWwindow* window;
61
62 // La texture d'alphabet
63 GLuint texId;
64
65 // la vitesse initiale
66 float speed = 0.0;
67
68 // La taille de notre fenetre
69 int winWidth = 800;
70 int winHeight = 400;
71
72 // La taille de notre texture
73 int texWidth = -1;
74 int texHeight = -1;
75
76 // This will identify our vertex buffer (VBO)
77 GLuint vertexbuffer;
78
79 // Identifiant de notre VAO
80 GLuint vertexArrayID;
81
82 // identifiant de notre programme de shaders
83 GLuint programID;
84
85
86 // stocke les variables uniformes qui seront communes a tous les vertex dessines
87 GLint uniform_proj, uniform_view, uniform_model, uniform_texture;
88
89
90 // Charge une texture et retourne l'identifiant openGL
91 GLuint LoadTexture(string fileName){
92 GLuint tId = -1;
93 // On utilise OpenCV pour charger l'image
94 Mat image = imread(fileName, CV_LOAD_IMAGE_UNCHANGED);
95
96 // On va utiliser des TEXTURE_RECTANGLE au lieu de classiques TEXTURE_2D
97 // car avec ca les coordonnees de texture s'exprime en pixels et non en coordoonnes homogenes (0.0...1.0)
98 // En effet la texture est composee de lettres et symbole que nous voudrons extraire... or la position et
99 // taille de ces symboles dans la texture sont connuees en "pixels". Ca sera donc plus facile
100
101 //comme d'hab on fait generer un numero unique(ID) par OpenGL
102 glGenTextures(1, &tId);
103
104 texWidth = image.cols;
105 texHeight = image.rows;
106
107 glBindTexture(GL_TEXTURE_RECTANGLE, tId);
108 // on envoie les pixels a la carte graphique
109 glTexImage2D(GL_TEXTURE_RECTANGLE,
110 0, // mipmap level => Attention pas de mipmap dans les textures rectangle
111 GL_RGBA, // internal color format
112 image.cols,
113 image.rows,
114 0, // border width in pixels
115 GL_BGRA, // input file format. Arg le png code les canaux dans l'autre sens
116 GL_UNSIGNED_BYTE, // image data type
117 image.ptr());
118 // On peut donner des indication a opengl sur comment la texture sera utilisee
119 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
120 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
121 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
122 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
123
124 // INTERDIT sur les textures rectangle!
125 //glGenerateMipmap(GL_TEXTURE_2D);
126 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
127
128 return tId;
129 }
130
131
132 // Charge un programme de shaders, le compile et recupere dedans des pointeurs vers
133 // les variables homogenes que nous voudront mettre a jour plus tard, a chaque dessin
134 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
135
136 // Create the shaders
137 GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
138 GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
139
140 // Read the Vertex Shader code from the file
141 string VertexShaderCode;
142 ifstream VertexShaderStream(vertex_file_path, ios::in);
143 if(VertexShaderStream.is_open()){
144 string Line = "";
145 while(getline(VertexShaderStream, Line))
146 VertexShaderCode += "\n" + Line;
147 VertexShaderStream.close();
148 }else{
149 printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
150 getchar();
151 return 0;
152 }
153
154 // Read the Fragment Shader code from the file
155 string FragmentShaderCode;
156 ifstream FragmentShaderStream(fragment_file_path, ios::in);
157 if(FragmentShaderStream.is_open()){
158 string Line = "";
159 while(getline(FragmentShaderStream, Line))
160 FragmentShaderCode += "\n" + Line;
161 FragmentShaderStream.close();
162 }
163
164 GLint Result = GL_FALSE;
165 int InfoLogLength;
166
167
168 // Compile Vertex Shader
169 printf("Compiling shader : %s\n", vertex_file_path);
170 char const * VertexSourcePointer = VertexShaderCode.c_str();
171 glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
172 glCompileShader(VertexShaderID);
173
174 // Check Vertex Shader
175 glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
176 glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
177 if ( InfoLogLength > 0 ){
178 vector<char> VertexShaderErrorMessage(InfoLogLength+1);
179 glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
180 printf("%s\n", &VertexShaderErrorMessage[0]);
181 }
182
183
184
185 // Compile Fragment Shader
186 printf("Compiling shader : %s\n", fragment_file_path);
187 char const * FragmentSourcePointer = FragmentShaderCode.c_str();
188 glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
189 glCompileShader(FragmentShaderID);
190
191 // Check Fragment Shader
192 glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
193 glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
194 if ( InfoLogLength > 0 ){
195 vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
196 glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
197 printf("%s\n", &FragmentShaderErrorMessage[0]);
198 }
199
200
201 // Link the program
202 printf("Linking program\n");
203 GLuint progID = glCreateProgram();
204 glAttachShader(progID, VertexShaderID);
205 glAttachShader(progID, FragmentShaderID);
206 glLinkProgram(progID);
207
208
209 // Check the program
210 glGetProgramiv(progID, GL_LINK_STATUS, &Result);
211 glGetProgramiv(progID, GL_INFO_LOG_LENGTH, &InfoLogLength);
212 if ( InfoLogLength > 0 ){
213 vector<char> ProgramErrorMessage(InfoLogLength+1);
214 glGetProgramInfoLog(progID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
215 printf("%s\n", &ProgramErrorMessage[0]);
216 }
217
218
219 glDetachShader(progID, VertexShaderID);
220 glDetachShader(progID, FragmentShaderID);
221
222 glDeleteShader(VertexShaderID);
223 glDeleteShader(FragmentShaderID);
224
225 return progID;
226 }
227
228
229 void generateData(float texw, float texh){
230 vertexSize = 9*5*N*sizeof(GLfloat);
231 colorSize = 9*5*N*sizeof(GLfloat);
232 texCoordSize = 3*2*5*N*sizeof(GLfloat);
233
234 if (g_vertex_buffer_data != NULL)
235 free(g_vertex_buffer_data);
236
237 if (g_vertex_color_data!= NULL)
238 free(g_vertex_color_data);
239
240 if (g_vertex_texcoord_data!= NULL)
241 free(g_vertex_texcoord_data);
242
243 g_vertex_buffer_data = (GLfloat*)malloc(vertexSize);
244 g_vertex_color_data = (GLfloat*)malloc(colorSize);
245 g_vertex_texcoord_data = (GLfloat*)malloc(texCoordSize);
246
247 for (int i=0; i<N; i++){
248 float r = (500+rand()%500)/1000.0;
249 g_vertex_buffer_data[ 0+i*9*5] = 0.0;
250 g_vertex_buffer_data[ 1+i*9*5] = 0.0;
251 g_vertex_buffer_data[ 2+i*9*5] = 0.0;
252
253 g_vertex_buffer_data[ 3+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
254 g_vertex_buffer_data[ 4+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
255 g_vertex_buffer_data[ 5+i*9*5] = r/5.0;
256
257 g_vertex_buffer_data[ 6+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
258 g_vertex_buffer_data[ 7+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
259 g_vertex_buffer_data[ 8+i*9*5] = r/5.0;
260
261
262 g_vertex_buffer_data[ 9+i*9*5] = 0.0;
263 g_vertex_buffer_data[10+i*9*5] = 0.0;
264 g_vertex_buffer_data[11+i*9*5] = 0.0;
265
266 g_vertex_buffer_data[12+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
267 g_vertex_buffer_data[13+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
268 g_vertex_buffer_data[14+i*9*5] = r/5.0;
269
270 g_vertex_buffer_data[15+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
271 g_vertex_buffer_data[16+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
272 g_vertex_buffer_data[17+i*9*5] = 0.0;
273
274
275 g_vertex_buffer_data[18+i*9*5] = 0.0;
276 g_vertex_buffer_data[19+i*9*5] = 0.0;
277 g_vertex_buffer_data[20+i*9*5] = 0.0;
278
279 g_vertex_buffer_data[21+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
280 g_vertex_buffer_data[22+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
281 g_vertex_buffer_data[23+i*9*5] = r/5.0;
282
283 g_vertex_buffer_data[24+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
284 g_vertex_buffer_data[25+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
285 g_vertex_buffer_data[26+i*9*5] = 0.0;
286
287
288 g_vertex_buffer_data[27+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
289 g_vertex_buffer_data[28+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
290 g_vertex_buffer_data[29+i*9*5] = r/5.0;
291
292 g_vertex_buffer_data[30+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
293 g_vertex_buffer_data[31+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
294 g_vertex_buffer_data[32+i*9*5] = r/5.0;
295
296 g_vertex_buffer_data[33+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
297 g_vertex_buffer_data[34+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
298 g_vertex_buffer_data[35+i*9*5] = 0.0;
299
300 g_vertex_buffer_data[36+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
301 g_vertex_buffer_data[37+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
302 g_vertex_buffer_data[38+i*9*5] = r/5.0;
303
304 g_vertex_buffer_data[39+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
305 g_vertex_buffer_data[40+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
306 g_vertex_buffer_data[41+i*9*5] = 0.0;
307
308 g_vertex_buffer_data[42+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
309 g_vertex_buffer_data[43+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
310 g_vertex_buffer_data[44+i*9*5] = 0.0;
311
312
313 g_vertex_color_data[ 0+i*9*5] = 0.0;
314 g_vertex_color_data[ 1+i*9*5] = 0.0;
315 g_vertex_color_data[ 2+i*9*5] = 1.0;
316
317 g_vertex_color_data[ 3+i*9*5] = 0.5;
318 g_vertex_color_data[ 4+i*9*5] = 0.0;
319 g_vertex_color_data[ 5+i*9*5] = 0.0;
320
321 g_vertex_color_data[ 6+i*9*5] = 1.0;
322 g_vertex_color_data[ 7+i*9*5] = 0.0;
323 g_vertex_color_data[ 8+i*9*5] = 0.0;
324
325 g_vertex_color_data[ 9+i*9*5] = 0.5;
326 g_vertex_color_data[10+i*9*5] = 0.0;
327 g_vertex_color_data[11+i*9*5] = 1.0;
328
329 g_vertex_color_data[12+i*9*5] = 0.5;
330 g_vertex_color_data[13+i*9*5] = 0.0;
331 g_vertex_color_data[14+i*9*5] = 0.0;
332
333 g_vertex_color_data[15+i*9*5] = 0.5;
334 g_vertex_color_data[16+i*9*5] = 0.0;
335 g_vertex_color_data[17+i*9*5] = 0.0;
336
337 g_vertex_color_data[18+i*9*5] = 1.0;
338 g_vertex_color_data[19+i*9*5] = 0.0;
339 g_vertex_color_data[20+i*9*5] = 1.0;
340
341 g_vertex_color_data[21+i*9*5] = 1.0;
342 g_vertex_color_data[22+i*9*5] = 0.0;
343 g_vertex_color_data[23+i*9*5] = 0.0;
344
345 g_vertex_color_data[24+i*9*5] = 1.0;
346 g_vertex_color_data[25+i*9*5] = 0.0;
347 g_vertex_color_data[26+i*9*5] = 0.0;
348
349 g_vertex_color_data[27+i*9*5] = 1.0;
350 g_vertex_color_data[28+i*9*5] = 0.0;
351 g_vertex_color_data[29+i*9*5] = 0.0;
352
353 g_vertex_color_data[30+i*9*5] = 0.5;
354 g_vertex_color_data[31+i*9*5] = 0.0;
355 g_vertex_color_data[32+i*9*5] = 0.0;
356
357 g_vertex_color_data[33+i*9*5] = 1.0;
358 g_vertex_color_data[34+i*9*5] = 0.0;
359 g_vertex_color_data[35+i*9*5] = 0.0;
360
361 g_vertex_color_data[36+i*9*5] = 0.5;
362 g_vertex_color_data[37+i*9*5] = 0.0;
363 g_vertex_color_data[38+i*9*5] = 0.0;
364
365 g_vertex_color_data[39+i*9*5] = 0.5;
366 g_vertex_color_data[40+i*9*5] = 0.0;
367 g_vertex_color_data[41+i*9*5] = 0.0;
368
369 g_vertex_color_data[42+i*9*5] = 1.0;
370 g_vertex_color_data[43+i*9*5] = 0.0;
371 g_vertex_color_data[44+i*9*5] = 0.0;
372
373
374 // on doit maintenant generer des coordonnees de texture pour chaque vertex.
375 // Meme ceux qu'on ne veux pas texturer ! La prochaine fois on fera 2 programmes "shader"
376 // avec 2 VBO, 2 VAO, etc.
377 g_vertex_texcoord_data[ 0+i*6*5] = 0.0;
378 g_vertex_texcoord_data[ 1+i*6*5] = 0.0;
379
380 g_vertex_texcoord_data[ 2+i*6*5] = 0.0;
381 g_vertex_texcoord_data[ 3+i*6*5] = 0.0;
382
383 g_vertex_texcoord_data[ 4+i*6*5] = 0.0;
384 g_vertex_texcoord_data[ 5+i*6*5] = 0.0;
385
386 g_vertex_texcoord_data[ 6+i*6*5] = 0.0;
387 g_vertex_texcoord_data[ 7+i*6*5] = 0.0;
388
389 g_vertex_texcoord_data[ 8+i*6*5] = 0.0;
390 g_vertex_texcoord_data[ 9+i*6*5] = 0.0;
391
392 g_vertex_texcoord_data[10+i*6*5] = 0.0;
393 g_vertex_texcoord_data[11+i*6*5] = 0.0;
394
395 g_vertex_texcoord_data[12+i*6*5] = 0.0;
396 g_vertex_texcoord_data[13+i*6*5] = 0.0;
397
398 g_vertex_texcoord_data[14+i*6*5] = 0.0;
399 g_vertex_texcoord_data[15+i*6*5] = 0.0;
400
401 g_vertex_texcoord_data[16+i*6*5] = 0.0;
402 g_vertex_texcoord_data[17+i*6*5] = 0.0;
403
404 g_vertex_texcoord_data[18+i*6*5] = 0.0;
405 g_vertex_texcoord_data[19+i*6*5] = 0.0;
406
407 g_vertex_texcoord_data[20+i*6*5] = texw;
408 g_vertex_texcoord_data[21+i*6*5] = 0.0;
409
410 g_vertex_texcoord_data[22+i*6*5] = 0.0;
411 g_vertex_texcoord_data[23+i*6*5] = texh;
412
413 g_vertex_texcoord_data[24+i*6*5] = texw;
414 g_vertex_texcoord_data[25+i*6*5] = 0.0;
415
416 g_vertex_texcoord_data[26+i*6*5] = texw;
417 g_vertex_texcoord_data[27+i*6*5] = texh;
418
419 g_vertex_texcoord_data[28+i*6*5] = 0.0;
420 g_vertex_texcoord_data[29+i*6*5] = texh;
421 }
422 }
423
424
425 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
426 {
427 // on teste si la touche E est pressee et si c'est le cas on re-genere des donnees
428 if (key== GLFW_KEY_E && action == GLFW_PRESS){
429
430 generateData(texWidth, texHeight);
431 // ici on n'envoie que les sommets car on souhaite garder les memes couleurs ... et le nombre
432 // n'a pas change !
433 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
434 glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize, g_vertex_buffer_data);
435 glBindBuffer(GL_ARRAY_BUFFER, 0);
436 } else if (key== GLFW_KEY_LEFT && action == GLFW_PRESS ){
437 speed = speed - 1.0/256.0;
438 } else if (key== GLFW_KEY_RIGHT && action == GLFW_PRESS){
439 speed = speed + 1.0/256.0;
440 } else if ((key== GLFW_KEY_UP || key== GLFW_KEY_DOWN) && action == GLFW_PRESS){
441 speed = 0.0;
442 }
443
444 }
445
446
447 void initOpenGL(){
448 // Enable depth test
449 glEnable(GL_DEPTH_TEST);
450 // Accept fragment if it closer to the camera than the former one
451 glDepthFunc(GL_LESS);
452 glDepthRange(-1, 1);
453
454 // creation du glVertexAttribPointer
455 glGenVertexArrays(1, &vertexArrayID);
456 glBindVertexArray(vertexArrayID);
457
458
459 // Generate 1 buffer, put the resulting identifier in vertexbuffer
460 glGenBuffers(1, &vertexbuffer);
461
462 // The following commands will talk about our 'vertexbuffer' buffer
463 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
464 // Only allocqte memory. Do not send yet our vertices to OpenGL.
465 glBufferData(GL_ARRAY_BUFFER, vertexSize+colorSize+texCoordSize, 0, GL_STATIC_DRAW);
466
467 // send vertices in the first part of the buffer
468 glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize, g_vertex_buffer_data);
469
470 // send colors in the second part of the buffer
471 glBufferSubData(GL_ARRAY_BUFFER, vertexSize, colorSize, g_vertex_color_data);
472
473 // send tex coords in the third part of the buffer
474 glBufferSubData(GL_ARRAY_BUFFER, vertexSize+colorSize, texCoordSize, g_vertex_texcoord_data);
475
476 // ici les commandes stockees "une fois pour toute" dans le VAO
477 // avant on faisait ca a chaque dessin
478 glVertexAttribPointer(
479 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
480 3, // size
481 GL_FLOAT, // type
482 GL_FALSE, // normalized?
483 0, // stride
484 (void*)0 // array buffer offset
485 );
486 glEnableVertexAttribArray(0);
487
488 glVertexAttribPointer( // same thing for the colors
489 1,
490 3,
491 GL_FLOAT,
492 GL_FALSE,
493 0,
494 (void*)vertexSize);
495 glEnableVertexAttribArray(1);
496
497 glVertexAttribPointer(
498 2,
499 2,
500 GL_FLOAT,
501 GL_FALSE,
502 0,
503 (void*)(vertexSize+colorSize));
504 glEnableVertexAttribArray(2);
505
506 glBindBuffer(GL_ARRAY_BUFFER, 0);
507
508 // on desactive le VAO a la fin de l'initialisation
509 glBindVertexArray (0);
510 }
511
512
513 GLFWwindow *initMainwindow(){
514 // Nous allons apprendre a lire une texture de "symboles" generee a partir d'un outil comme :
515 // https://evanw.github.io/font-texture-generator/
516
517 glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
518 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
519 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
520 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
521 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
522 glfwWindowHint(GLFW_DEPTH_BITS, 24);
523
524 // Ouvre une fenêtre et crée son contexte OpenGl
525 GLFWwindow *win = glfwCreateWindow( winWidth, winHeight, "Main 06", NULL, NULL);
526 if( win == NULL ){
527 fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are maybe not 3.3 compatible. \n" );
528 glfwTerminate();
529 }
530
531 //
532 glfwMakeContextCurrent(win);
533
534 // Assure que l'on peut capturer la touche d'échappement
535 glfwSetInputMode(win, GLFW_STICKY_KEYS, GL_TRUE);
536
537 // active une callback = une fonction appellee automatiquement quand un evenement arrive
538 glfwSetKeyCallback(win, key_callback);
539
540 return win;
541 }
542
543
544 void draw(){
545 angleRot = (angleRot+M_PI*speed);
546
547 // clear before every draw
548 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
549
550 // Use our shader
551 glUseProgram(programID);
552
553 // matrice de projection proportionelle a la taille de la fenetre
554 mat4 projectionMatrix = ortho( -1.0f, 1.0f, -1.0f*winHeight/winWidth, 1.0f*winHeight/winWidth, -3.f, 3.f );
555 mat4 viewMatrix = lookAt(
556 vec3(1.5*cos(angleRot), 1.5*sin(angleRot), -0.35), // where is the camara
557 vec3(0, 0, 0.1), //where it looks
558 vec3(0, 0, 1.0) // head is up
559 );
560 mat4 modelMatrix = mat4(1.0);
561
562 glUniformMatrix4fv(uniform_proj, 1, GL_FALSE, value_ptr(projectionMatrix));
563 glUniformMatrix4fv(uniform_view, 1, GL_FALSE, value_ptr(viewMatrix));
564 glUniformMatrix4fv(uniform_model, 1, GL_FALSE, value_ptr(modelMatrix));
565
566 // La texture aussi est donnee en variable uniforme. On lui donne le No 0
567 glUniform1i(uniform_texture, 0);
568
569 // on re-active le VAO avant d'envoyer les buffers
570 glBindVertexArray(vertexArrayID);
571
572 // On active la texture 0
573 glActiveTexture(GL_TEXTURE0);
574
575 // Verrouillage de la texture
576 glBindTexture(GL_TEXTURE_RECTANGLE, texId);
577
578 // Draw the triangle(s) !
579 glDrawArrays(GL_TRIANGLES, 0, vertexSize/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
580
581 // Déverrouillage de la texture
582 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
583
584 // on desactive le VAO a la fin du dessin
585 glBindVertexArray (0);
586
587 // on desactive les shaders
588 glUseProgram(0);
589
590 // Swap buffers
591 glfwSwapBuffers(window);
592 glfwPollEvents();
593 }
594
595
596 int main(){
597 // Initialise GLFW
598 if( !glfwInit() ) {
599 fprintf( stderr, "Failed to initialize GLFW\n" );
600 return -1;
601 }
602
603 window = initMainwindow();
604
605 // Initialise GLEW
606 glewExperimental=true; // Nécessaire dans le profil de base
607 if (glewInit() != GLEW_OK) {
608 fprintf(stderr, "Failed to initialize GLEW\n");
609 return -1;
610 }
611
612 texId = LoadTexture("font.png");
613
614 generateData(texWidth, texHeight);
615
616 initOpenGL();
617
618 programID = LoadShaders( "SimpleVertexShader6.vertexshader", "SimpleFragmentShader6.fragmentshader" );
619 uniform_proj = glGetUniformLocation(progID, "projectionMatrix");
620 uniform_view = glGetUniformLocation(progID, "viewMatrix");
621 uniform_model = glGetUniformLocation(progID, "modelMatrix");
622 uniform_texture = glGetUniformLocation(progID, "loctexture");
623
624 double before = glfwGetTime();
625 int cpt = 0;
626 do{
627 draw();
628 cpt++;
629
630 // On a fait 100 dessins, il est temps de voir combien de temps cela a pris
631 // et quel est le taux de raffraichissement
632 if (cpt==100) {
633 double after = glfwGetTime();
634 cout << 100.0/(after-before) << "Hz"<<endl;
635 before = after;
636 cpt=0;
637 }
638 } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
639 while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );
640 }