1 // sous mac
2 // g++ -I/usr/local/include/ -lglfw -lGLEW -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs main7.cpp -framework OpenGL -omain7
3 // ./main7
4
5 // sous linux
6 // g++ -I/usr/local/include/ -I/public/ig/glm/ -c main7.cpp -omain7.o
7 // g++ -I/usr/local main7.o -lglfw -lGLEW -lGL -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -omain7
8 // ./main7
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 // Maintenant on a 2 VBO avec 2 parties chacun
47 long vertexSize1, vertexSize2, colorSize1, texCoordSize2;
48
49 // Les donnees sous forme de pointeur. Il faudra donc faire un malloc
50 // pour allouer de l'espace avant de mettre des donnees dedans
51 GLfloat *g_vertex_buffer_data1 = NULL;
52 GLfloat *g_vertex_color_data1 = NULL;
53 GLfloat *g_vertex_buffer_data2 = NULL;
54 GLfloat *g_vertex_texcoord_data2 = 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 buffers (VBOs)
77 GLuint vertexbuffer1;
78 GLuint vertexbuffer2;
79
80 // Identifiant de notre VAO
81 GLuint vertexArrayID1;
82 GLuint vertexArrayID2;
83
84 // identifiant de nos programmes de shaders
85 GLuint programID1;
86 GLuint programID2;
87
88 // stocke les variables uniformes qui seront communes a tous les vertex dessines
89 GLint uniform_proj1, uniform_view1, uniform_model1, uniform_proj2, uniform_view2, uniform_model2, uniform_texture2;
90
91
92 typedef struct Character {
93 int codePoint, x, y, width, height, originX, originY;
94 } Character;
95
96 typedef struct Font {
97 const char *name;
98 int size, bold, italic, width, height, characterCount;
99 Character *characters;
100 } Font;
101
102 // On a recupere tout ca sur le meme site qui a genere la texture des symboles
103 static Character characters_Arial[] = {
104 {' ', 311, 112, 3, 3, 1, 1},
105 {'!', 145, 86, 9, 26, -1, 25},
106 {'"', 212, 112, 16, 12, 0, 25},
107 {'#', 346, 0, 21, 27, 2, 25},
108 {'$', 128, 0, 19, 32, 1, 27},
109 {'%', 173, 0, 29, 27, 0, 25},
110 {'&', 253, 0, 24, 27, 0, 25},
111 {'\'', 228, 112, 8, 12, 0, 25},
112 {'(', 99, 0, 11, 33, 0, 25},
113 {')', 87, 0, 12, 33, 1, 25},
114 {'*', 188, 112, 15, 14, 1, 25},
115 {'+', 131, 112, 19, 19, 0, 21},
116 {',', 203, 112, 9, 13, 0, 6},
117 {'-', 257, 112, 12, 8, 0, 13},
118 {'.', 302, 112, 9, 7, 0, 6},
119 {'/', 264, 33, 13, 27, 2, 25},
120 {'0', 215, 33, 18, 27, 0, 25},
121 {'1', 109, 86, 14, 26, -1, 25},
122 {'2', 0, 86, 19, 26, 1, 25},
123 {'3', 178, 33, 19, 27, 1, 25},
124 {'4', 339, 60, 20, 26, 1, 25},
125 {'5', 159, 33, 19, 27, 0, 25},
126 {'6', 121, 33, 19, 27, 0, 25},
127 {'7', 76, 86, 18, 26, 0, 25},
128 {'8', 197, 33, 18, 27, 0, 25},
129 {'9', 140, 33, 19, 27, 1, 25},
130 {':', 122, 112, 9, 20, -1, 19},
131 {';', 172, 86, 8, 26, -1, 19},
132 {'<', 298, 86, 19, 21, 0, 22},
133 {'=', 169, 112, 19, 15, 0, 19},
134 {'>', 260, 86, 19, 21, 0, 22},
135 {'?', 299, 60, 20, 26, 0, 25},
136 {'@', 0, 0, 34, 33, 1, 25},
137 {'A', 311, 33, 27, 26, 2, 25},
138 {'B', 146, 60, 23, 26, -1, 25},
139 {'C', 300, 0, 23, 27, 0, 25},
140 {'D', 123, 60, 23, 26, -1, 25},
141 {'E', 257, 60, 21, 26, -1, 25},
142 {'F', 38, 86, 19, 26, -1, 25},
143 {'G', 228, 0, 25, 27, 0, 25},
144 {'H', 235, 60, 22, 26, -1, 25},
145 {'I', 163, 86, 9, 26, 0, 25},
146 {'J', 233, 33, 18, 27, 1, 25},
147 {'K', 75, 60, 24, 26, -1, 25},
148 {'L', 319, 60, 20, 26, -1, 25},
149 {'M', 338, 33, 26, 26, 0, 25},
150 {'N', 213, 60, 22, 26, -1, 25},
151 {'O', 202, 0, 26, 27, 0, 25},
152 {'P', 278, 60, 21, 26, -1, 25},
153 {'Q', 147, 0, 26, 29, 0, 25},
154 {'R', 99, 60, 24, 26, -1, 25},
155 {'S', 277, 0, 23, 27, 1, 25},
156 {'T', 191, 60, 22, 26, 1, 25},
157 {'U', 323, 0, 23, 27, 0, 25},
158 {'V', 50, 60, 25, 26, 2, 25},
159 {'W', 277, 33, 34, 26, 2, 25},
160 {'X', 25, 60, 25, 26, 2, 25},
161 {'Y', 0, 60, 25, 26, 2, 25},
162 {'Z', 169, 60, 22, 26, 1, 25},
163 {'[', 63, 0, 12, 33, 0, 25},
164 {'\\', 251, 33, 13, 27, 2, 25},
165 {']', 110, 0, 11, 33, 1, 25},
166 {'^', 150, 112, 19, 16, 0, 25},
167 {'_', 280, 112, 22, 7, 2, -1},
168 {'`', 269, 112, 11, 8, 1, 25},
169 {'a', 221, 86, 20, 21, 1, 19},
170 {'b', 21, 33, 20, 27, 0, 25},
171 {'c', 241, 86, 19, 21, 0, 19},
172 {'d', 81, 33, 20, 27, 0, 25},
173 {'e', 201, 86, 20, 21, 1, 19},
174 {'f', 94, 86, 15, 26, 1, 25},
175 {'g', 61, 33, 20, 27, 0, 19},
176 {'h', 57, 86, 19, 26, 0, 25},
177 {'i', 154, 86, 9, 26, 0, 25},
178 {'j', 75, 0, 12, 33, 3, 25},
179 {'k', 19, 86, 19, 26, 0, 25},
180 {'l', 136, 86, 9, 26, 0, 25},
181 {'m', 0, 112, 28, 20, 0, 19},
182 {'n', 70, 112, 19, 20, 0, 19},
183 {'o', 180, 86, 21, 21, 1, 19},
184 {'p', 41, 33, 20, 27, 0, 19},
185 {'q', 101, 33, 20, 27, 0, 19},
186 {'r', 107, 112, 15, 20, 0, 19},
187 {'s', 317, 86, 19, 21, 1, 19},
188 {'t', 123, 86, 13, 26, 1, 24},
189 {'u', 279, 86, 19, 21, 0, 19},
190 {'v', 28, 112, 21, 20, 2, 19},
191 {'w', 336, 86, 29, 20, 2, 19},
192 {'x', 49, 112, 21, 20, 2, 19},
193 {'y', 0, 33, 21, 27, 2, 19},
194 {'z', 89, 112, 18, 20, 1, 19},
195 {'{', 34, 0, 15, 33, 1, 25},
196 {'|', 121, 0, 7, 33, -1, 25},
197 {'}', 49, 0, 14, 33, 1, 25},
198 {'~', 236, 112, 21, 9, 1, 16},
199 };
200
201 char characters_ArialIndexes[256];
202
203 static Font font_Arial = {"Arial", 32, 1, 0, 367, 132, 95, characters_Arial};
204
205
206
207 // Charge une texture et retourne l'identifiant openGL
208 GLuint LoadTexture(string fileName){
209 GLuint tId = -1;
210 // On utilise OpenCV pour charger l'image
211 Mat image = imread(fileName, CV_LOAD_IMAGE_UNCHANGED);
212
213 // On va utiliser des TEXTURE_RECTANGLE au lieu de classiques TEXTURE_2D
214 // car avec ca les coordonnees de texture s'exprime en pixels et non en coordoonnes homogenes (0.0...1.0)
215 // En effet la texture est composee de lettres et symbole que nous voudrons extraire... or la position et
216 // taille de ces symboles dans la texture sont connuees en "pixels". Ca sera donc plus facile
217 glEnable(GL_TEXTURE_RECTANGLE);
218 //comme d'hab on fait generer un numero unique(ID) par OpenGL
219 glGenTextures(1, &tId);
220
221 texWidth = image.cols;
222 texHeight = image.rows;
223
224 glBindTexture(GL_TEXTURE_RECTANGLE, tId);
225 // on envoie les pixels a la carte graphique
226 glTexImage2D(GL_TEXTURE_RECTANGLE,
227 0, // mipmap level => Attention pas de mipmap dans les textures rectangle
228 GL_RGBA, // internal color format
229 image.cols,
230 image.rows,
231 0, // border width in pixels
232 GL_BGRA, // input file format. Arg le png code les canaux dans l'autre sens
233 GL_UNSIGNED_BYTE, // image data type
234 image.ptr());
235 // On peut donner des indication a opengl sur comment la texture sera utilisee
236 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
237 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
238 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
239 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
240
241 // INTERDIT sur les textures rectangle!
242 //glGenerateMipmap(GL_TEXTURE_2D);
243 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
244
245 return tId;
246 }
247
248
249 // Charge un programme de shaders, le compile et recupere dedans des pointeurs vers
250 // les variables homogenes que nous voudront mettre a jour plus tard, a chaque dessin
251 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
252
253 // Create the shaders
254 GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
255 GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
256
257 // Read the Vertex Shader code from the file
258 string VertexShaderCode;
259 ifstream VertexShaderStream(vertex_file_path, ios::in);
260 if(VertexShaderStream.is_open()){
261 string Line = "";
262 while(getline(VertexShaderStream, Line))
263 VertexShaderCode += "\n" + Line;
264 VertexShaderStream.close();
265 }else{
266 printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
267 getchar();
268 return 0;
269 }
270
271 // Read the Fragment Shader code from the file
272 string FragmentShaderCode;
273 ifstream FragmentShaderStream(fragment_file_path, ios::in);
274 if(FragmentShaderStream.is_open()){
275 string Line = "";
276 while(getline(FragmentShaderStream, Line))
277 FragmentShaderCode += "\n" + Line;
278 FragmentShaderStream.close();
279 }
280
281 GLint Result = GL_FALSE;
282 int InfoLogLength;
283
284
285 // Compile Vertex Shader
286 printf("Compiling shader : %s\n", vertex_file_path);
287 char const * VertexSourcePointer = VertexShaderCode.c_str();
288 glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
289 glCompileShader(VertexShaderID);
290
291 // Check Vertex Shader
292 glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
293 glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
294 if ( InfoLogLength > 0 ){
295 vector<char> VertexShaderErrorMessage(InfoLogLength+1);
296 glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
297 printf("%s\n", &VertexShaderErrorMessage[0]);
298 }
299
300
301
302 // Compile Fragment Shader
303 printf("Compiling shader : %s\n", fragment_file_path);
304 char const * FragmentSourcePointer = FragmentShaderCode.c_str();
305 glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
306 glCompileShader(FragmentShaderID);
307
308 // Check Fragment Shader
309 glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
310 glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
311 if ( InfoLogLength > 0 ){
312 vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
313 glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
314 printf("%s\n", &FragmentShaderErrorMessage[0]);
315 }
316
317
318
319 // Link the program
320 printf("Linking program\n");
321 GLuint progID = glCreateProgram();
322 glAttachShader(progID, VertexShaderID);
323 glAttachShader(progID, FragmentShaderID);
324 glLinkProgram(progID);
325
326
327 // Check the program
328 glGetProgramiv(progID, GL_LINK_STATUS, &Result);
329 glGetProgramiv(progID, GL_INFO_LOG_LENGTH, &InfoLogLength);
330 if ( InfoLogLength > 0 ){
331 vector<char> ProgramErrorMessage(InfoLogLength+1);
332 glGetProgramInfoLog(progID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
333 printf("%s\n", &ProgramErrorMessage[0]);
334 }
335
336
337 glDetachShader(progID, VertexShaderID);
338 glDetachShader(progID, FragmentShaderID);
339
340 glDeleteShader(VertexShaderID);
341 glDeleteShader(FragmentShaderID);
342
343 return progID;
344 }
345
346
347 void generateData(){
348 vertexSize1 = 3*3*5*N*sizeof(GLfloat);
349 colorSize1 = 3*3*5*N*sizeof(GLfloat);
350
351 vertexSize2 = 3*3*4*N*sizeof(GLfloat);
352 texCoordSize2 = 3*2*4*N*sizeof(GLfloat);
353
354 if (g_vertex_buffer_data1 != NULL)
355 free(g_vertex_buffer_data1);
356
357 if (g_vertex_color_data1!= NULL)
358 free(g_vertex_color_data1);
359
360 if (g_vertex_buffer_data2 != NULL)
361 free(g_vertex_buffer_data2);
362
363 if (g_vertex_texcoord_data2!= NULL)
364 free(g_vertex_texcoord_data2);
365
366 g_vertex_buffer_data1 = (GLfloat*)malloc(vertexSize1);
367 g_vertex_color_data1 = (GLfloat*)malloc(colorSize1);
368
369 g_vertex_buffer_data2 = (GLfloat*)malloc(vertexSize2);
370 g_vertex_texcoord_data2 = (GLfloat*)malloc(texCoordSize2);
371
372 for (int i=0; i<N; i++){
373 int val = rand()%100;
374 char *str = (char *)malloc(4);
375 sprintf(str, "%02i", val);
376 cout << val<< " ="<< str <<endl;
377 float r = (100+val)/199.0;
378 g_vertex_buffer_data1[ 0+i*9*5] = 0.0;
379 g_vertex_buffer_data1[ 1+i*9*5] = 0.0;
380 g_vertex_buffer_data1[ 2+i*9*5] = 0.0;
381
382 g_vertex_buffer_data1[ 3+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
383 g_vertex_buffer_data1[ 4+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
384 g_vertex_buffer_data1[ 5+i*9*5] = r/5.0;
385
386 g_vertex_buffer_data1[ 6+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
387 g_vertex_buffer_data1[ 7+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
388 g_vertex_buffer_data1[ 8+i*9*5] = r/5.0;
389
390
391 g_vertex_buffer_data1[ 9+i*9*5] = 0.0;
392 g_vertex_buffer_data1[10+i*9*5] = 0.0;
393 g_vertex_buffer_data1[11+i*9*5] = 0.0;
394
395 g_vertex_buffer_data1[12+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
396 g_vertex_buffer_data1[13+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
397 g_vertex_buffer_data1[14+i*9*5] = r/5.0;
398
399 g_vertex_buffer_data1[15+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
400 g_vertex_buffer_data1[16+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
401 g_vertex_buffer_data1[17+i*9*5] = 0.0;
402
403
404 g_vertex_buffer_data1[18+i*9*5] = 0.0;
405 g_vertex_buffer_data1[19+i*9*5] = 0.0;
406 g_vertex_buffer_data1[20+i*9*5] = 0.0;
407
408 g_vertex_buffer_data1[21+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
409 g_vertex_buffer_data1[22+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
410 g_vertex_buffer_data1[23+i*9*5] = r/5.0;
411
412 g_vertex_buffer_data1[24+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
413 g_vertex_buffer_data1[25+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
414 g_vertex_buffer_data1[26+i*9*5] = 0.0;
415
416
417 g_vertex_buffer_data1[27+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
418 g_vertex_buffer_data1[28+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
419 g_vertex_buffer_data1[29+i*9*5] = r/5.0;
420
421 g_vertex_buffer_data1[30+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
422 g_vertex_buffer_data1[31+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
423 g_vertex_buffer_data1[32+i*9*5] = r/5.0;
424
425 g_vertex_buffer_data1[33+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
426 g_vertex_buffer_data1[34+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
427 g_vertex_buffer_data1[35+i*9*5] = 0.0;
428
429 g_vertex_buffer_data1[36+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
430 g_vertex_buffer_data1[37+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
431 g_vertex_buffer_data1[38+i*9*5] = r/5.0;
432
433 g_vertex_buffer_data1[39+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
434 g_vertex_buffer_data1[40+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
435 g_vertex_buffer_data1[41+i*9*5] = 0.0;
436
437 g_vertex_buffer_data1[42+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
438 g_vertex_buffer_data1[43+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
439 g_vertex_buffer_data1[44+i*9*5] = 0.0;
440
441
442 g_vertex_color_data1[ 0+i*9*5] = 0.0;
443 g_vertex_color_data1[ 1+i*9*5] = 0.0;
444 g_vertex_color_data1[ 2+i*9*5] = 1.0;
445
446 g_vertex_color_data1[ 3+i*9*5] = 0.5;
447 g_vertex_color_data1[ 4+i*9*5] = 0.0;
448 g_vertex_color_data1[ 5+i*9*5] = 0.0;
449
450 g_vertex_color_data1[ 6+i*9*5] = 1.0;
451 g_vertex_color_data1[ 7+i*9*5] = 0.0;
452 g_vertex_color_data1[ 8+i*9*5] = 0.0;
453
454 g_vertex_color_data1[ 9+i*9*5] = 0.5;
455 g_vertex_color_data1[10+i*9*5] = 0.0;
456 g_vertex_color_data1[11+i*9*5] = 1.0;
457
458 g_vertex_color_data1[12+i*9*5] = 0.5;
459 g_vertex_color_data1[13+i*9*5] = 0.0;
460 g_vertex_color_data1[14+i*9*5] = 0.0;
461
462 g_vertex_color_data1[15+i*9*5] = 0.5;
463 g_vertex_color_data1[16+i*9*5] = 0.0;
464 g_vertex_color_data1[17+i*9*5] = 0.0;
465
466 g_vertex_color_data1[18+i*9*5] = 1.0;
467 g_vertex_color_data1[19+i*9*5] = 0.0;
468 g_vertex_color_data1[20+i*9*5] = 1.0;
469
470 g_vertex_color_data1[21+i*9*5] = 1.0;
471 g_vertex_color_data1[22+i*9*5] = 0.0;
472 g_vertex_color_data1[23+i*9*5] = 0.0;
473
474 g_vertex_color_data1[24+i*9*5] = 1.0;
475 g_vertex_color_data1[25+i*9*5] = 0.0;
476 g_vertex_color_data1[26+i*9*5] = 0.0;
477
478 g_vertex_color_data1[27+i*9*5] = 1.0;
479 g_vertex_color_data1[28+i*9*5] = 0.0;
480 g_vertex_color_data1[29+i*9*5] = 0.0;
481
482 g_vertex_color_data1[30+i*9*5] = 0.5;
483 g_vertex_color_data1[31+i*9*5] = 0.0;
484 g_vertex_color_data1[32+i*9*5] = 0.0;
485
486 g_vertex_color_data1[33+i*9*5] = 1.0;
487 g_vertex_color_data1[34+i*9*5] = 0.0;
488 g_vertex_color_data1[35+i*9*5] = 0.0;
489
490 g_vertex_color_data1[36+i*9*5] = 0.5;
491 g_vertex_color_data1[37+i*9*5] = 0.0;
492 g_vertex_color_data1[38+i*9*5] = 0.0;
493
494 g_vertex_color_data1[39+i*9*5] = 0.5;
495 g_vertex_color_data1[40+i*9*5] = 0.0;
496 g_vertex_color_data1[41+i*9*5] = 0.0;
497
498 g_vertex_color_data1[42+i*9*5] = 1.0;
499 g_vertex_color_data1[43+i*9*5] = 0.0;
500 g_vertex_color_data1[44+i*9*5] = 0.0;
501
502 g_vertex_buffer_data2[0+i*9*4] = 0.0+r*cos((2*i+1.45)*M_PI/(N));
503 g_vertex_buffer_data2[1+i*9*4] = 0.0+r*sin((2*i+1.45)*M_PI/(N));
504 g_vertex_buffer_data2[2+i*9*4] = 3*r/20.0;
505
506 g_vertex_buffer_data2[3+i*9*4] = 0.0+r*cos((2*i+1.0)*M_PI/(N));
507 g_vertex_buffer_data2[4+i*9*4] = 0.0+r*sin((2*i+1.0)*M_PI/(N));
508 g_vertex_buffer_data2[5+i*9*4] = 3*r/20.0;
509
510 g_vertex_buffer_data2[6+i*9*4] = 0.0+r*cos((2*i+1.45)*M_PI/(N));
511 g_vertex_buffer_data2[7+i*9*4] = 0.0+r*sin((2*i+1.45)*M_PI/(N));
512 g_vertex_buffer_data2[8+i*9*4] = 1*r/20.0;
513
514 g_vertex_buffer_data2[9+i*9*4] = 0.0+r*cos((2*i+1.0)*M_PI/(N));
515 g_vertex_buffer_data2[10+i*9*4] = 0.0+r*sin((2*i+1.0)*M_PI/(N));
516 g_vertex_buffer_data2[11+i*9*4] = 3*r/20.0;
517
518 g_vertex_buffer_data2[12+i*9*4] = 0.0+r*cos((2*i+1.0)*M_PI/(N));
519 g_vertex_buffer_data2[13+i*9*4] = 0.0+r*sin((2*i+1.0)*M_PI/(N));
520 g_vertex_buffer_data2[14+i*9*4] = 1*r/20.0; ;
521
522 g_vertex_buffer_data2[15+i*9*4] = 0.0+r*cos((2*i+1.45)*M_PI/(N));
523 g_vertex_buffer_data2[16+i*9*4] = 0.0+r*sin((2*i+1.45)*M_PI/(N));
524 g_vertex_buffer_data2[17+i*9*4] = 1*r/20.0; ;
525
526
527 g_vertex_buffer_data2[18+i*9*4] = 0.0+r*cos((2*i+1.00)*M_PI/(N));
528 g_vertex_buffer_data2[19+i*9*4] = 0.0+r*sin((2*i+1.00)*M_PI/(N));
529 g_vertex_buffer_data2[20+i*9*4] = 3*r/20.0;
530
531 g_vertex_buffer_data2[21+i*9*4] = 0.0+r*cos((2*i+0.5)*M_PI/(N));
532 g_vertex_buffer_data2[22+i*9*4] = 0.0+r*sin((2*i+0.5)*M_PI/(N));
533 g_vertex_buffer_data2[23+i*9*4] = 3*r/20.0;
534
535 g_vertex_buffer_data2[24+i*9*4] = 0.0+r*cos((2*i+1.00)*M_PI/(N));
536 g_vertex_buffer_data2[25+i*9*4] = 0.0+r*sin((2*i+1.00)*M_PI/(N));
537 g_vertex_buffer_data2[26+i*9*4] = 1*r/20.0;
538
539 g_vertex_buffer_data2[27+i*9*4] = 0.0+r*cos((2*i+0.5)*M_PI/(N));
540 g_vertex_buffer_data2[28+i*9*4] = 0.0+r*sin((2*i+0.5)*M_PI/(N));
541 g_vertex_buffer_data2[29+i*9*4] = 3*r/20.0;
542
543 g_vertex_buffer_data2[30+i*9*4] = 0.0+r*cos((2*i+0.5)*M_PI/(N));
544 g_vertex_buffer_data2[31+i*9*4] = 0.0+r*sin((2*i+0.5)*M_PI/(N));
545 g_vertex_buffer_data2[32+i*9*4] = 1*r/20.0; ;
546
547 g_vertex_buffer_data2[33+i*9*4] = 0.0+r*cos((2*i+1.00)*M_PI/(N));
548 g_vertex_buffer_data2[34+i*9*4] = 0.0+r*sin((2*i+1.00)*M_PI/(N));
549 g_vertex_buffer_data2[35+i*9*4] = 1*r/20.0;
550
551
552
553
554 // on doit maintenant generer des coordonnees de texture pour chaque vertex.
555 // plutot que d'afficher toute la texture on affiche que la sous partie qui correspond au 2ieme symbole
556 char symbol = str[0];
557 char index = characters_ArialIndexes[symbol];
558
559 g_vertex_texcoord_data2[0+i*6*4] = characters_Arial[index].x+1;
560 g_vertex_texcoord_data2[1+i*6*4] = characters_Arial[index].y+1;
561
562 g_vertex_texcoord_data2[2+i*6*4] = characters_Arial[index].x+1+characters_Arial[20].width-2;
563 g_vertex_texcoord_data2[3+i*6*4] = characters_Arial[index].y+1;
564
565 g_vertex_texcoord_data2[4+i*6*4] = characters_Arial[index].x+1;
566 g_vertex_texcoord_data2[5+i*6*4] = characters_Arial[index].y+1+characters_Arial[20].height-2;
567
568 g_vertex_texcoord_data2[6+i*6*4] = characters_Arial[index].x+1+characters_Arial[20].width-2;
569 g_vertex_texcoord_data2[7+i*6*4] = characters_Arial[index].y+1;
570
571 g_vertex_texcoord_data2[8+i*6*4] = characters_Arial[index].x+1+characters_Arial[20].width-2;
572 g_vertex_texcoord_data2[9+i*6*4] = characters_Arial[index].y+1+characters_Arial[20].height-2;
573
574 g_vertex_texcoord_data2[10+i*6*4] = characters_Arial[index].x+1;
575 g_vertex_texcoord_data2[11+i*6*4] = characters_Arial[index].y+1+characters_Arial[20].height-2;
576
577
578 symbol = str[1];
579 index = characters_ArialIndexes[symbol];
580
581 g_vertex_texcoord_data2[12+i*6*4] = characters_Arial[index].x+1;
582 g_vertex_texcoord_data2[13+i*6*4] = characters_Arial[index].y+1;
583
584 g_vertex_texcoord_data2[14+i*6*4] = characters_Arial[index].x+1+characters_Arial[20].width-2;
585 g_vertex_texcoord_data2[15+i*6*4] = characters_Arial[index].y+1;
586
587 g_vertex_texcoord_data2[16+i*6*4] = characters_Arial[index].x+1;
588 g_vertex_texcoord_data2[17+i*6*4] = characters_Arial[index].y+1+characters_Arial[20].height-2;
589
590 g_vertex_texcoord_data2[18+i*6*4] = characters_Arial[index].x+1+characters_Arial[20].width-2;
591 g_vertex_texcoord_data2[19+i*6*4] = characters_Arial[index].y+1;
592
593 g_vertex_texcoord_data2[20+i*6*4] = characters_Arial[index].x+1+characters_Arial[20].width-2;
594 g_vertex_texcoord_data2[21+i*6*4] = characters_Arial[index].y+1+characters_Arial[20].height-2;
595
596 g_vertex_texcoord_data2[22+i*6*4] = characters_Arial[index].x+1;
597 g_vertex_texcoord_data2[23+i*6*4] = characters_Arial[index].y+1+characters_Arial[20].height-2;
598 }
599 }
600
601
602 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
603 {
604 // on teste si la touche E est pressee et si c'est le cas on re-genere des donnees
605 if (key== GLFW_KEY_E && action == GLFW_PRESS){
606
607 generateData();
608 // ici on n'envoie que les sommets car on souhaite garder les memes couleurs ... et le nombre
609 // n'a pas change !
610 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer1);
611 glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize1, g_vertex_buffer_data1);
612 glBindBuffer(GL_ARRAY_BUFFER, 0);
613 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
614 glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize2, g_vertex_buffer_data2);
615 glBindBuffer(GL_ARRAY_BUFFER, 0);
616 } else if (key== GLFW_KEY_LEFT && action == GLFW_PRESS ){
617 speed = speed - 1.0/256.0;
618 } else if (key== GLFW_KEY_RIGHT && action == GLFW_PRESS){
619 speed = speed + 1.0/256.0;
620 } else if ((key== GLFW_KEY_UP || key== GLFW_KEY_DOWN) && action == GLFW_PRESS){
621 speed = 0.0;
622 }
623
624 }
625
626
627 void initOpenGL(){
628 // Enable depth test
629 glEnable(GL_DEPTH_TEST);
630 // Accept fragment if it closer to the camera than the former one
631 glDepthFunc(GL_LESS);
632 glDepthRange(-1, 1);
633
634 // car maintenant on va appliquer une texture transparente par dessus un quad colore
635 // (avant on pouvait faire le melange nous meme dans le fragment shader car tout etait
636 // faitdans un meme shader)
637 glEnable(GL_BLEND);
638 glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
639 glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
640
641 // creation du glVertexAttribPointer
642 glGenVertexArrays(1, &vertexArrayID1);
643 glGenVertexArrays(2, &vertexArrayID2);
644
645 // Generate 2 buffers, put the resulting identifier in vertexbuffer
646 glGenBuffers(1, &vertexbuffer1);
647 glGenBuffers(1, &vertexbuffer2);
648
649 glBindVertexArray(vertexArrayID1);
650
651 // The following commands will talk about our 'vertexbuffer' buffer
652 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer1);
653 // Only allocqte memory. Do not send yet our vertices to OpenGL.
654 glBufferData(GL_ARRAY_BUFFER, vertexSize1+colorSize1, 0, GL_STATIC_DRAW);
655
656 // send vertices in the first part of the buffer
657 glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize1, g_vertex_buffer_data1);
658
659 // send colors in the second part of the buffer
660 glBufferSubData(GL_ARRAY_BUFFER, vertexSize1, colorSize1, g_vertex_color_data1);
661
662 // ici les commandes stockees "une fois pour toute" dans le VAO
663 // avant on faisait ca a chaque dessin
664 glVertexAttribPointer(
665 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
666 3, // size
667 GL_FLOAT, // type
668 GL_FALSE, // normalized?
669 0, // stride
670 (void*)0 // array buffer offset
671 );
672 glEnableVertexAttribArray(0);
673
674 glVertexAttribPointer( // same thing for the colors
675 1,
676 3,
677 GL_FLOAT,
678 GL_FALSE,
679 0,
680 (void*)vertexSize1);
681 glEnableVertexAttribArray(1);
682
683 glBindVertexArray(vertexArrayID2);
684 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
685
686 // Only allocqte memory. Do not send yet our vertices to OpenGL.
687 glBufferData(GL_ARRAY_BUFFER, vertexSize2+texCoordSize2, 0, GL_STATIC_DRAW);
688
689 // send vertices in the first part of the buffer
690 glBufferSubData(GL_ARRAY_BUFFER, 0, vertexSize2, g_vertex_buffer_data2);
691
692 // send tex coords in the second part of the buffer
693 glBufferSubData(GL_ARRAY_BUFFER, vertexSize2, texCoordSize2, g_vertex_texcoord_data2);
694
695 // ici les commandes stockees "une fois pour toute" dans le VAO
696 // avant on faisait ca a chaque dessin
697 glVertexAttribPointer(
698 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
699 3, // size
700 GL_FLOAT, // type
701 GL_FALSE, // normalized?
702 0, // stride
703 (void*)0 // array buffer offset
704 );
705 glEnableVertexAttribArray(0);
706
707 glVertexAttribPointer(
708 1,
709 2,
710 GL_FLOAT,
711 GL_FALSE,
712 0,
713 (void*)(vertexSize2));
714 glEnableVertexAttribArray(1);
715
716 glBindBuffer(GL_ARRAY_BUFFER, 0);
717
718 // on desactive le VAO a la fin de l'initialisation
719 glBindVertexArray (0);
720 }
721
722
723 GLFWwindow *initMainwindow(){
724 // Nous allons apprendre a lire une texture de "symboles" generee a partir d'un outil comme :
725 // https://evanw.github.io/font-texture-generator/
726
727 glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
728 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
729 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
730 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
731 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
732 glfwWindowHint(GLFW_DEPTH_BITS, 24);
733
734 // Ouvre une fenêtre et crée son contexte OpenGl
735 GLFWwindow *win = glfwCreateWindow( winWidth, winHeight, "Main 07", NULL, NULL);
736 if( win == NULL ){
737 fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are maybe not 3.3 compatible. \n" );
738 glfwTerminate();
739 }
740
741 //
742 glfwMakeContextCurrent(win);
743
744 // Assure que l'on peut capturer la touche d'échappement
745 glfwSetInputMode(win, GLFW_STICKY_KEYS, GL_TRUE);
746
747 // active une callback = une fonction appellee automatiquement quand un evenement arrive
748 glfwSetKeyCallback(win, key_callback);
749
750 return win;
751 }
752
753
754 void draw(){
755 angleRot = (angleRot+M_PI*speed);
756
757 // clear before every draw
758 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
759
760 // matrice de projection proportionelle a la taille de la fenetre
761 mat4 projectionMatrix = ortho( -1.0f, 1.0f, -1.0f*winHeight/winWidth, 1.0f*winHeight/winWidth, -3.f, 3.f );
762 mat4 viewMatrix = lookAt(
763 vec3(1.5*cos(angleRot), 1.5*sin(angleRot), -0.35), // where is the camara
764 vec3(0, 0, 0.1), //where it looks
765 vec3(0, 0, 1.0) // head is up
766 );
767 mat4 modelMatrix = mat4(1.0);
768
769 // Use our shader
770 glUseProgram(programID1);
771
772 glUniformMatrix4fv(uniform_proj1, 1, GL_FALSE, value_ptr(projectionMatrix));
773 glUniformMatrix4fv(uniform_view1, 1, GL_FALSE, value_ptr(viewMatrix));
774 glUniformMatrix4fv(uniform_model1, 1, GL_FALSE, value_ptr(modelMatrix));
775
776 // on re-active le VAO avant d'envoyer les buffers
777 glBindVertexArray(vertexArrayID1);
778
779 // Draw the triangle(s) !
780 glDrawArrays(GL_TRIANGLES, 0, vertexSize1/(3*sizeof(float)));
781
782 // on desactive le VAO a la fin du dessin
783 glBindVertexArray (0);
784
785 // Use our second shader
786 glUseProgram(programID2);
787
788 glUniformMatrix4fv(uniform_proj2, 1, GL_FALSE, value_ptr(projectionMatrix));
789 glUniformMatrix4fv(uniform_view2, 1, GL_FALSE, value_ptr(viewMatrix));
790 glUniformMatrix4fv(uniform_model2, 1, GL_FALSE, value_ptr(modelMatrix));
791
792 // La texture aussi est donnee en variable uniforme. On lui donne le No 0
793 glUniform1i(uniform_texture2, 0);
794
795 // on re-active le VAO avant d'envoyer les buffers
796 glBindVertexArray(vertexArrayID2);
797
798 // On active la texture 0
799 glActiveTexture(GL_TEXTURE0);
800
801 // Verrouillage de la texture
802 glBindTexture(GL_TEXTURE_RECTANGLE, texId);
803
804 // Draw the triangle(s) !
805 glDrawArrays(GL_TRIANGLES, 0, vertexSize2/(3*sizeof(float)));
806
807 // Déverrouillage de la texture
808 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
809
810 // on desactive le VAO a la fin du dessin
811 glBindVertexArray (0);
812
813 // on desactive les shaders
814 glUseProgram(0);
815
816 // Swap buffers
817 glfwSwapBuffers(window);
818 glfwPollEvents();
819 }
820
821
822 int main(){
823 // Probleme, le tableau des symboles (avec leurs positions et tailles dans la texture) ne permet pas de
824 // facilement trouver les infos correspondantes a un symbole donne (par exemple ou est le symbole 4 dans la texture)
825 // Pour eviter de faire une boucle et cherche les symboles un par un on stocke dans un grand tableau (<256 :-)
826 // ou se trouve les infos de chaque symbole de la table ASCII (256 symboles max !)
827 for (int i=0 ; i< sizeof(characters_Arial)/sizeof(characters_Arial[0]); i++){
828 Character c0 = characters_Arial[i];
829 char index = c0.codePoint;
830 characters_ArialIndexes[index] = i;
831 }
832 cout << "indice du caractere '4' dans le tableau des "<< (sizeof(characters_Arial)/sizeof(characters_Arial[0])) <<"symboles : " << (int)characters_ArialIndexes['4']<<endl;
833
834 // Initialise GLFW
835 if( !glfwInit() ) {
836 fprintf( stderr, "Failed to initialize GLFW\n" );
837 return -1;
838 }
839
840 window = initMainwindow();
841
842 // Initialise GLEW
843 glewExperimental=true; // Nécessaire dans le profil de base
844 if (glewInit() != GLEW_OK) {
845 fprintf(stderr, "Failed to initialize GLEW\n");
846 return -1;
847 }
848
849 generateData();
850
851 initOpenGL();
852
853 texId = LoadTexture("font.png");
854
855
856 programID1 = LoadShaders( "SimpleVertexShader71.vertexshader", "SimpleFragmentShader71.fragmentshader" );
857 uniform_proj1 = glGetUniformLocation(programID1, "projectionMatrix");
858 uniform_view1 = glGetUniformLocation(programID1, "viewMatrix");
859 uniform_model1 = glGetUniformLocation(programID1, "modelMatrix");
860 programID2 = LoadShaders( "SimpleVertexShader72.vertexshader", "SimpleFragmentShader72.fragmentshader" );
861 uniform_proj2 = glGetUniformLocation(programID2, "projectionMatrix");
862 uniform_view2 = glGetUniformLocation(programID2, "viewMatrix");
863 uniform_model2 = glGetUniformLocation(programID2, "modelMatrix");
864 uniform_texture2 = glGetUniformLocation(programID2, "loctexture");
865 cout <<uniform_texture2<<endl;
866
867 double before = glfwGetTime();
868 int cpt = 0;
869 do{
870 draw();
871 cpt++;
872
873 // On a fait 100 dessins, il est temps de voir combien de temps cela a pris
874 // et quel est le taux de raffraichissement
875 if (cpt==100) {
876 double after = glfwGetTime();
877 cout << 100.0/(after-before) << "Hz"<<endl;
878 before = after;
879 cpt=0;
880 }
881 } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
882 while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );
883 }