1 // sous mac 
  2 // >g++ -I/u/usr/local/include/ -lglfw -lGLEW main50.cpp -framework OpenGL  -omain50 
  3 // >./main50
  4 
  5 // sous linux   
  6 // >g++ -I/usr/local/include/ -I/public/ig/glm/ -c main50.cpp  -omain50.o
  7 // >g++ -I/usr/local main50.o -lglfw  -lGLEW  -lGL  -omain50
  8 // >./main50
  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 #define GLM_FORCE_RADIANS
 32 #include <glm/glm.hpp>
 33 #include <glm/gtc/matrix_transform.hpp>
 34 #include <glm/gtc/type_ptr.hpp>
 35 
 36 using namespace glm;
 37 
 38 
 39 const int N = 40;
 40 // stocke les variables uniformes qui seront communes a tous les vertex dessines
 41 // dans une variable globale CAR
 42 // C'est dans la fonction loadShaders que nous pouvos recupere les bonnes valeurs de pointeur (une fois le shader compile/linke)
 43 // c'est dans le main que nous pouvons donne les bonnes valeurs "au bout du pointeur" pour que les shaders les recoivent 
 44 GLint uniform_proj, uniform_view, uniform_model;
 45 
 46 
 47 void readData(){
 48   ifstream file ( "villes2.csv" ); // declare file stream: http://www.cplusplus.com/reference/iostream/ifstream/
 49   string value;
 50   getline ( file, value, '\n' );
 51   while ( file.good() ) {
 52 
 53        getline ( file, value, ';' ); // read a string until next comma: http://www.cplusplus.com/reference/string/getline/
 54        string sinsee = string( value, 0, value.length() );
 55        getline ( file, value, ';' );
 56        string sname = string( value, 0, value.length() );
 57        getline ( file, value, ';' );
 58        string saltitude = string( value, 0, value.length() );
 59        getline ( file, value, ';' );
 60        string scp = string( value, 0, value.length() );
 61        getline ( file, value, ';' );
 62        string slon = string( value, 0, value.length() );
 63        float lon = stof(slon, NULL);
 64        getline ( file, value, ';' );
 65        string slat = string( value, 0, value.length() );
 66        float lat = stof(slat, NULL);
 67        getline ( file, value, ';' );
 68        string spop = string( value, 0, value.length() );
 69        getline ( file, value, '\n' );
 70        string ssur = string( value, 0, value.length() );
 71 
 72        cout << lon << " ... " << lat << endl; // display value 
 73   }
 74 
 75 }
 76 
 77 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
 78 
 79   // Create the shaders
 80   GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
 81   GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
 82 
 83   // Read the Vertex Shader code from the file
 84   std::string VertexShaderCode;
 85   std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
 86   if (VertexShaderStream.is_open()){
 87     std::string Line = "";
 88     while(getline(VertexShaderStream, Line))
 89       VertexShaderCode += "\n" + Line;
 90     VertexShaderStream.close();
 91   } else {
 92     printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
 93     getchar();
 94     return 0;
 95   }
 96 
 97   // Read the Fragment Shader code from the file
 98   std::string FragmentShaderCode;
 99   std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
100   if(FragmentShaderStream.is_open()){
101     std::string Line = "";
102     while(getline(FragmentShaderStream, Line))
103       FragmentShaderCode += "\n" + Line;
104     FragmentShaderStream.close();
105   }
106 
107   GLint Result = GL_FALSE;
108   int InfoLogLength;
109 
110 
111   // Compile Vertex Shader
112   printf("Compiling shader : %s\n", vertex_file_path);
113   char const * VertexSourcePointer = VertexShaderCode.c_str();
114   glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
115   glCompileShader(VertexShaderID);
116 
117   // Check Vertex Shader
118   glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
119   glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
120   if ( InfoLogLength > 0 ){
121     std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
122     glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
123     printf("%s\n", &VertexShaderErrorMessage[0]);
124   }
125 
126 
127   // Compile Fragment Shader
128   printf("Compiling shader : %s\n", fragment_file_path);
129   char const * FragmentSourcePointer = FragmentShaderCode.c_str();
130   glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
131   glCompileShader(FragmentShaderID);
132 
133   // Check Fragment Shader
134   glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
135   glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
136   if ( InfoLogLength > 0 ){
137     std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
138     glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
139     printf("%s\n", &FragmentShaderErrorMessage[0]);
140   }
141 
142   // Link the program
143   printf("Linking program\n");
144   GLuint ProgramID = glCreateProgram();
145   glAttachShader(ProgramID, VertexShaderID);
146   glAttachShader(ProgramID, FragmentShaderID);
147   glLinkProgram(ProgramID);
148 
149   // Check the program
150   glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
151   glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
152   if ( InfoLogLength > 0 ){
153     std::vector<char> ProgramErrorMessage(InfoLogLength+1);
154     glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
155     printf("%s\n", &ProgramErrorMessage[0]);
156   }
157   
158   glDetachShader(ProgramID, VertexShaderID);
159   glDetachShader(ProgramID, FragmentShaderID);
160   
161   glDeleteShader(VertexShaderID);
162   glDeleteShader(FragmentShaderID);
163 
164   return ProgramID;
165 }
166 
167 
168 int main(){
169     // Initialise GLFW
170   if( !glfwInit() ) {
171       fprintf( stderr, "Failed to initialize GLFW\n" );
172       return -1;
173   }
174 
175   GLfloat g_vertex_buffer_data[9*5*N];
176   GLfloat g_vertex_color_data[9*5*N];
177 
178 
179   readData();
180 
181   // on rajoute des faces et de la hauteur a notre figure
182   for (int i=0; i<N; i++){
183     float r = (rand()%1000)/1000.0; 
184     g_vertex_buffer_data[ 0+i*9*5] = 0.0;
185     g_vertex_buffer_data[ 1+i*9*5] = 0.0;
186     g_vertex_buffer_data[ 2+i*9*5] = 0.0;
187 
188     g_vertex_buffer_data[ 3+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
189     g_vertex_buffer_data[ 4+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
190     g_vertex_buffer_data[ 5+i*9*5] = r/5.0;
191 
192     g_vertex_buffer_data[ 6+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
193     g_vertex_buffer_data[ 7+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
194     g_vertex_buffer_data[ 8+i*9*5] = r/5.0;
195 
196 
197     g_vertex_buffer_data[ 9+i*9*5] = 0.0;
198     g_vertex_buffer_data[10+i*9*5] = 0.0;
199     g_vertex_buffer_data[11+i*9*5] = 0.0;
200 
201     g_vertex_buffer_data[12+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
202     g_vertex_buffer_data[13+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
203     g_vertex_buffer_data[14+i*9*5] = r/5.0;
204 
205     g_vertex_buffer_data[15+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
206     g_vertex_buffer_data[16+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
207     g_vertex_buffer_data[17+i*9*5] = 0.0;
208 
209 
210     g_vertex_buffer_data[18+i*9*5] = 0.0;
211     g_vertex_buffer_data[19+i*9*5] = 0.0;
212     g_vertex_buffer_data[20+i*9*5] = 0.0;
213 
214     g_vertex_buffer_data[21+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
215     g_vertex_buffer_data[22+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
216     g_vertex_buffer_data[23+i*9*5] = r/5.0;
217 
218     g_vertex_buffer_data[24+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
219     g_vertex_buffer_data[25+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
220     g_vertex_buffer_data[26+i*9*5] = 0.0;    
221 
222 
223     g_vertex_buffer_data[27+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
224     g_vertex_buffer_data[28+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
225     g_vertex_buffer_data[29+i*9*5] = r/5.0;
226 
227     g_vertex_buffer_data[30+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
228     g_vertex_buffer_data[31+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
229     g_vertex_buffer_data[32+i*9*5] = r/5.0;
230 
231     g_vertex_buffer_data[33+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
232     g_vertex_buffer_data[34+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
233     g_vertex_buffer_data[35+i*9*5] = 0.0;    
234 
235     g_vertex_buffer_data[36+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
236     g_vertex_buffer_data[37+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
237     g_vertex_buffer_data[38+i*9*5] = r/5.0;
238 
239     g_vertex_buffer_data[39+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
240     g_vertex_buffer_data[40+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
241     g_vertex_buffer_data[41+i*9*5] = 0.0;
242 
243     g_vertex_buffer_data[42+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
244     g_vertex_buffer_data[43+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
245     g_vertex_buffer_data[44+i*9*5] = 0.0;    
246 
247 
248     g_vertex_color_data[ 0+i*9*5] = 0.0;
249     g_vertex_color_data[ 1+i*9*5] = 0.0;
250     g_vertex_color_data[ 2+i*9*5] = 1.0;
251 
252     g_vertex_color_data[ 3+i*9*5] = 0.5;
253     g_vertex_color_data[ 4+i*9*5] = 0.0;
254     g_vertex_color_data[ 5+i*9*5] = 0.0;
255 
256     g_vertex_color_data[ 6+i*9*5] = 1.0;
257     g_vertex_color_data[ 7+i*9*5] = 0.0;
258     g_vertex_color_data[ 8+i*9*5] = 0.0;
259 
260     g_vertex_color_data[ 9+i*9*5] = 0.5;
261     g_vertex_color_data[10+i*9*5] = 0.0;
262     g_vertex_color_data[11+i*9*5] = 1.0;
263 
264     g_vertex_color_data[12+i*9*5] = 0.5;
265     g_vertex_color_data[13+i*9*5] = 0.0;
266     g_vertex_color_data[14+i*9*5] = 0.0;
267 
268     g_vertex_color_data[15+i*9*5] = 0.5;
269     g_vertex_color_data[16+i*9*5] = 0.0;
270     g_vertex_color_data[17+i*9*5] = 0.0;    
271 
272     g_vertex_color_data[18+i*9*5] = 1.0;
273     g_vertex_color_data[19+i*9*5] = 0.0;
274     g_vertex_color_data[20+i*9*5] = 1.0;
275 
276     g_vertex_color_data[21+i*9*5] = 1.0;
277     g_vertex_color_data[22+i*9*5] = 0.0;
278     g_vertex_color_data[23+i*9*5] = 0.0;
279 
280     g_vertex_color_data[24+i*9*5] = 1.0;
281     g_vertex_color_data[25+i*9*5] = 0.0;
282     g_vertex_color_data[26+i*9*5] = 0.0;    
283 
284     g_vertex_color_data[27+i*9*5] = 1.0;
285     g_vertex_color_data[28+i*9*5] = 0.0;
286     g_vertex_color_data[29+i*9*5] = 0.0;    
287 
288     g_vertex_color_data[30+i*9*5] = 0.5;
289     g_vertex_color_data[31+i*9*5] = 0.0;
290     g_vertex_color_data[32+i*9*5] = 0.0;
291 
292     g_vertex_color_data[33+i*9*5] = 1.0;
293     g_vertex_color_data[34+i*9*5] = 0.0;
294     g_vertex_color_data[35+i*9*5] = 0.0;  
295 
296     g_vertex_color_data[36+i*9*5] = 0.5;
297     g_vertex_color_data[37+i*9*5] = 0.0;
298     g_vertex_color_data[38+i*9*5] = 0.0;    
299 
300     g_vertex_color_data[39+i*9*5] = 0.5;
301     g_vertex_color_data[40+i*9*5] = 0.0;
302     g_vertex_color_data[41+i*9*5] = 0.0;
303 
304     g_vertex_color_data[42+i*9*5] = 1.0;
305     g_vertex_color_data[43+i*9*5] = 0.0;
306     g_vertex_color_data[44+i*9*5] = 0.0;    
307 
308   }
309 
310 
311   glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
312   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
313   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
314   glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
315   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
316   glfwWindowHint(GLFW_DEPTH_BITS, 24);
317 
318   // Ouvre une fenêtre et crée son contexte OpenGl
319   GLFWwindow* window; // (Dans le code source qui accompagne, cette variable est globale)
320   window = glfwCreateWindow( 1024, 768, "Main 05", NULL, NULL);
321   if( window == NULL ){
322       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" );
323       glfwTerminate();
324       return -1;
325   }
326 
327   glfwMakeContextCurrent(window); // Initialise GLEW
328   glewExperimental=true; // Nécessaire dans le profil de base
329   if (glewInit() != GLEW_OK) {
330       fprintf(stderr, "Failed to initialize GLEW\n");
331       return -1;
332   }
333 
334   // Enable depth test
335   glEnable(GL_DEPTH_TEST);
336   // Accept fragment if it closer to the camera than the former one
337   glDepthFunc(GL_LESS);
338   glDepthRange(-1, 1);
339 
340   // Bon maintenant on cree le VAO et cette fois on va s'en servir !
341   GLuint VertexArrayID;
342   glGenVertexArrays(1, &VertexArrayID);
343   glBindVertexArray(VertexArrayID);
344 
345   // This will identify our vertex buffer
346   GLuint vertexbuffer;
347   // Generate 1 buffer, put the resulting identifier in vertexbuffer
348   glGenBuffers(1, &vertexbuffer);
349 
350   // The following commands will talk about our 'vertexbuffer' buffer
351   glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
352     // Only allocqte memory. Do not send yet our vertices to OpenGL.
353     glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data)+sizeof(g_vertex_color_data), 0, GL_STATIC_DRAW);
354 
355       // send vertices in the first part of the buffer
356     glBufferSubData(GL_ARRAY_BUFFER, 0,                            sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
357 
358     // send vertices in the second part of the buffer
359     glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), sizeof(g_vertex_color_data), g_vertex_color_data);
360   
361     // ici les commandes stockees "une fois pour toute" dans le VAO 
362     glVertexAttribPointer(
363        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
364        3,                  // size
365        GL_FLOAT,           // type
366        GL_FALSE,           // normalized?
367        0,                  // stride
368        (void*)0            // array buffer offset
369     );
370     glEnableVertexAttribArray(0);
371 
372     glVertexAttribPointer( // same thing for the colors
373       1, 
374       3, 
375       GL_FLOAT, 
376       GL_FALSE, 
377       0, 
378       (void*)sizeof(g_vertex_buffer_data));
379     glEnableVertexAttribArray(1);
380 
381 
382   glBindBuffer(GL_ARRAY_BUFFER, 0);
383 
384   // on desactive le VAO a la fin de l'initialisation
385   glBindVertexArray (0);
386 
387 
388   // Assure que l'on peut capturer la touche d'échappement enfoncée ci-dessous
389   glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
390 
391   GLuint programID = LoadShaders( "SimpleVertexShader50.vertexshader", "SimpleFragmentShader50.fragmentshader" );
392   uniform_proj     = glGetUniformLocation(programID, "projectionMatrix");
393   uniform_view     = glGetUniformLocation(programID, "viewMatrix");
394   uniform_model    = glGetUniformLocation(programID, "modelMatrix");
395 
396   float angle = 0.0f;
397 
398   do{
399     angle = (angle+M_PI/200);
400 
401     // clear before every draw 1
402         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
403 
404     // Use our shader
405     glUseProgram(programID); 
406 
407     // onchange de matrice de projection : la projection orthogonale est plus propice a la visualization !
408     //glm::mat4 projectionMatrix = glm::perspective(45.0f, 1024.0f / 768.0f, 0.0f, 200.0f);
409     glm::mat4 projectionMatrix = glm::ortho( -1.0f, 1.0f, -1.0f, 1.0f, -3.f, 3.f );
410     glm::mat4 viewMatrix       = glm::lookAt(
411                                   vec3(1.5*cos(angle), 1.5*sin(angle), -0.5), // where is the camara
412                                   vec3(0,0,0.5), //where it looks
413                                   vec3(0,0, 1) // head is up
414                                 );
415     mat4 modelMatrix      = glm::mat4(1.0);
416 
417     glUniformMatrix4fv(uniform_proj,  1, GL_FALSE, glm::value_ptr(projectionMatrix));
418     glUniformMatrix4fv(uniform_view,  1, GL_FALSE, glm::value_ptr(viewMatrix));
419     glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix));
420 
421     // on re-active le VAO avant d'envoyer les buffers
422     glBindVertexArray(VertexArrayID);
423 
424     // Je met en commentaire tous les trucs qui n'ont plus besoin d'etre appelle a chaque dessin !
425     // 1rst attribute buffer : vertices
426     /*glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
427     glVertexAttribPointer(
428        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
429        3,                  // size
430        GL_FLOAT,           // type
431        GL_FALSE,           // normalized?
432        0,                  // stride
433        (void*)0            // array buffer offset
434     );
435     glEnableVertexAttribArray(0);
436 
437     glVertexAttribPointer( // same thing for the colors
438       1, 
439       3, 
440       GL_FLOAT, 
441       GL_FALSE, 
442       0, 
443       (void*)sizeof(g_vertex_buffer_data));
444     glEnableVertexAttribArray(1);*/
445 
446     // Draw the triangle(s) !
447     glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
448 
449     // Ca aussi on peut l'enlever puisque le enable n'est plus fait ici !
450     /*glDisableVertexAttribArray(0);
451     glDisableVertexAttribArray(1);*/
452 
453     // on desactive le VAO a la fin du dessin
454     glBindVertexArray (0);
455 
456     // on desactive les shaders
457     glUseProgram(0);
458 
459 
460     // Swap buffers
461     glfwSwapBuffers(window);
462     glfwPollEvents();
463 
464     // apres avoir recupere les evenements, on teste si la touche E est pressee et si c'est le cas
465     // on re-genere des donnees
466     if (glfwGetKey(window, GLFW_KEY_E ) == GLFW_PRESS){
467       for (int i=0; i<N; i++){
468         float r = (rand()%1000)/1000.0; 
469         g_vertex_buffer_data[ 0+i*9*5] = 0.0;
470         g_vertex_buffer_data[ 1+i*9*5] = 0.0;
471         g_vertex_buffer_data[ 2+i*9*5] = 0.0;
472 
473         g_vertex_buffer_data[ 3+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
474         g_vertex_buffer_data[ 4+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
475         g_vertex_buffer_data[ 5+i*9*5] = r/5.0;
476 
477         g_vertex_buffer_data[ 6+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
478         g_vertex_buffer_data[ 7+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
479         g_vertex_buffer_data[ 8+i*9*5] = r/5.0;
480 
481 
482         g_vertex_buffer_data[ 9+i*9*5] = 0.0;
483         g_vertex_buffer_data[10+i*9*5] = 0.0;
484         g_vertex_buffer_data[11+i*9*5] = 0.0;
485 
486         g_vertex_buffer_data[12+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
487         g_vertex_buffer_data[13+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
488         g_vertex_buffer_data[14+i*9*5] = r/5.0;
489 
490         g_vertex_buffer_data[15+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
491         g_vertex_buffer_data[16+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
492         g_vertex_buffer_data[17+i*9*5] = 0.0;
493 
494 
495         g_vertex_buffer_data[18+i*9*5] = 0.0;
496         g_vertex_buffer_data[19+i*9*5] = 0.0;
497         g_vertex_buffer_data[20+i*9*5] = 0.0;
498 
499         g_vertex_buffer_data[21+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
500         g_vertex_buffer_data[22+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
501         g_vertex_buffer_data[23+i*9*5] = r/5.0;
502 
503         g_vertex_buffer_data[24+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
504         g_vertex_buffer_data[25+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
505         g_vertex_buffer_data[26+i*9*5] = 0.0;    
506 
507 
508         g_vertex_buffer_data[27+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
509         g_vertex_buffer_data[28+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
510         g_vertex_buffer_data[29+i*9*5] = r/5.0;
511 
512         g_vertex_buffer_data[30+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
513         g_vertex_buffer_data[31+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
514         g_vertex_buffer_data[32+i*9*5] = r/5.0;
515 
516         g_vertex_buffer_data[33+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
517         g_vertex_buffer_data[34+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
518         g_vertex_buffer_data[35+i*9*5] = 0.0;    
519 
520         g_vertex_buffer_data[36+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
521         g_vertex_buffer_data[37+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
522         g_vertex_buffer_data[38+i*9*5] = r/5.0;
523 
524         g_vertex_buffer_data[39+i*9*5] = 0.0+r*cos((2*i+0)*M_PI/(N));
525         g_vertex_buffer_data[40+i*9*5] = 0.0+r*sin((2*i+0)*M_PI/(N));
526         g_vertex_buffer_data[41+i*9*5] = 0.0;
527 
528         g_vertex_buffer_data[42+i*9*5] = 0.0+r*cos((2*i+1.9)*M_PI/(N));
529         g_vertex_buffer_data[43+i*9*5] = 0.0+r*sin((2*i+1.9)*M_PI/(N));
530         g_vertex_buffer_data[44+i*9*5] = 0.0;    
531       }
532       // ici on n'envoie que les sommets car on souhaite garder les memes couleurs ... et le nombre
533       // n'a pas change !
534       glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
535       glBufferSubData(GL_ARRAY_BUFFER, 0,                            sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
536       glBindBuffer(GL_ARRAY_BUFFER, 0);
537     }
538 
539   } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
540   while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
541   glfwWindowShouldClose(window) == 0 );
542 }