1 // sous mac 
  2 // g++ -I/usr/local/include/ -lglfw -lGLEW main3.cpp -framework OpenGL  -omain3 
  3 // ./main3
  4 
  5 // sous linux   
  6 // g++ -I/usr/local/include/ -I/public/ig/glm/ -c main3.cpp  -omain3.o
  7 // g++ -I/usr/local main3.o -lglfw  -lGLEW  -lGL  -omain3
  8 // ./main3
  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 #include <glm/glm.hpp>
 25 #ifdef __APPLE__
 26 #include <OpenGL/gl.h>
 27 #else
 28 #include <GL/gl.h>
 29 #endif
 30 using namespace glm;
 31 
 32 const int N = 40;
 33 
 34 
 35 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
 36 
 37   // Create the shaders
 38   GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
 39   GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
 40 
 41   // Read the Vertex Shader code from the file
 42   std::string VertexShaderCode;
 43   std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
 44   if(VertexShaderStream.is_open()){
 45     std::string Line = "";
 46     while(getline(VertexShaderStream, Line))
 47       VertexShaderCode += "\n" + Line;
 48     VertexShaderStream.close();
 49   }else{
 50     printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
 51     getchar();
 52     return 0;
 53   }
 54 
 55   // Read the Fragment Shader code from the file
 56   std::string FragmentShaderCode;
 57   std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
 58   if(FragmentShaderStream.is_open()){
 59     std::string Line = "";
 60     while(getline(FragmentShaderStream, Line))
 61       FragmentShaderCode += "\n" + Line;
 62     FragmentShaderStream.close();
 63   }
 64 
 65   GLint Result = GL_FALSE;
 66   int InfoLogLength;
 67 
 68 
 69   // Compile Vertex Shader
 70   printf("Compiling shader : %s\n", vertex_file_path);
 71   char const * VertexSourcePointer = VertexShaderCode.c_str();
 72   glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
 73   glCompileShader(VertexShaderID);
 74 
 75   // Check Vertex Shader
 76   glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
 77   glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
 78   if ( InfoLogLength > 0 ){
 79     std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
 80     glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
 81     printf("%s\n", &VertexShaderErrorMessage[0]);
 82   }
 83 
 84 
 85 
 86   // Compile Fragment Shader
 87   printf("Compiling shader : %s\n", fragment_file_path);
 88   char const * FragmentSourcePointer = FragmentShaderCode.c_str();
 89   glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
 90   glCompileShader(FragmentShaderID);
 91 
 92   // Check Fragment Shader
 93   glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
 94   glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
 95   if ( InfoLogLength > 0 ){
 96     std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
 97     glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
 98     printf("%s\n", &FragmentShaderErrorMessage[0]);
 99   }
100 
101 
102 
103   // Link the program
104   printf("Linking program\n");
105   GLuint ProgramID = glCreateProgram();
106   glAttachShader(ProgramID, VertexShaderID);
107   glAttachShader(ProgramID, FragmentShaderID);
108   glLinkProgram(ProgramID);
109 
110   // Check the program
111   glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
112   glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
113   if ( InfoLogLength > 0 ){
114     std::vector<char> ProgramErrorMessage(InfoLogLength+1);
115     glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
116     printf("%s\n", &ProgramErrorMessage[0]);
117   }
118 
119   
120   glDetachShader(ProgramID, VertexShaderID);
121   glDetachShader(ProgramID, FragmentShaderID);
122   
123   glDeleteShader(VertexShaderID);
124   glDeleteShader(FragmentShaderID);
125 
126   return ProgramID;
127 }
128 
129 int main(){
130     // Initialise GLFW
131   if( !glfwInit() )
132   {
133       fprintf( stderr, "Failed to initialize GLFW\n" );
134       return -1;
135   }
136 GLfloat g_vertex_buffer_data[9*N];
137 
138 GLfloat g_vertex_color_data[9*N];
139 
140     //g_vertex_buffer_data = malloc(sizeof(GLfloat)*N*3);
141     for (int i=0; i<N; i++){
142        float r = (rand()%1000)/1000.0; 
143 
144       g_vertex_buffer_data[0+i*9] = 0.0;
145     g_vertex_buffer_data[1+i*9] = 0.0;
146     g_vertex_buffer_data[2+i*9] = 0.0;
147 
148     g_vertex_buffer_data[3+i*9] = 0.0+r*cos((2*i+0)*M_PI/(N));
149     g_vertex_buffer_data[4+i*9] = 0.0+r*sin((2*i+0)*M_PI/(N));
150     g_vertex_buffer_data[5+i*9] = 0.0;
151 
152     g_vertex_buffer_data[6+i*9] = 0.0+r*cos((2*i+2)*M_PI/(N));
153     g_vertex_buffer_data[7+i*9] = 0.0+r*sin((2*i+2)*M_PI/(N));
154     g_vertex_buffer_data[8+i*9] = 0.0;
155 
156     g_vertex_color_data[0+i*9] = 0.0;
157     g_vertex_color_data[1+i*9] = 0.0;
158     g_vertex_color_data[2+i*9] = 1.0;
159 
160     g_vertex_color_data[3+i*9] = 0.5;
161     g_vertex_color_data[4+i*9] = 0.0;
162     g_vertex_color_data[5+i*9] = 0.0;
163 
164     g_vertex_color_data[6+i*9] = 1.0;
165     g_vertex_color_data[7+i*9] = 0.0;
166     g_vertex_color_data[8+i*9] = 0.0;
167     }
168 
169 
170   glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
171   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
172   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
173   glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
174   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
175 
176   // Ouvre une fenêtre et crée son contexte OpenGl
177   GLFWwindow* window; // (Dans le code source qui accompagne, cette variable est globale)
178   window = glfwCreateWindow( 1024, 768, "Main 03", NULL, NULL);
179   if( window == NULL ){
180       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" );
181       glfwTerminate();
182       return -1;
183   }
184 
185   glfwMakeContextCurrent(window); // Initialise GLEW
186   glewExperimental=true; // Nécessaire dans le profil de base
187   if (glewInit() != GLEW_OK) {
188       fprintf(stderr, "Failed to initialize GLEW\n");
189       return -1;
190   }
191 
192   // modern OpenGL do not have a default VAO anymore. Even if we don't want to use it
193   // we have a create and bind one before playing with buffers ! 
194   GLuint VertexArrayID;
195   glGenVertexArrays(1, &VertexArrayID);
196   glBindVertexArray(VertexArrayID);
197 
198   // This will identify our vertex buffer
199   GLuint vertexbuffer;
200   // Generate 1 buffer, put the resulting identifier in vertexbuffer
201   glGenBuffers(1, &vertexbuffer);
202 
203   // The following commands will talk about our 'vertexbuffer' buffer
204   glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
205 
206     // Only allocate memory. Do not send yet our vertices to OpenGL.
207     glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data)+sizeof(g_vertex_color_data), 0, GL_STATIC_DRAW);
208 
209       // send vertices in the first part of the buffer
210     glBufferSubData(GL_ARRAY_BUFFER, 0,                            sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
211 
212     // send colors in the second part of the buffer
213     glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), sizeof(g_vertex_color_data), g_vertex_color_data);
214   
215   glBindBuffer(GL_ARRAY_BUFFER, 0);
216 
217 
218   // Assure que l'on peut capturer la touche d'échappement enfoncée ci-dessous
219   glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
220 
221   GLuint programID = LoadShaders( "SimpleVertexShader3.vertexshader", "SimpleFragmentShader3.fragmentshader" );
222 
223   do{
224     // clear before every draw 1
225         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
226 
227         // Use our shader
228     glUseProgram(programID); 
229 
230       // 1rst attribute buffer : vertices
231     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
232     glVertexAttribPointer(
233        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
234        3,                  // size
235        GL_FLOAT,           // type
236        GL_FALSE,           // normalized?
237        0,                  // stride
238        (void*)0            // array buffer offset
239     );
240     glEnableVertexAttribArray(0);
241 
242     glVertexAttribPointer( // same thing for the colors
243           1, 
244           3, 
245           GL_FLOAT, 
246           GL_FALSE, 
247           0, 
248           (void*)sizeof(g_vertex_buffer_data));
249     glEnableVertexAttribArray(1);
250 
251     // Draw the triangle !
252     glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data)/(3*sizeof(float))); // Starting from vertex 0; 3xN vertices total -> N triangles
253 
254     glDisableVertexAttribArray(0);
255     glDisableVertexAttribArray(1);
256 
257       // Swap buffers
258       glfwSwapBuffers(window);
259       glfwPollEvents();
260 
261       // apres avoir recupere les evenements, on teste si la touche E est pressee et si c'est le cas
262       // on re-genere des donnees
263       if (glfwGetKey(window, GLFW_KEY_E ) == GLFW_PRESS){
264         //g_vertex_buffer_data = malloc(sizeof(GLfloat)*N*3);
265         for (int i=0; i<N; i++){
266            float r = (rand()%1000)/1000.0; 
267 
268           g_vertex_buffer_data[0+i*9] = 0.0;
269         g_vertex_buffer_data[1+i*9] = 0.0;
270         g_vertex_buffer_data[2+i*9] = 0.0;
271 
272         g_vertex_buffer_data[3+i*9] = 0.0+r*cos((2*i+0)*M_PI/(N));
273         g_vertex_buffer_data[4+i*9] = 0.0+r*sin((2*i+0)*M_PI/(N));
274         g_vertex_buffer_data[5+i*9] = 0.0;
275 
276         g_vertex_buffer_data[6+i*9] = 0.0+r*cos((2*i+2)*M_PI/(N));
277         g_vertex_buffer_data[7+i*9] = 0.0+r*sin((2*i+2)*M_PI/(N));
278         g_vertex_buffer_data[8+i*9] = 0.0;
279         }
280         // ici on n'envoie que les sommets car on souhaite garder les memes couleurs ... et le nombre
281         // n'a pas change !
282         glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
283         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
284         glBindBuffer(GL_ARRAY_BUFFER, 0);
285       }
286       
287 
288   } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
289   while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
290   glfwWindowShouldClose(window) == 0 );
291 }