1 // sous mac
2 // g++ -I/usr/local/include/ -lglfw -lGLEW -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs main54.cpp -framework OpenGL -omain54
3 // ./main54
4
5 // sous linux
6 // g++ -I/usr/local/include/ -I/public/ig/glm/ -c main54.cpp -omain54.o
7 // g++ -I/usr/local main54.o -lglfw -lGLEW -lGL -omain54
8 // ./main54
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 #include <map>
18 using namespace std;
19
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <GL/glew.h>
24 #include <GLFW/glfw3.h>
25
26 // following the tutorial found here:
27 // https://www.learnopencv.com/delaunay-triangulation-and-voronoi-diagram-using-opencv-c-python/
28 // http://www.faadoosupport.com/learning-opencv-3-delaunay-triangulation-and-voronoi-diagram-explanation/
29 #include <opencv2/imgproc/imgproc.hpp>
30 #include <opencv2/highgui/highgui.hpp>
31
32 #ifdef __APPLE__
33 #include <OpenGL/gl.h>
34 #else
35 #include <GL/gl.h>
36 #endif
37
38 #define GLM_FORCE_RADIANS
39 #include <glm/glm.hpp>
40 #include <glm/gtc/matrix_transform.hpp>
41 #include <glm/gtc/type_ptr.hpp>
42
43
44 using namespace glm;
45 using namespace cv;
46
47 double dangle = M_PI/1024;
48
49 const int N = 10000000;
50
51 std::map<Point2f,float> altitudes;
52 std::map<Point2f,float> infos2;
53 long sss=0;
54 GLfloat *g_vertex_buffer_data;
55 GLfloat *g_vertex_color_data;
56 GLfloat *g_vertex_normal_data;
57 vector<vector<Point2f> > facets;
58 vector<Point2f> centers;
59
60 // stocke les variables uniformes qui seront communes a tous les vertex dessines dans une variable globale
61 GLint uniform_proj, uniform_view, uniform_model;
62 float w = 1000.0;
63
64 // france in geojson from :
65 //https://github.com/mledoze/countries/blob/bb61a1cddfefd09ad5c92ad0a1effbfceba39930/data/fra.geo.json
66
67 bool sitesOrdered(const Point2f& s1, const Point2f& s2) {
68 if (s1.y < s2.y)
69 return true;
70 if (s1.y == s2.y && s1.x < s2.x)
71 return true;
72
73 return false;
74 }
75
76
77
78 namespace cv {
79 bool operator<(Point2f const& lhs, Point2f const& rhs) {
80 return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
81 }
82 }
83
84
85
86 void readData(){
87 std::cout << "readData " <<endl;
88 unsigned int nPoints;
89 float dimension = 1.0;
90 Rect *rect = new Rect(0, 0, w, w);
91
92
93
94
95 // Create an instance of Subdiv2D
96 Subdiv2D *subdiv = new Subdiv2D(*rect);
97
98 ifstream file ( "villes.csv" ); // declare file stream: http://www.cplusplus.com/reference/iostream/ifstream/
99 string value;
100 getline ( file, value, '\n' );
101
102
103 float minlon = 10;
104 float maxlon = 0;
105 float minlat = 10;
106 float maxlat = 0;
107 int count = 0;
108
109 vector<Point2f> tmpSites;
110 vector<Point2f> sites;
111 Point2f s;
112
113
114 while ( file.good() ) {
115 getline ( file, value, ';' ); // read a string until next comma: http://www.cplusplus.com/reference/string/getline/
116 string sinsee = string( value, 0, value.length() );
117 getline ( file, value, ';' );
118 string sname = string( value, 0, value.length() );
119 getline ( file, value, ';' );
120 string saltitude = string( value, 0, value.length() );
121 float alt = stof(saltitude, NULL);
122 getline ( file, value, ';' );
123 string scp = string( value, 0, value.length() );
124 getline ( file, value, ';' );
125 string slon = string( value, 0, value.length() );
126 float lon = stof(slon, NULL);
127 getline ( file, value, ';' );
128 string slat = string( value, 0, value.length() );
129 float lat = stof(slat, NULL);
130 getline ( file, value, ';' );
131 string spop = string( value, 0, value.length() );
132 int pop = stoi(spop, NULL);
133 getline ( file, value, '\n' );
134 string ssur = string( value, 0, value.length() );
135 float sur = stof(ssur, NULL);
136
137 count++;
138 if (count<N){
139 minlon = glm::min(lon, minlon);
140 maxlon = glm::max(lon, maxlon);
141 minlat = glm::min(lat, minlat);
142 maxlat = glm::max(lat, maxlat);
143 s.x = lon;
144 s.y = lat;
145 altitudes[s] = alt/20000.0;
146 infos2[s] = pop/sur/200.0;
147
148 tmpSites.push_back(s);
149 }
150
151 }
152
153 cout << "City File read !" << tmpSites.size() << " / " << N << endl;
154 cout <<" lons:"<<minlon<<"..."<<maxlon<<endl;
155 cout <<" lats:"<<minlat<<"..."<<maxlat<<endl;
156
157 ifstream file2 ( "fra.geo.json" ); // declare file stream: http://www.cplusplus.com/reference/iostream/ifstream/
158 getline ( file2, value, '[' );
159 getline ( file2, value, '[' );
160 getline ( file2, value, '[' );
161 getline ( file2, value, '[' );
162 getline ( file2, value, '[' );
163 count = 0;
164 while ( file2.good() ) {
165 getline ( file2, value, ',' );
166 int i=0;
167 while(value.at(i)=='[') i++;
168 string sx = string( value, i, value.length());
169
170 getline ( file2, value, ']' );
171 string sy = string( value, 0, value.length());
172 getline ( file2, value, '[' );
173
174 float lon = M_PI/180.0*stof(sx, NULL);
175 float lat = M_PI/180.0*stof(sy, NULL);
176 minlon=glm::min(lon, minlon);
177 maxlon=glm::max(lon, maxlon);
178 minlat=glm::min(lat, minlat);
179 maxlat=glm::max(lat, maxlat);
180 s.x = lon;
181 s.y = lat;
182 // cout << s.x << ", " << s.y << " " << endl;
183 tmpSites.push_back(s);
184 altitudes[s] = -0.25;
185 count++;
186 }
187 cout << "Border File read !" << count << endl;
188 cout <<" lons:"<<minlon<<"..."<<maxlon<<" among "<<tmpSites.size()<<" / "<<N<<endl;
189 cout <<" lats:"<<minlat<<"..."<<maxlat<<" among "<<tmpSites.size()<<" / "<<N<<endl;
190
191 //enleve les doublons et normalise
192 Point2f s2;
193 std::sort(tmpSites.begin(), tmpSites.end(), sitesOrdered);
194 s2.x = (0.1+(tmpSites[0].x-minlon)/(maxlon-minlon))*0.8*w;
195 s2.y = (0.1+(tmpSites[0].y-minlat)/(maxlat-minlat))*0.8*w;
196
197 sites.push_back(s2);
198 for (vector<Point2f>::iterator it = tmpSites.begin(); it != tmpSites.end(); it++) {
199 Point2f& s =*it;
200 s2.x = (0.1+(s.x-minlon)/(maxlon-minlon)*0.8)*w;
201 s2.y = (0.1+(s.y-minlat)/(maxlat-minlat)*0.8)*w;
202
203 if (s != sites.back()) {
204 sites.push_back(s2);
205 altitudes[s2] = altitudes[s];
206 infos2[s2] = infos2[s];
207 } else{
208 cout <<"WARNING: "<<s2.x<<","<<s2.y<<" is identical to "<<sites.back().x<<","<<sites.back().y<<endl;
209 }
210
211 }
212 cout << " point normalization and duplicate removal done. " <<endl;
213
214 for( vector<Point2f>::iterator it = sites.begin(); it != sites.end(); it++){
215 subdiv->insert(*it);
216 }
217
218 // Voila c'est ici qu'on lance l'algo de Voronoi
219 subdiv->getVoronoiFacetList(vector<int>(), facets, centers);
220
221 cout << " facets¢ers list: " << facets.size() << " % " << centers.size()<<endl;
222
223 // une premiere passe sur les cellule de voronoi pour ajouter a cahque point du bord
224 // l'altitude du centre de la cellule de vononoi (chaque point devrait se voir ajouter 3 altitudes !)
225 for( size_t i = 0; i < facets.size(); i++ ){
226 for( size_t j = 0; j < facets[i].size(); j++ ){
227 altitudes[facets[i][j]] = altitudes[facets[i][j]] + altitudes[centers[i]];
228 sss++; // on en profite pour compter combien de triangles nous aurons besoin
229 }
230 }
231
232 // sss est ici le nombre de triangles necessaires .. mais on voudrait plutot la taille memoire cencessaire
233 sss = (4+sss)*sizeof(GLfloat)*9;
234
235 cout << "allocate arrays => " << sss << endl;
236
237 // Malheureusement on ne peut plus faire de l'allocation statique de memoire
238 g_vertex_buffer_data = (GLfloat *)malloc(sss);
239 g_vertex_color_data = (GLfloat *)malloc(sss);
240 g_vertex_normal_data = (GLfloat *)malloc(sss);
241 //GLfloat g_vertex_buffer_data[sss];
242 //GLfloat g_vertex_color_data[sss];
243 }
244
245
246 void updateRepr(float gain1, float gain2){
247 long ii=0;
248 glm::vec3 normal;
249
250 for( size_t i = 0; i < facets.size(); i++ ){
251 Point2f p0 = centers[i];
252 srand(i); // chaque facette aura une couleur differente
253 float r = (rand()%256)/256.0;
254 float g = (rand()%256)/256.0;
255 float b = 0.0;
256 for( size_t j = 0; j < facets[i].size(); j++ ){
257 Point2f p1 = facets[i][j];
258 // ah ah ah qui comprend la formule avec un modulo ?
259 Point2f p2 = facets[i][(j+facets[i].size()-1)%facets[i].size()];
260
261 g_vertex_buffer_data[ 0+ii*9] = p0.x/w;
262 g_vertex_buffer_data[ 1+ii*9] = p0.y/w;
263 g_vertex_buffer_data[ 2+ii*9] = gain1*altitudes[p0];
264
265 g_vertex_buffer_data[ 3+ii*9] = p1.x/w;
266 g_vertex_buffer_data[ 4+ii*9] = p1.y/w;
267 g_vertex_buffer_data[ 5+ii*9] = gain1*altitudes[p1]/3.0;
268
269 g_vertex_buffer_data[ 6+ii*9] = p2.x/w;
270 g_vertex_buffer_data[ 7+ii*9] = p2.y/w;
271 g_vertex_buffer_data[ 8+ii*9] = gain1*altitudes[p2]/3.0;
272
273 // le centre de la cellule de voronoi a une couleur dependant de info2
274 g_vertex_color_data[ 0+ii*9] = gain2*infos2[p0];
275 g_vertex_color_data[ 1+ii*9] = gain2*infos2[p0];
276 g_vertex_color_data[ 2+ii*9] = gain2*infos2[p0];
277
278 //les bords de la cellule de voronoi ont une couleur aleatoire dependante de la cellule
279 g_vertex_color_data[ 3+ii*9] = 0.5+r/2.0;
280 g_vertex_color_data[ 4+ii*9] = 0.5+g/2.0;
281 g_vertex_color_data[ 5+ii*9] = 0.5+b/2.0;
282
283 g_vertex_color_data[ 6+ii*9] = 0.5+r/2.0;
284 g_vertex_color_data[ 7+ii*9] = 0.5+g/2.0;
285 g_vertex_color_data[ 8+ii*9] = 0.5+b/2.0;
286
287 // calcul de la normale
288 normal = -glm::normalize(glm::cross(glm::vec3(p1.x/w, p1.y/w, gain1*altitudes[p1]/3.0)-
289 glm::vec3(p0.x/w, p0.y/w, gain1*altitudes[p0]),
290 glm::vec3(p2.x/w, p2.y/w, gain1*altitudes[p2]/3.0)-
291 glm::vec3(p0.x/w, p0.y/w, gain1*altitudes[p0])));
292
293 g_vertex_normal_data[ 0+ii*9] = normal.x;
294 g_vertex_normal_data[ 1+ii*9] = normal.y;
295 g_vertex_normal_data[ 2+ii*9] = normal.z;
296
297 g_vertex_normal_data[ 3+ii*9] = normal.x;
298 g_vertex_normal_data[ 4+ii*9] = normal.y;
299 g_vertex_normal_data[ 5+ii*9] = normal.z;
300
301 g_vertex_normal_data[ 6+ii*9] = normal.x;
302 g_vertex_normal_data[ 7+ii*9] = normal.y;
303 g_vertex_normal_data[ 8+ii*9] = normal.z;
304
305 ii++;
306 }
307 }
308
309 // 4 triangles pour la mer
310 g_vertex_buffer_data[ 0+ii*9] = 0.5;
311 g_vertex_buffer_data[ 1+ii*9] = 0.5;
312 g_vertex_buffer_data[ 2+ii*9] = 0;
313
314 g_vertex_buffer_data[ 3+ii*9] = 1.5;
315 g_vertex_buffer_data[ 4+ii*9] = -0.5;
316 g_vertex_buffer_data[ 5+ii*9] = 0;
317
318 g_vertex_buffer_data[ 6+ii*9] = 1.5;
319 g_vertex_buffer_data[ 7+ii*9] = 1.5;
320 g_vertex_buffer_data[ 8+ii*9] = 0;
321
322 g_vertex_color_data[ 0+ii*9] = 0;
323 g_vertex_color_data[ 1+ii*9] = 0;
324 g_vertex_color_data[ 2+ii*9] = 0.7;
325
326 g_vertex_color_data[ 3+ii*9] = 0;
327 g_vertex_color_data[ 4+ii*9] = 0;
328 g_vertex_color_data[ 5+ii*9] = 0.1;
329
330 g_vertex_color_data[ 6+ii*9] = 0;
331 g_vertex_color_data[ 7+ii*9] = 0;
332 g_vertex_color_data[ 8+ii*9] = 0.1;
333
334 ii++;
335
336 g_vertex_buffer_data[ 0+ii*9] = 0.5;
337 g_vertex_buffer_data[ 1+ii*9] = 0.5;
338 g_vertex_buffer_data[ 2+ii*9] = 0;
339
340 g_vertex_buffer_data[ 3+ii*9] = -0.5;
341 g_vertex_buffer_data[ 4+ii*9] = 1.5;
342 g_vertex_buffer_data[ 5+ii*9] = 0;
343
344 g_vertex_buffer_data[ 6+ii*9] = -0.5;
345 g_vertex_buffer_data[ 7+ii*9] = -0.5;
346 g_vertex_buffer_data[ 8+ii*9] = 0;
347
348 g_vertex_color_data[ 0+ii*9] = 0;
349 g_vertex_color_data[ 1+ii*9] = 0;
350 g_vertex_color_data[ 2+ii*9] = 0.7;
351
352 g_vertex_color_data[ 3+ii*9] = 0;
353 g_vertex_color_data[ 4+ii*9] = 0;
354 g_vertex_color_data[ 5+ii*9] = 0.1;
355
356 g_vertex_color_data[ 6+ii*9] = 0;
357 g_vertex_color_data[ 7+ii*9] = 0;
358 g_vertex_color_data[ 8+ii*9] = 0.1;
359
360 ii++;
361
362 g_vertex_buffer_data[ 0+ii*9] = 0.5;
363 g_vertex_buffer_data[ 1+ii*9] = 0.5;
364 g_vertex_buffer_data[ 2+ii*9] = 0;
365
366 g_vertex_buffer_data[ 3+ii*9] = 1.5;
367 g_vertex_buffer_data[ 4+ii*9] = -0.5;
368 g_vertex_buffer_data[ 5+ii*9] = 0;
369
370 g_vertex_buffer_data[ 6+ii*9] = -0.5;
371 g_vertex_buffer_data[ 7+ii*9] = -0.5;
372 g_vertex_buffer_data[ 8+ii*9] = 0;
373
374 g_vertex_color_data[ 0+ii*9] = 0;
375 g_vertex_color_data[ 1+ii*9] = 0;
376 g_vertex_color_data[ 2+ii*9] = 0.7;
377
378 g_vertex_color_data[ 3+ii*9] = 0;
379 g_vertex_color_data[ 4+ii*9] = 0;
380 g_vertex_color_data[ 5+ii*9] = 0.1;
381
382 g_vertex_color_data[ 6+ii*9] = 0;
383 g_vertex_color_data[ 7+ii*9] = 0;
384 g_vertex_color_data[ 8+ii*9] = 0.1;
385
386 ii++;
387
388 g_vertex_buffer_data[ 0+ii*9] = 0.5;
389 g_vertex_buffer_data[ 1+ii*9] = 0.5;
390 g_vertex_buffer_data[ 2+ii*9] = 0;
391
392 g_vertex_buffer_data[ 3+ii*9] = -0.5;
393 g_vertex_buffer_data[ 4+ii*9] = 1.5;
394 g_vertex_buffer_data[ 5+ii*9] = 0;
395
396 g_vertex_buffer_data[ 6+ii*9] = 1.5;
397 g_vertex_buffer_data[ 7+ii*9] = 1.5;
398 g_vertex_buffer_data[ 8+ii*9] = 0;
399
400 g_vertex_color_data[ 0+ii*9] = 0;
401 g_vertex_color_data[ 1+ii*9] = 0;
402 g_vertex_color_data[ 2+ii*9] = 0.7;
403
404 g_vertex_color_data[ 3+ii*9] = 0;
405 g_vertex_color_data[ 4+ii*9] = 0;
406 g_vertex_color_data[ 5+ii*9] = 0.1;
407
408 g_vertex_color_data[ 6+ii*9] = 0;
409 g_vertex_color_data[ 7+ii*9] = 0;
410 g_vertex_color_data[ 8+ii*9] = 0.1;
411 }
412
413
414
415 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
416
417 // Create the shaders
418 GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
419 GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
420
421 // Read the Vertex Shader code from the file
422 std::string VertexShaderCode;
423 std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
424 if (VertexShaderStream.is_open()){
425 std::string Line = "";
426 while(getline(VertexShaderStream, Line))
427 VertexShaderCode += "\n" + Line;
428 VertexShaderStream.close();
429 } else {
430 printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
431 getchar();
432 return 0;
433 }
434
435 // Read the Fragment Shader code from the file
436 std::string FragmentShaderCode;
437 std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
438 if(FragmentShaderStream.is_open()){
439 std::string Line = "";
440 while(getline(FragmentShaderStream, Line))
441 FragmentShaderCode += "\n" + Line;
442 FragmentShaderStream.close();
443 }
444
445 GLint Result = GL_FALSE;
446 int InfoLogLength;
447
448
449 // Compile Vertex Shader
450 printf("Compiling shader : %s\n", vertex_file_path);
451 char const * VertexSourcePointer = VertexShaderCode.c_str();
452 glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
453 glCompileShader(VertexShaderID);
454
455 // Check Vertex Shader
456 glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
457 glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
458 if ( InfoLogLength > 0 ){
459 std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
460 glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
461 printf("%s\n", &VertexShaderErrorMessage[0]);
462 }
463
464
465 // Compile Fragment Shader
466 printf("Compiling shader : %s\n", fragment_file_path);
467 char const * FragmentSourcePointer = FragmentShaderCode.c_str();
468 glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
469 glCompileShader(FragmentShaderID);
470
471 // Check Fragment Shader
472 glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
473 glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
474 if ( InfoLogLength > 0 ){
475 std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
476 glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
477 printf("%s\n", &FragmentShaderErrorMessage[0]);
478 }
479
480 // Link the program
481 printf("Linking program\n");
482 GLuint ProgramID = glCreateProgram();
483 glAttachShader(ProgramID, VertexShaderID);
484 glAttachShader(ProgramID, FragmentShaderID);
485 glLinkProgram(ProgramID);
486
487 // Check the program
488 glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
489 glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
490 if ( InfoLogLength > 0 ){
491 std::vector<char> ProgramErrorMessage(InfoLogLength+1);
492 glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
493 printf("%s\n", &ProgramErrorMessage[0]);
494 }
495
496 glDetachShader(ProgramID, VertexShaderID);
497 glDetachShader(ProgramID, FragmentShaderID);
498
499 glDeleteShader(VertexShaderID);
500 glDeleteShader(FragmentShaderID);
501
502 return ProgramID;
503 }
504
505
506 int main(){
507 // Initialise GLFW
508 if( !glfwInit() ) {
509 fprintf( stderr, "Failed to initialize GLFW\n" );
510 return -1;
511 }
512
513
514
515 // 3eme partie du pipeline ... en openGL ...
516 glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
517 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
518 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
519 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
520 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
521 glfwWindowHint(GLFW_DEPTH_BITS, 24);
522
523 // Ouvre une fenêtre et crée son contexte OpenGl
524 GLFWwindow* window; // (Dans le code source qui accompagne, cette variable est globale)
525 window = glfwCreateWindow( 2560, 1600, "Main 54", NULL, NULL);
526 if( window == NULL ){
527 fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
528 glfwTerminate();
529 return -1;
530 }
531
532 glfwMakeContextCurrent(window); // Initialise GLEW
533 glewExperimental=true; // Nécessaire dans le profil de base
534 if (glewInit() != GLEW_OK) {
535 fprintf(stderr, "Failed to initialize GLEW\n");
536 return -1;
537 }
538 cout << "OpenGL and window initialized "<<endl;
539
540 // Enable depth test
541 glEnable(GL_DEPTH_TEST);
542
543 // Accept fragment if it closer to the camera than the former one
544 glDepthFunc(GL_LESS);
545 glDepthRange(0, 10);
546
547 // Bon maintenant on cree le VAO et cette fois on va s'en servir !
548 GLuint VertexArrayID;
549 glGenVertexArrays(1, &VertexArrayID);
550 glBindVertexArray(VertexArrayID);
551
552 float gainAlt = 1.0;
553 float gainCol = 1.0;
554
555
556 // 1ere partie du pipeline
557 readData();
558
559 // 2eme partie du pipeline
560 updateRepr(gainAlt, gainCol);
561
562 // This will identify our vertex buffer
563 GLuint vertexbuffer;
564 // Generate 1 buffer, put the resulting identifier in vertexbuffer
565 glGenBuffers(1, &vertexbuffer);
566
567 // The following commands will talk about our 'vertexbuffer' buffer
568 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
569 // Only allocqte memory. Do not send yet our vertices to OpenGL.
570 glBufferData(GL_ARRAY_BUFFER, sss+sss+sss, 0, GL_STATIC_DRAW);
571
572 // send vertices in the first part of the buffer
573 glBufferSubData(GL_ARRAY_BUFFER, 0, sss, g_vertex_buffer_data);
574
575 // send colors in the second part of the buffer
576 glBufferSubData(GL_ARRAY_BUFFER, sss, sss, g_vertex_color_data);
577
578 // send normals in the third part of the buffer
579 glBufferSubData(GL_ARRAY_BUFFER, sss+sss, sss, g_vertex_normal_data);
580
581 // ici les commandes stockees "une fois pour toute" dans le VAO
582 glVertexAttribPointer(
583 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
584 3, // size
585 GL_FLOAT, // type
586 GL_FALSE, // normalized?
587 0, // stride
588 (void*)0 // array buffer offset
589 );
590 glEnableVertexAttribArray(0);
591
592 glVertexAttribPointer( // same thing for the colors
593 1,
594 3,
595 GL_FLOAT,
596 GL_FALSE,
597 0,
598 (void*)sss);
599 glEnableVertexAttribArray(1);
600
601 glVertexAttribPointer( // same thing for the normals
602 2,
603 3,
604 GL_FLOAT,
605 GL_FALSE,
606 0,
607 (void*)(sss+sss));
608 glEnableVertexAttribArray(2);
609
610
611 glBindBuffer(GL_ARRAY_BUFFER, 0);
612
613 // on desactive le VAO a la fin de l'initialisation
614 glBindVertexArray (0);
615
616
617 // Assure que l'on peut capturer la touche d'échappement enfoncée ci-dessous
618 glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
619
620 GLuint programID = LoadShaders( "SimpleVertexShader54.vertexshader", "SimpleFragmentShader54.fragmentshader" );
621 uniform_proj = glGetUniformLocation(programID, "projectionMatrix");
622 uniform_view = glGetUniformLocation(programID, "viewMatrix");
623 uniform_model = glGetUniformLocation(programID, "modelMatrix");
624
625 float angle = -M_PI/2;
626 float elev = M_PI/6;
627
628
629 do{
630 //angle += dangle;
631 elev = M_PI/6 + 0.5*sin(angle)*sin(angle);
632
633 // recupere la taille effective de la fenetre
634 int width, height;
635 glfwGetWindowSize (window, &width, &height);
636
637 // re-initialise les tableaux de bits avant un nouvel affichage
638 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
639
640 // Utilise notre unique shader
641 glUseProgram(programID);
642
643 // on change de matrice de projection : la projection orthogonale est plus propice a la visualization !
644 //glm::mat4 projectionMatrix = glm::ortho( -1.0f, 1.0f, -1.0f*height/width, 1.0f*height/width, 0.0f, 2.f );
645 glm::mat4 projectionMatrix = glm::perspective(glm::radians(66.0f), ((float) width) / ((float) height), 0.1f, 4.0f);
646
647 vec3 vc = vec3(cos(angle)*cos(elev), sin(angle)*cos(elev), sin(elev));
648 vec3 vt = vec3(-sin(angle)*cos(elev), cos(angle)*cos(elev), 0);
649
650 glm::mat4 viewMatrix = glm::lookAt(
651 vc, // where is the camara
652 //vec3(0.0, 0.0, 2.0),
653 vec3(0.0, -0.1, 0.0), //where it looks
654 2.0f*normalize(glm::cross(vc, vt)) // head is up
655 );
656
657 mat4 modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(1.9f, 1.9f, 1.9f));
658 modelMatrix = glm::translate(modelMatrix, glm::vec3(-0.5f, -0.5f, 0.0));
659
660 glUniformMatrix4fv(uniform_proj, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
661 glUniformMatrix4fv(uniform_view, 1, GL_FALSE, glm::value_ptr(viewMatrix));
662 glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix));
663
664 // on re-active le VAO avant d'envoyer les buffers
665 glBindVertexArray(VertexArrayID);
666
667 // dessine les triangle(s) !
668 glDrawArrays(GL_TRIANGLES, 0, sss/(3*sizeof(GLfloat))); // Starting from vertex 0.. all the vertices;
669
670 // on desactive le VAO a la fin du dessin
671 glBindVertexArray (0);
672
673 // on desactive les shaders
674 glUseProgram(0);
675
676 // echange le buffer visible et invisible
677 glfwSwapBuffers(window);
678 glfwPollEvents();
679
680 if (glfwGetKey(window, GLFW_KEY_UP ) == GLFW_PRESS){
681 gainAlt = gainAlt*1.5;
682 updateRepr(gainAlt, gainCol);
683 glBindVertexArray(VertexArrayID);
684 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
685
686 glBufferSubData(GL_ARRAY_BUFFER, 0, sss, g_vertex_buffer_data);
687 glBufferSubData(GL_ARRAY_BUFFER, sss, sss, g_vertex_color_data);
688 glBufferSubData(GL_ARRAY_BUFFER, sss+sss, sss, g_vertex_normal_data);
689
690 glBindBuffer(GL_ARRAY_BUFFER, 0);
691 glBindVertexArray (0);
692 } else if (glfwGetKey(window, GLFW_KEY_DOWN ) == GLFW_PRESS){
693 gainAlt = gainAlt*0.75;
694 updateRepr(gainAlt, gainCol);
695 glBindVertexArray(VertexArrayID);
696 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
697
698 glBufferSubData(GL_ARRAY_BUFFER, 0, sss, g_vertex_buffer_data);
699 glBufferSubData(GL_ARRAY_BUFFER, sss, sss, g_vertex_color_data);
700 glBufferSubData(GL_ARRAY_BUFFER, sss+sss, sss, g_vertex_normal_data);
701
702 glBindBuffer(GL_ARRAY_BUFFER, 0);
703 glBindVertexArray (0);
704 } else if (glfwGetKey(window, GLFW_KEY_LEFT ) == GLFW_PRESS){
705 gainCol = gainCol*0.75;
706 updateRepr(gainAlt, gainCol);
707 glBindVertexArray(VertexArrayID);
708 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
709
710 glBufferSubData(GL_ARRAY_BUFFER, 0, sss, g_vertex_buffer_data);
711 glBufferSubData(GL_ARRAY_BUFFER, sss, sss, g_vertex_color_data);
712 glBufferSubData(GL_ARRAY_BUFFER, sss+sss, sss, g_vertex_normal_data);
713
714 glBindBuffer(GL_ARRAY_BUFFER, 0);
715 glBindVertexArray (0);
716 } else if (glfwGetKey(window, GLFW_KEY_RIGHT ) == GLFW_PRESS){
717 gainCol = gainCol*1.5;
718 updateRepr(gainAlt, gainCol);
719 glBindVertexArray(VertexArrayID);
720 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
721
722 glBufferSubData(GL_ARRAY_BUFFER, 0, sss, g_vertex_buffer_data);
723 glBufferSubData(GL_ARRAY_BUFFER, sss, sss, g_vertex_color_data);
724 glBufferSubData(GL_ARRAY_BUFFER, sss+sss, sss, g_vertex_normal_data);
725 glBindBuffer(GL_ARRAY_BUFFER, 0);
726 glBindVertexArray (0);
727 }
728 } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
729 while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
730 glfwWindowShouldClose(window) == 0 );
731 }