1 // sous mac 
  2 // g++ -I/usr/local/include/ -lglfw -lGLEW main4.cpp -framework OpenGL  -omain4 
  3 // ./main4
  4 
  5 // sous linux   
  6 // g++ -I/usr/local/include/ -I/public/ig/glm/ -c main4.cpp  -omain4.o
  7 // g++ -I/usr/local main4.o -lglfw  -lGLEW  -lGL  -omain4
  8 // ./main4
  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   // Link the program
112   printf("Linking program\n");
113   GLuint ProgramID = glCreateProgram();
114   glAttachShader(ProgramID, VertexShaderID);
115   glAttachShader(ProgramID, FragmentShaderID);
116   glLinkProgram(ProgramID);
117 
118   
119   // Check the program
120   glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
121   glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
122   if ( InfoLogLength > 0 ){
123     std::vector<char> ProgramErrorMessage(InfoLogLength+1);
124     glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
125     printf("%s\n", &ProgramErrorMessage[0]);
126   }
127 
128   
129   glDetachShader(ProgramID, VertexShaderID);
130   glDetachShader(ProgramID, FragmentShaderID);
131   
132   glDeleteShader(VertexShaderID);
133   glDeleteShader(FragmentShaderID);
134 
135   return ProgramID;
136 }
137 
138 int main(){
139     // Initialise GLFW
140   if( !glfwInit() )
141   {
142       fprintf( stderr, "Failed to initialize GLFW\n" );
143       return -1;
144   }
145   GLfloat g_vertex_buffer_data[9*N];
146   GLfloat g_vertex_color_data[9*N];
147 
148   for (int i=0; i<N; i++){
149     float r = (rand()%1000)/1000.0; 
150 
151     g_vertex_buffer_data[0+i*9] = 0.0;
152     g_vertex_buffer_data[1+i*9] = 0.0;
153     g_vertex_buffer_data[2+i*9] = 0.0;
154 
155     g_vertex_buffer_data[3+i*9] = 0.0+r*cos((2*i+0)*M_PI/(N));
156     g_vertex_buffer_data[4+i*9] = 0.0+r*sin((2*i+0)*M_PI/(N));
157     g_vertex_buffer_data[5+i*9] = 0.0;
158 
159     g_vertex_buffer_data[6+i*9] = 0.0+r*cos((2*i+2)*M_PI/(N));
160     g_vertex_buffer_data[7+i*9] = 0.0+r*sin((2*i+2)*M_PI/(N));
161     g_vertex_buffer_data[8+i*9] = 0.0;
162 
163     g_vertex_color_data[0+i*9] = 0.0;
164     g_vertex_color_data[1+i*9] = 0.0;
165     g_vertex_color_data[2+i*9] = 1.0;
166 
167     g_vertex_color_data[3+i*9] = 0.5;
168     g_vertex_color_data[4+i*9] = 0.0;
169     g_vertex_color_data[5+i*9] = 0.0;
170 
171     g_vertex_color_data[6+i*9] = 1.0;
172     g_vertex_color_data[7+i*9] = 0.0;
173     g_vertex_color_data[8+i*9] = 0.0;
174   }
175 
176 
177   glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
178   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
179   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
180   glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
181   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
182 
183   // Ouvre une fenêtre et crée son contexte OpenGl
184   GLFWwindow* window; // (Dans le code source qui accompagne, cette variable est globale)
185   window = glfwCreateWindow( 1024, 768, "Main 04", NULL, NULL);
186   if( window == NULL ){
187       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" );
188       glfwTerminate();
189       return -1;
190   }
191 
192   glfwMakeContextCurrent(window); // Initialise GLEW
193   glewExperimental=true; // Nécessaire dans le profil de base
194   if (glewInit() != GLEW_OK) {
195       fprintf(stderr, "Failed to initialize GLEW\n");
196       return -1;
197   }
198 
199   // modern OpenGL do not have a default VAO anymore. Even if we don't want to use it
200   // we have a create and bind one before playing with buffers ! 
201   GLuint VertexArrayID;
202   glGenVertexArrays(1, &VertexArrayID);
203   glBindVertexArray(VertexArrayID);
204 
205   // This will identify our vertex buffer
206   GLuint vertexbuffer;
207   // Generate 1 buffer, put the resulting identifier in vertexbuffer
208   glGenBuffers(1, &vertexbuffer);
209 
210   // The following commands will talk about our 'vertexbuffer' buffer
211   glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
212   
213     // Only allocate memory. Do not send yet our vertices to OpenGL.
214     glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data)+sizeof(g_vertex_color_data), 0, GL_STATIC_DRAW);
215 
216       // send vertices in the first part of the buffer
217     glBufferSubData(GL_ARRAY_BUFFER, 0,                            sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
218 
219     // send colors in the second part of the buffer
220     glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), sizeof(g_vertex_color_data), g_vertex_color_data);
221   
222   glBindBuffer(GL_ARRAY_BUFFER, 0);
223 
224 
225   // Assure que l'on peut capturer la touche d'échappement enfoncée ci-dessous
226   glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
227 
228   GLuint programID = LoadShaders( "SimpleVertexShader4.vertexshader", "SimpleFragmentShader4.fragmentshader" );
229   uniform_proj = glGetUniformLocation(programID, "projectionMatrix");
230   uniform_view = glGetUniformLocation(programID, "viewMatrix");
231   uniform_model = glGetUniformLocation(programID, "modelMatrix");
232 
233   float angle = 0.0f;
234 
235   do{
236     angle = (angle+M_PI/200);
237 
238     // clear before every draw 1
239         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
240 
241         // Use our shader
242     glUseProgram(programID); 
243 
244     glm::mat4 projectionMatrix = glm::perspective(glm::radians(66.0f), 1024.0f / 768.0f, 0.1f, 200.0f);
245     glm::mat4 viewMatrix       = glm::lookAt(
246                             vec3(2*cos(angle), 2*sin(angle), 2.0f), // where is the camara
247                             vec3(0,0,0), //where it looks
248                             vec3(0,0,1) // head is up
249                           );
250     mat4 modelMatrix      = glm::mat4(1.0);
251 
252     glUniformMatrix4fv(uniform_proj,  1, GL_FALSE, glm::value_ptr(projectionMatrix));
253     glUniformMatrix4fv(uniform_view,  1, GL_FALSE, glm::value_ptr(viewMatrix));
254     glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix));
255 
256     // 1rst attribute buffer : vertices
257     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
258     glVertexAttribPointer(
259        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
260        3,                  // size
261        GL_FLOAT,           // type
262        GL_FALSE,           // normalized?
263        0,                  // stride
264        (void*)0            // array buffer offset
265     );
266     glEnableVertexAttribArray(0);
267 
268         glVertexAttribPointer( // same thing for the colors
269           1, 
270           3, 
271           GL_FLOAT, 
272           GL_FALSE, 
273           0, 
274           (void*)sizeof(g_vertex_buffer_data));
275     glEnableVertexAttribArray(1);
276 
277     // Draw the triangle !
278     glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
279 
280     glDisableVertexAttribArray(0);
281     glDisableVertexAttribArray(1);
282 
283       // Swap buffers
284       glfwSwapBuffers(window);
285       glfwPollEvents();
286 
287       // apres avoir recupere les evenements, on teste si la touche E est pressee et si c'est le cas
288       // on re-genere des donnees
289       if (glfwGetKey(window, GLFW_KEY_E ) == GLFW_PRESS){
290         //g_vertex_buffer_data = malloc(sizeof(GLfloat)*N*3);
291         for (int i=0; i<N; i++){
292           float r = (rand()%1000)/1000.0; 
293 
294           g_vertex_buffer_data[0+i*9] = 0.0;
295           g_vertex_buffer_data[1+i*9] = 0.0;
296           g_vertex_buffer_data[2+i*9] = 0.0;
297 
298           g_vertex_buffer_data[3+i*9] = 0.0+r*cos((2*i+0)*M_PI/(N));
299           g_vertex_buffer_data[4+i*9] = 0.0+r*sin((2*i+0)*M_PI/(N));
300           g_vertex_buffer_data[5+i*9] = 0.0;
301 
302           g_vertex_buffer_data[6+i*9] = 0.0+r*cos((2*i+2)*M_PI/(N));
303           g_vertex_buffer_data[7+i*9] = 0.0+r*sin((2*i+2)*M_PI/(N));
304           g_vertex_buffer_data[8+i*9] = 0.0;
305         }
306         // ici on n'envoie que les sommets car on souhaite garder les memes couleurs ... et le nombre
307         // n'a pas change !
308         glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
309         glBufferSubData(GL_ARRAY_BUFFER, 0,                            sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
310         glBindBuffer(GL_ARRAY_BUFFER, 0);
311       }
312       
313 
314   } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
315   while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
316   glfwWindowShouldClose(window) == 0 );
317 }