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