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