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 }