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 }